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 }