00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef SHAPE_BOUNDARYDISCRETIZER_H
00010 #define SHAPE_BOUNDARYDISCRETIZER_H
00011
00012 #include <shape/Box.hpp>
00013
00014 namespace imaging
00015 {
00017 namespace boundary_discretizer_impl
00018 {
00019 float_t compute_curve_curvature(ublas::fixed_vector<float_t, 2> & first_derivative, ublas::fixed_vector<float_t, 2> & second_derivative);
00020
00021 template <class const_vector_accessor_t>
00022 void compute_zero_extension(const const_vector_accessor_t & vector_field, const ublas::fixed_vector<float_t, const_vector_accessor_t::dimension> & point, ublas::fixed_vector<float_t, const_vector_accessor_t::dimension> & value)
00023 {
00024 const size_t N = const_vector_accessor_t::dimension;
00025 bool is_valid = true;
00026 bool no_valid_index = true;
00027 ublas::fixed_vector<size_t, N> valid_index;
00028 value = ublas::scalar_vector<float_t>(N, 0.0);
00029
00030
00031 for(size_t i = 0; i < N; ++i)
00032 if(point(i) < 0.0)
00033 return;
00034
00035 valid_index = ublas::fixed_vector<size_t, N>(point);
00036 int valid_coordinate;
00037
00038 for(size_t i = 0; i < N; ++i)
00039 if( ! ( valid_index(i) < vector_field.size()(i) ) )
00040 {
00041 if(! is_valid)
00042 return;
00043 else
00044 {
00045 valid_index(i) = vector_field.size()(i) - 1;
00046 is_valid = false;
00047 }
00048 valid_coordinate = i;
00049 no_valid_index = false;
00050 }
00051
00052 if(no_valid_index)
00053 {
00054 value = vector_field[ublas::fixed_vector<size_t, N>(point)];
00055 return;
00056 }
00057
00058 value(valid_coordinate) = vector_field[valid_index](valid_coordinate);
00059 }
00060 }
00061
00068 template <size_t N>
00069 class BoundaryDiscretizer
00070 {
00071 protected:
00073 size_t _n_points;
00074
00075 public:
00077 static const size_t SHAPE_DIMENSION = N;
00078
00080 BoundaryDiscretizer(size_t n_points) : _n_points(n_points) {}
00081
00082 virtual ~BoundaryDiscretizer() {}
00083
00085 size_t n_points() const { return _n_points; }
00086
00088 virtual void evaluate(size_t i, ublas::fixed_vector<float_t, SHAPE_DIMENSION> & point, ublas::fixed_vector<float_t, SHAPE_DIMENSION> & normal, float_t & curvature) const = 0;
00089
00091 ublas::fixed_vector<float_t, SHAPE_DIMENSION> operator()(size_t i, ublas::fixed_vector<float_t, SHAPE_DIMENSION> & normal, float_t & curvature) const
00092 {
00093 ublas::fixed_vector<float_t, SHAPE_DIMENSION> point;
00094 evaluate(i, point, normal, curvature);
00095 return point;
00096 }
00097
00099 ublas::fixed_vector<float_t, SHAPE_DIMENSION> operator()(size_t i, ublas::fixed_vector<float_t, SHAPE_DIMENSION> & normal) const
00100 {
00101 float_t curvature;
00102 return operator()(i, normal, curvature);
00103 }
00104
00106 ublas::fixed_vector<float_t, SHAPE_DIMENSION> operator()(size_t i) const
00107 {
00108 ublas::fixed_vector<float_t, SHAPE_DIMENSION> normal;
00109 return operator()(i, normal);
00110 }
00111
00113 template <class const_accessort_t>
00114 typename const_accessort_t::data_t integrate(const const_accessort_t & image) const
00115 {
00116 typename const_accessort_t::data_t result = 0.0;
00117 ublas::fixed_vector<float_t, SHAPE_DIMENSION> point, normal;
00118
00119 for(size_t i = 0; i < n_points(); ++i)
00120 {
00121 point = (*this)(i, normal);
00122
00123
00124 ublas::fixed_vector<size_t, const_accessort_t::dimension> pixel_position = ublas::fixed_vector<size_t, const_accessort_t::dimension>(point);
00125 bool is_valid_pixel = true;
00126
00127 for(size_t i = 0; i < const_accessort_t::dimension; ++i)
00128 {
00129 if( ! ( pixel_position(i) < image.size()(i) ) )
00130 {
00131 is_valid_pixel = false;
00132 break;
00133 }
00134 }
00135
00136 if(is_valid_pixel)
00137 result += image[pixel_position] * norm_2(normal);
00138 }
00139
00140 return result;
00141 }
00142
00144 float_t compute_boundary_area() const
00145 {
00146 float_t result = 0.0;
00147 ublas::fixed_vector<float_t, SHAPE_DIMENSION> point, normal;
00148
00149 for(size_t i = 0; i < n_points(); ++i)
00150 {
00151 point = (*this)(i, normal);
00152
00153 result += norm_2(normal);
00154 }
00155
00156 return result;
00157 }
00158
00159
00161 template <class const_vector_accessor_t>
00162 float_t integrate_vector_field
00163 (const const_vector_accessor_t & vector_field) const
00164 {
00165 float_t result = 0.0;
00166 ublas::fixed_vector<float_t, SHAPE_DIMENSION> point, normal;
00167
00168 for(size_t i = 0; i < n_points(); ++i)
00169 {
00170 point = (*this)(i, normal);
00171
00172
00173 ublas::fixed_vector<size_t, const_vector_accessor_t::dimension> pixel_position = ublas::fixed_vector<size_t, const_vector_accessor_t::dimension>(point);
00174 bool is_valid_pixel = true;
00175
00176 for(size_t i = 0; i < const_vector_accessor_t::dimension; ++i)
00177 {
00178 if( ! ( pixel_position(i) < vector_field.size()(i) ) )
00179 {
00180 is_valid_pixel = false;
00181 break;
00182 }
00183 }
00184
00185 if(is_valid_pixel)
00186
00187 result += inner_prod(vector_field[pixel_position], normal);
00188 else
00189 {
00190 ublas::fixed_vector<float_t, SHAPE_DIMENSION> value;
00191 boundary_discretizer_impl::compute_zero_extension(vector_field, point, value);
00192 result += inner_prod(value, normal);
00193 }
00194 }
00195
00196 return result;
00197 }
00198
00199
00200
00202 Box<SHAPE_DIMENSION> compute_bounding_box() const
00203 {
00204 ublas::fixed_vector<float_t, SHAPE_DIMENSION> lower_corner, upper_corner, point;
00205
00206 if(n_points() == 0)
00207 return Box<SHAPE_DIMENSION>();
00208
00209 lower_corner = (*this)(0);
00210 upper_corner = (*this)(0);
00211
00212 for(size_t i = 1; i < n_points(); ++i)
00213 {
00214 point = (*this)(i);
00215 for(size_t j = 0; j < SHAPE_DIMENSION; ++j)
00216 {
00217 if(point(j) < lower_corner(j))
00218 lower_corner(j) = point(j);
00219
00220 if(point(j) > upper_corner(j))
00221 upper_corner(j) = point(j);
00222 }
00223 }
00224
00225 return Box<SHAPE_DIMENSION>(lower_corner, upper_corner);
00226 }
00227 };
00228
00230 float_t compute_intersection_volume(const BoundaryDiscretizer<2> & shape_a, const BoundaryDiscretizer<2> & shape_b);
00231 }
00232
00233
00234 #endif