00001
00002 #include "sdet_fit_conics.h"
00003
00004
00005 #include <vsol/vsol_conic_2d.h>
00006 #include <vtol/vtol_edge_2d.h>
00007 #include <vdgl/vdgl_digital_curve.h>
00008 #include <vdgl/vdgl_interpolator.h>
00009 #include <vdgl/vdgl_interpolator_sptr.h>
00010 #include <vdgl/vdgl_edgel_chain.h>
00011 #include <vdgl/vdgl_edgel_chain_sptr.h>
00012
00013
00014
00015
00016
00017
00018
00019
00020 sdet_fit_conics::sdet_fit_conics(sdet_fit_conics_params& flp)
00021 : sdet_fit_conics_params(flp), fitter_(vgl_fit_conics_2d<double>())
00022 {
00023 }
00024
00025
00026 sdet_fit_conics::~sdet_fit_conics()
00027 {
00028 }
00029
00030
00031
00032
00033 void sdet_fit_conics::set_edges(vcl_vector<vtol_edge_2d_sptr> const& edges)
00034 {
00035 segs_valid_ = false;
00036 edges_=edges;
00037 }
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 bool sdet_fit_conics::fit_conics()
00048 {
00049 if (segs_valid_)
00050 return false;
00051 if (!edges_.size())
00052 return false;
00053 fitter_.set_min_fit_length(min_fit_length_);
00054 fitter_.set_rms_error_tol(rms_distance_);
00055 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges_.begin();
00056 eit != edges_.end(); eit++)
00057 {
00058 vsol_curve_2d_sptr c = (*eit)->curve();
00059 vdgl_digital_curve_sptr dc = c->cast_to_vdgl_digital_curve();
00060 if (!dc)
00061 continue;
00062 vdgl_interpolator_sptr intp = dc->get_interpolator();
00063 vdgl_edgel_chain_sptr ec = intp->get_edgel_chain();
00064 fitter_.clear();
00065 int nedgl = ec->size();
00066 if(nedgl<min_fit_length_)
00067 continue;
00068 for (int i=0; i<nedgl; i++)
00069 {
00070 vgl_point_2d<double> p((*ec)[i].x(), (*ec)[i].y());
00071 fitter_.add_point(p);
00072 }
00073
00074 fitter_.fit();
00075 vcl_vector<vgl_conic_segment_2d<double> >& segs = fitter_.get_conic_segs();
00076 for (vcl_vector<vgl_conic_segment_2d<double> >::iterator sit=segs.begin();
00077 sit != segs.end(); sit++)
00078 {
00079 vsol_conic_2d_sptr conic = new vsol_conic_2d(*sit);
00080 vcl_cout << "Fitted a conic of type " << conic->real_type() << '\n';
00081
00082 if (conic->real_type() != 1)
00083 {
00084 conic_segs_.push_back(conic);
00085 }
00086 else
00087 {
00088 double cx, cy, width, height, angle;
00089 conic->ellipse_parameters(cx,cy,angle,width,height);
00090 if ((width/height)<aspect_ratio_)
00091 conic_segs_.push_back(conic);
00092 }
00093
00094 }
00095 }
00096 segs_valid_ = true;
00097 return true;
00098 }
00099
00100
00101
00102
00103 vcl_vector<vsol_conic_2d_sptr>& sdet_fit_conics::get_conic_segs()
00104 {
00105 if (segs_valid_)
00106 return conic_segs_;
00107 this->fit_conics();
00108 return conic_segs_;
00109 }
00110
00111
00112
00113
00114 void sdet_fit_conics::clear()
00115 {
00116 fitter_.clear();
00117 edges_.clear();
00118 conic_segs_.clear();
00119 segs_valid_ = false;
00120 }
00121