Go to the documentation of this file.00001
00002 #ifndef vgl_fit_conics_2d_txx_
00003 #define vgl_fit_conics_2d_txx_
00004
00005
00006
00007 #include "vgl_fit_conics_2d.h"
00008 #include <vgl/vgl_vector_2d.h>
00009 #include <vgl/algo/vgl_conic_2d_regression.h>
00010 #include <vcl_iostream.h>
00011 #include <vcl_cassert.h>
00012
00013
00014
00015 template <class T>
00016 vgl_fit_conics_2d<T>::vgl_fit_conics_2d(const unsigned min_length,
00017 const T tol)
00018 : min_length_(min_length), tol_(tol)
00019 {
00020 }
00021
00022
00023
00024
00025 template <class T>
00026 void vgl_fit_conics_2d<T>::add_point(vgl_point_2d<T> const& p)
00027 {
00028 curve_.push_back(p);
00029 #ifdef DEBUG
00030 vcl_cout << p << '\n';
00031 #endif
00032 }
00033
00034
00035 template <class T>
00036 void vgl_fit_conics_2d<T>::add_point(T x, T y)
00037 {
00038 curve_.push_back(vgl_point_2d<T>(x, y));
00039 }
00040
00041
00042 template <class T>
00043 void vgl_fit_conics_2d<T>::clear()
00044 {
00045 curve_.clear();
00046 segs_.clear();
00047 }
00048
00049 template <class T>
00050 void vgl_fit_conics_2d<T>::output(const unsigned start_index,
00051 const unsigned end_index,
00052 vgl_conic<T> const& conic)
00053 {
00054 assert(start_index < curve_.size() && end_index <= curve_.size());
00055
00056 vgl_homg_point_2d<T> center = conic.centre();
00057 if (center.ideal(static_cast<T>(1e-06)))
00058 {
00059 vcl_cout << "Can't output a conic at infinity in vgl_fit_conics<T>\n";
00060 return;
00061 }
00062
00063
00064
00065
00066 int middle_index = (end_index-1-start_index)/2 + start_index;
00067 if (middle_index == static_cast<int>(start_index))
00068 middle_index = end_index-1;
00069 vgl_point_2d<T> pm = curve_[middle_index];
00070
00071 vgl_point_2d<T> ps = curve_[start_index], pe = curve_[end_index-1];
00072 vgl_vector_2d<T> vms(ps.x()-pm.x(), ps.y()-pm.y());
00073
00074 vgl_vector_2d<T> vme(pe.x()-pm.x(), pe.y()-pm.y());
00075
00076 T cp = cross_product(vms, vme);
00077
00078
00079 unsigned i1=start_index, i2 = end_index-1;
00080 if (cp > 1e-04)
00081 {
00082 i1 = end_index-1;
00083 i2 = start_index;
00084 }
00085
00086
00087
00088 vgl_conic_segment_2d<T> e_seg(curve_[i1], curve_[i2], conic);
00089 #ifdef DEBUG
00090 vcl_cout << "output " << e_seg << '\n';
00091 #endif
00092 segs_.push_back(e_seg);
00093 }
00094
00095 template <class T>
00096 bool vgl_fit_conics_2d<T>::fit()
00097 {
00098 if (curve_.size()<min_length_)
00099 {
00100 vcl_cout << "In vgl_fit_conics_2d<T>::fit() - number of points < min_length "
00101 << min_length_ << '\n';
00102 return false;
00103 }
00104
00105 vgl_conic_2d_regression<T> reg;
00106
00107
00108
00109 unsigned int ns = 0, nf = min_length_, cur_len = curve_.size();
00110 for (unsigned int i = ns; i<nf; ++i)
00111 reg.add_point(curve_[i]);
00112
00113 while (nf<=cur_len)
00114 {
00115 if (reg.fit()&®.get_rms_sampson_error()<tol_)
00116 {
00117 if (nf==cur_len)
00118 {
00119 output(ns, nf, reg.conic());
00120 return true;
00121 }
00122 #ifdef DEBUG
00123 vcl_cout << "Initial fit error " << reg.get_rms_sampson_error()
00124 << " for\n" << reg.conic() << '\n';
00125 #endif
00126 bool below_error_tol = true;
00127 bool data_added = false;
00128 while (nf<cur_len&&below_error_tol)
00129 {
00130 vgl_point_2d<T>& p = curve_[nf];
00131
00132 T error = reg.get_rms_error_est(p);
00133 below_error_tol = error<tol_;
00134 if (below_error_tol)
00135 {
00136 reg.add_point(p);
00137 data_added = true;
00138 nf++;
00139 #ifdef DEBUG
00140 vcl_cout << "Adding point " << p << "with estimated error "
00141 << error << '\n';
00142 #endif
00143 }
00144 }
00145
00146
00147 if (!data_added)
00148 {
00149 output(ns, nf, reg.conic());
00150 ns = nf-1; nf=ns+min_length_;
00151 if (nf<=cur_len)
00152 {
00153 reg.clear_points();
00154 for (unsigned int i = ns; i<nf; i++)
00155 reg.add_point(curve_[i]);
00156 }
00157 }
00158 }
00159
00160
00161
00162 else
00163 {
00164 reg.remove_point(curve_[ns]);
00165 ns++;
00166 if (reg.get_n_pts()>min_length_)
00167 while (reg.get_n_pts()>min_length_+1)
00168 {
00169 nf--;
00170 reg.remove_point(curve_[nf]);
00171 }
00172 else if (nf<cur_len)
00173 {
00174 reg.add_point(curve_[nf]);
00175 nf++;
00176 }
00177 else
00178 nf++;
00179 }
00180 }
00181 return true;
00182 }
00183
00184
00185 #undef VGL_FIT_CONICS_2D_INSTANTIATE
00186 #define VGL_FIT_CONICS_2D_INSTANTIATE(T) \
00187 template class vgl_fit_conics_2d<T >
00188
00189 #endif // vgl_fit_conics_2d_txx_