contrib/brl/bseg/sdet/sdet_fit_conics.cxx
Go to the documentation of this file.
00001 // This is brl/bseg/sdet/sdet_fit_conics.cxx
00002 #include "sdet_fit_conics.h"
00003 //:
00004 // \file
00005 
00006 #include <vgl/vgl_point_2d.h>
00007 #include <vgl/vgl_conic_segment_2d.h>
00008 #include <vsol/vsol_conic_2d.h>
00009 #include <vtol/vtol_edge_2d.h>
00010 #include <vdgl/vdgl_digital_curve.h>
00011 #include <vdgl/vdgl_interpolator.h>
00012 #include <vdgl/vdgl_interpolator_sptr.h>
00013 #include <vdgl/vdgl_edgel_chain.h>
00014 #include <vdgl/vdgl_edgel_chain_sptr.h>
00015 
00016 //---------------------------------------------------------------
00017 // Constructors
00018 //
00019 //----------------------------------------------------------------
00020 
00021 //: constructor from a parameter block (the only way)
00022 //
00023 sdet_fit_conics::sdet_fit_conics(sdet_fit_conics_params& flp)
00024   : sdet_fit_conics_params(flp), fitter_(vgl_fit_conics_2d<double>())
00025 {
00026 }
00027 
00028 //:Default Destructor
00029 sdet_fit_conics::~sdet_fit_conics()
00030 {
00031 }
00032 
00033 //-------------------------------------------------------------------------
00034 //: Set the edges to be processed
00035 //
00036 void sdet_fit_conics::set_edges(vcl_vector<vtol_edge_2d_sptr> const& edges)
00037 {
00038   segs_valid_ = false;
00039   edges_=edges;
00040 }
00041 
00042 //--------------------------------------------------------------------------
00043 //:
00044 //  Convert each digital curve to a set of vgl_point_2d<double> and add
00045 //  them to vgl linear regression fitter point set. A set of line segments
00046 //  are computed that fit the point set within a specified mean square
00047 //  tolerance.  The resulting vgl_line_segment_2d<double> segments
00048 //  are converted back to vsol geometry.
00049 //
00050 bool sdet_fit_conics::fit_conics()
00051 {
00052   if (segs_valid_)
00053     return false;
00054   if (!edges_.size())
00055     return false;
00056   fitter_.set_min_fit_length(min_fit_length_);
00057   fitter_.set_rms_error_tol(rms_distance_);
00058   for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges_.begin();
00059        eit != edges_.end(); eit++)
00060   {
00061     vsol_curve_2d_sptr c = (*eit)->curve();
00062     vdgl_digital_curve_sptr dc = c->cast_to_vdgl_digital_curve();
00063     if (!dc)
00064       continue;
00065     vdgl_interpolator_sptr intp = dc->get_interpolator();
00066     vdgl_edgel_chain_sptr ec = intp->get_edgel_chain();
00067     fitter_.clear();
00068     int nedgl = ec->size();
00069     if (nedgl<min_fit_length_)
00070       continue;
00071     for (int i=0; i<nedgl; i++)
00072     {
00073       vgl_point_2d<double> p((*ec)[i].x(), (*ec)[i].y());
00074       fitter_.add_point(p);
00075     }
00076 
00077     fitter_.fit();
00078     vcl_vector<vgl_conic_segment_2d<double> >& segs = fitter_.get_conic_segs();
00079     for (vcl_vector<vgl_conic_segment_2d<double> >::iterator sit=segs.begin();
00080          sit != segs.end(); sit++)
00081     {
00082       vsol_conic_2d_sptr conic = new vsol_conic_2d(*sit);
00083       vcl_cout << "Fitted a conic of type " << conic->real_conic_type() << '\n';
00084       //adding a condition on aspect ratio
00085       if (conic->real_type() != vsol_conic_2d::real_ellipse)
00086       {
00087           conic_segs_.push_back(conic);
00088       }
00089       else
00090       {
00091         double cx, cy, width, height, angle;
00092         conic->ellipse_parameters(cx,cy,angle,width,height);
00093         if (width/height < aspect_ratio_)
00094           conic_segs_.push_back(conic);
00095       }
00096     }
00097   }
00098   segs_valid_ = true;
00099   return true;
00100 }
00101 
00102 //-------------------------------------------------------------------------
00103 //: Get the conic segments
00104 //
00105 vcl_vector<vsol_conic_2d_sptr>& sdet_fit_conics::get_conic_segs()
00106 {
00107   if (segs_valid_)
00108     return conic_segs_;
00109   this->fit_conics();
00110   return conic_segs_;
00111 }
00112 
00113 //----------------------------------------------------------
00114 //: Clear internal storage
00115 //
00116 void sdet_fit_conics::clear()
00117 {
00118   fitter_.clear();
00119   edges_.clear();
00120   conic_segs_.clear();
00121   segs_valid_ = false;
00122 }
00123