00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef IMAGE_POLYNOMIALINTERPOLATIONADAPTOR_H
00010 #define IMAGE_POLYNOMIALINTERPOLATIONADAPTOR_H
00011
00012 #include <image/InterpolationAdaptorInterface.hpp>
00013 #include <core/utilities.hpp>
00014
00015
00016 namespace imaging
00017 {
00018 namespace polynomial_interpolation_adaptor_impl
00019 {
00020 template <class image_t>
00021 typename image_t::data_t interpolate_1d(const image_t & image_reference, const ublas::fixed_vector<size_t, 1> & base_coordinates, const ublas::fixed_vector<float_t, 1> & truncated_coordinates)
00022 {
00023 return typename image_t::data_t(0.0);
00024 }
00025
00026 template <class image_t>
00027 typename image_t::data_t interpolate_2d(const image_t & image_reference, const ublas::fixed_vector<size_t, 2> & base_coordinates, const ublas::fixed_vector<float_t, 2> & truncated_coordinates)
00028 {
00029 return (1.0 - truncated_coordinates(0)) * (1.0 - truncated_coordinates(1)) * image_reference[base_coordinates] +
00030 truncated_coordinates(0) * (1.0 - truncated_coordinates(1)) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(1, 0)] +
00031 (1.0 - truncated_coordinates(0)) * truncated_coordinates(1) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(0, 1)] +
00032 truncated_coordinates(0) * truncated_coordinates(1) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(1, 1)];
00033 }
00034
00035
00036 template <class image_t>
00037 typename image_t::data_t interpolate_3d(const image_t & image_reference, const ublas::fixed_vector<size_t, 3> & base_coordinates, const ublas::fixed_vector<float_t, 3> & truncated_coordinates)
00038 {
00039 float_t temp(0.0);
00040 for(size_t i = 0; i < 2; ++i)
00041 for(size_t j = 0; j < 2; ++j)
00042 for(size_t k = 0; k < 2; ++k)
00043 {
00044 temp += (delta(1, i) * truncated_coordinates(0) + delta(0, i) * (1.0 - truncated_coordinates(0))) *
00045 (delta(1, j) * truncated_coordinates(1) + delta(0, j) * (1.0 - truncated_coordinates(1))) *
00046 (delta(1, k) * truncated_coordinates(2) + delta(0, k) * (1.0 - truncated_coordinates(2))) *
00047 image_reference[base_coordinates + ublas::fixed_vector<size_t, 3>(i, j, k)];
00048 }
00049
00050 return temp;
00051 }
00052
00053 template <class image_t, class result_t>
00054 void interpolate_gradient_1d(const image_t & image_reference, const ublas::fixed_vector<size_t, 1> & base_coordinates, const ublas::fixed_vector<float_t, 1> & truncated_coordinates, result_t & value)
00055 {}
00056
00057 template <class image_t, class result_t>
00058 void interpolate_gradient_2d(const image_t & image_reference, const ublas::fixed_vector<size_t, 2> & base_coordinates, const ublas::fixed_vector<float_t, 2> & truncated_coordinates, result_t & value)
00059 {
00060 value(0) = - (1.0 - truncated_coordinates(1)) * image_reference[base_coordinates]
00061 + (1.0 - truncated_coordinates(1)) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(1, 0)]
00062 - truncated_coordinates(1) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(0, 1)]
00063 + truncated_coordinates(1) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(1, 1)];
00064
00065 value(1) = - (1.0 - truncated_coordinates(0)) * image_reference[base_coordinates]
00066 - truncated_coordinates(0) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(1, 0)]
00067 + (1.0 - truncated_coordinates(0)) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(0, 1)]
00068 + truncated_coordinates(0) * image_reference[base_coordinates + ublas::fixed_vector<size_t, 2>(1, 1)];
00069 }
00070
00071 template <class image_t, class result_t>
00072 void interpolate_gradient_3d(const image_t & image_reference, const ublas::fixed_vector<size_t, 3> & base_coordinates, const ublas::fixed_vector<float_t, 3> & truncated_coordinates, result_t & value)
00073 {
00074 value.assign(0);
00075
00076 for(size_t i = 0; i < 2; ++i)
00077 for(size_t j = 0; j < 2; ++j)
00078 for(size_t k = 0; k < 2; ++k)
00079 {
00080 value(0) += (delta(1, i)-delta(0, i)) *
00081 (delta(1, j)*truncated_coordinates(1)+delta(0, j)*(1-truncated_coordinates(1))) *
00082 (delta(1, k)*truncated_coordinates(2)+delta(0, k)*(1-truncated_coordinates(2))) *
00083 image_reference[base_coordinates + ublas::fixed_vector<size_t, 3>(i, j, k)];
00084
00085 value(1) += (delta(1, i)*truncated_coordinates(0)+delta(0, i)*(1-truncated_coordinates(0))) *
00086 (delta(1, j)-delta(0, j)) *
00087 (delta(1, k)*truncated_coordinates(2)+delta(0, k)*(1-truncated_coordinates(2))) *
00088 image_reference[base_coordinates + ublas::fixed_vector<size_t, 3>(i, j, k)];
00089
00090 value(2) += (delta(1, i)*truncated_coordinates(0)+delta(0, i)*(1-truncated_coordinates(0))) *
00091 (delta(1, j)*truncated_coordinates(1)+delta(0, j)*(1-truncated_coordinates(1))) *
00092 (delta(1, k)-delta(0, k)) *
00093 image_reference[base_coordinates + ublas::fixed_vector<size_t, 3>(i, j, k)];
00094 }
00095 }
00096 }
00097
00098
00105 template <class image_t>
00106 class PolynomialInterpolationAdaptor : public InterpolationAdaptorInterface<image_t>
00107 {
00108 public:
00110 PolynomialInterpolationAdaptor(const image_t & image_reference) : InterpolationAdaptorInterface<image_t>(image_reference)
00111 {}
00112
00113 typename InterpolationAdaptorInterface<image_t>::data_t operator[](const ublas::fixed_vector<float_t, InterpolationAdaptorInterface<image_t>::dimension> & index)
00114 {
00115 ublas::fixed_vector<float_t, InterpolationAdaptorInterface<image_t>::dimension> local_index;
00116 if( ! interpolation_adaptor_impl::offset_position(InterpolationAdaptorInterface<image_t>::size(), index, local_index))
00117 {
00118 return typename InterpolationAdaptorInterface<image_t>::data_t(0);
00119 }
00120
00121 ublas::fixed_vector<size_t, InterpolationAdaptorInterface<image_t>::dimension> base_coordinates;
00122 ublas::fixed_vector<float_t, InterpolationAdaptorInterface<image_t>::dimension> truncated_coordinates;
00123
00124 interpolation_adaptor_impl::compute_local_coordinates(local_index, InterpolationAdaptorInterface<image_t>::_image_reference.size(), base_coordinates, truncated_coordinates);
00125
00126 switch(InterpolationAdaptorInterface<image_t>::dimension)
00127 {
00128 case 1:
00129 return polynomial_interpolation_adaptor_impl::interpolate_1d(InterpolationAdaptorInterface<image_t>::_image_reference, base_coordinates, truncated_coordinates);
00130 case 2:
00131 return polynomial_interpolation_adaptor_impl::interpolate_2d(InterpolationAdaptorInterface<image_t>::_image_reference, base_coordinates, truncated_coordinates);
00132 case 3:
00133 return polynomial_interpolation_adaptor_impl::interpolate_3d(InterpolationAdaptorInterface<image_t>::_image_reference, base_coordinates, truncated_coordinates);
00134
00135 default:
00136 throw Exception("Exception: PolynomialInterpolationAdaptor not implemented for image dimension " + boost::lexical_cast<std::string>(InterpolationAdaptorInterface<image_t>::dimension) + ".");
00137 }
00138 }
00139
00141 void gradient (const ublas::fixed_vector<float_t, InterpolationAdaptorInterface<image_t>::dimension> & index, ublas::fixed_vector<typename InterpolationAdaptorInterface<image_t>::data_t, InterpolationAdaptorInterface<image_t>::dimension> & value)
00142 {
00143 typedef ublas::fixed_vector<typename InterpolationAdaptorInterface<image_t>::data_t, InterpolationAdaptorInterface<image_t>::dimension> return_data_t;
00144
00145 ublas::fixed_vector<float_t, InterpolationAdaptorInterface<image_t>::dimension> local_index;
00146 if( ! interpolation_adaptor_impl::offset_position(InterpolationAdaptorInterface<image_t>::size(), index, local_index))
00147 {
00148 value = return_data_t(0);
00149 return;
00150 }
00151
00152 ublas::fixed_vector<size_t, InterpolationAdaptorInterface<image_t>::dimension> base_coordinates;
00153 ublas::fixed_vector<float_t, InterpolationAdaptorInterface<image_t>::dimension> truncated_coordinates;
00154
00155 interpolation_adaptor_impl::compute_local_coordinates(local_index, InterpolationAdaptorInterface<image_t>::_image_reference.size(), base_coordinates, truncated_coordinates);
00156
00157 switch(InterpolationAdaptorInterface<image_t>::dimension)
00158 {
00159 case 1:
00160 polynomial_interpolation_adaptor_impl::interpolate_gradient_1d(InterpolationAdaptorInterface<image_t>::_image_reference, base_coordinates, truncated_coordinates, value);
00161 break;
00162 case 2:
00163 polynomial_interpolation_adaptor_impl::interpolate_gradient_2d(InterpolationAdaptorInterface<image_t>::_image_reference, base_coordinates, truncated_coordinates, value);
00164 break;
00165 case 3:
00166 polynomial_interpolation_adaptor_impl::interpolate_gradient_3d(InterpolationAdaptorInterface<image_t>::_image_reference, base_coordinates, truncated_coordinates, value);
00167 break;
00168
00169 default:
00170 throw Exception("Exception: LinearInterpolationAdaptor not implemented for image dimension " + boost::lexical_cast<std::string>(InterpolationAdaptorInterface<image_t>::dimension) + ".");
00171 }
00172 }
00173 };
00174 }
00175
00176 #endif
00177