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