2 #ifndef vgl_conic_2d_regression_hxx_ 3 #define vgl_conic_2d_regression_hxx_ 11 # include <vcl_msvc_warnings.h> 13 #include <vnl/vnl_vector_fixed.h> 14 #include <vnl/vnl_inverse.h> 15 #include <vnl/vnl_numeric_traits.h> 16 #include <vnl/algo/vnl_svd.h> 23 partial_sums_.resize(14, 0.0);
26 Dinv_.put(0,0,0.5); Dinv_.put(1,1,1.0); Dinv_.put(2,2,0.5);
56 if (hp.
w() == 0 || hc.
w() == 0) {
57 return vnl_numeric_traits<T>::maxval;
69 typename std::vector<vgl_point_2d<T> >::iterator pit;
70 for (pit = points_.begin(); pit != points_.end(); ++pit)
72 T x = pit->x(), y = pit->y();
73 T alg_dist = (a*x + b*y + d)*x + (c*y + e)*y + f;
74 T two = static_cast<T>(2);
75 T dx = two*a*x + b*y + d;
76 T dy = two*c*y + b*x + e;
77 T grad_mag_sqrd = dx*dx+dy*dy;
78 sum += (alg_dist*alg_dist)/grad_mag_sqrd;
82 sampson_error_ = static_cast<T>(std::sqrt(sum/npts_));
85 sampson_error_ = vnl_numeric_traits<T>::maxval;
99 typename std::vector<vgl_point_2d<T> >::iterator result;
100 result = std::find(points_.begin(), points_.end(), p);
101 if (result != points_.end())
102 points_.erase(result);
117 hnorm_points_.clear();
119 std::vector<vgl_homg_point_2d<T> > hpoints;
121 typename std::vector<vgl_point_2d<T> >::iterator pit;
122 for (pit = points_.begin(); pit != points_.end(); ++pit)
126 trans_.compute_from_points(hpoints,
false);
130 pit != hpoints.end(); ++pit)
131 hnorm_points_.push_back(trans_(*pit));
133 for (
typename std::vector<T>::iterator dit = partial_sums_.begin();
134 dit != partial_sums_.end(); ++dit)
139 pit != hnorm_points_.end(); ++pit)
141 T x = pit->x()/pit->w(),
142 y = pit->y()/pit->w();
144 x2 = x*x; x3 = x2*x; y2 = y*y; y3 = y2*y;
145 partial_sums_[0] += x3*x; partial_sums_[1] += x3*y;
146 partial_sums_[2] += x2*y2; partial_sums_[3] += x*y3;
147 partial_sums_[4] += y3*y; partial_sums_[5] += x3;
148 partial_sums_[6] += x2*y; partial_sums_[7] += x*y2;
149 partial_sums_[8] += y3; partial_sums_[9] += x2;
150 partial_sums_[10] += x*y; partial_sums_[11] += y2;
151 partial_sums_[12] += x; partial_sums_[13] += y;
158 S11_.put(0,0,partial_sums_[0]);
159 S11_.put(0,1,partial_sums_[1]);
160 S11_.put(0,2,partial_sums_[2]);
161 S11_.put(1,0,partial_sums_[1]);
162 S11_.put(1,1,partial_sums_[2]);
163 S11_.put(1,2,partial_sums_[3]);
164 S11_.put(2,0,partial_sums_[2]);
165 S11_.put(2,1,partial_sums_[3]);
166 S11_.put(2,2,partial_sums_[4]);
168 S12_.put(0,0,partial_sums_[5]);
169 S12_.put(0,1,partial_sums_[6]);
170 S12_.put(0,2,partial_sums_[9]);
171 S12_.put(1,0,partial_sums_[6]);
172 S12_.put(1,1,partial_sums_[7]);
173 S12_.put(1,2,partial_sums_[10]);
174 S12_.put(2,0,partial_sums_[7]);
175 S12_.put(2,1,partial_sums_[8]);
176 S12_.put(2,2,partial_sums_[11]);
178 S22_.put(0,0,partial_sums_[9]);
179 S22_.put(0,1,partial_sums_[10]);
180 S22_.put(0,2,partial_sums_[12]);
181 S22_.put(1,0,partial_sums_[10]);
182 S22_.put(1,1,partial_sums_[11]);
183 S22_.put(1,2,partial_sums_[13]);
184 S22_.put(2,0,partial_sums_[12]);
185 S22_.put(2,1,partial_sums_[13]);
186 T npts = static_cast<T>(npts_);
194 if (this->get_n_pts()<5)
198 this->compute_partial_sums();
201 this->fill_scatter_matrix();
204 T det = vnl_det(S22_);
205 if (det == static_cast<T>(0))
207 std::cout <<
"Singular S22 Matrix in vgl_conic_2d_regression::fit()\n";
211 vnl_matrix_fixed<T,3,3> S12_T = S12_.transpose();
212 vnl_matrix_fixed<T,3,3> S_lambda =
213 Dinv_*(S11_- S12_*(vnl_inverse(S22_)*S12_T));
215 vnl_svd<T> svd(S_lambda.as_ref());
216 cost_ = svd.sigma_min();
217 vnl_vector_fixed<T,3> v1 = svd.nullvector();
218 vnl_vector_fixed<T,3> v2 = - vnl_inverse(S22_)*S12_T*v1;
219 vgl_conic<T> nc(v1[0], v1[1], v1[2], v2[0], v2[1], v2[2]);
231 this->set_sampson_error(conic_.a(), conic_.b(), conic_.c(),
232 conic_.d(), conic_.e(), conic_.f());
240 str <<
"Current Pointset has " << npts_ <<
" points\n";
242 typename std::vector<vgl_point_2d<T> >::iterator pit;
243 for (pit = points_.begin(); pit != points_.end(); ++pit)
248 #undef VGL_CONIC_2D_REGRESSION_INSTANTIATE 249 #define VGL_CONIC_2D_REGRESSION_INSTANTIATE(T) \ 250 template class vgl_conic_2d_regression<T > 252 #endif // vgl_conic_2d_regression_hxx_ void remove_point(vgl_point_2d< T > const &p)
void compute_partial_sums()
2D homogeneous operations
void add_point(vgl_point_2d< T > const &p)
vgl_conic_2d_regression()
Constructors.
static vgl_homg_point_2d< T > closest_point(vgl_homg_line_2d< T > const &l, vgl_homg_point_2d< T > const &p)
Return the point on the line closest to the given point.
T get_rms_error_est(vgl_point_2d< T > const &p) const
get the estimated Euclidean error with respect to the fitted conic segment in the original frame.
void clear_points()
clear the regression data.
bool fit()
the fitting method.
void set_sampson_error(T a, T b, T c, T d, T e, T f)
Fits a conic to a set of points using linear regression.
void fill_scatter_matrix()
double vgl_distance(vgl_point_2d< T >const &p1, vgl_point_2d< T >const &p2)
return the distance between two points.
void print_pointset(std::ostream &str=std::cout)
Set of distance functions.
Represents a homogeneous 2D point.
T get_rms_algebraic_error() const
get the current algebraic fitting error in the normalized frame.