Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vifa_int_face_attr_common.cxx

Go to the documentation of this file.
00001 // This is gel/vifa/vifa_int_face_attr_common.cxx
00002 #include <vdgl/vdgl_fit_lines.h>
00003 #include <vtol/vtol_intensity_face.h>
00004 #include <vgl/vgl_point_2d.h>
00005 #include <vsol/vsol_line_2d.h>
00006 #include <vtol/vtol_vertex_sptr.h>
00007 #include <vifa/vifa_int_face_attr_common.h>
00008 #include <vifa/vifa_group_pgram.h>
00009 #include <vcl_cmath.h> // fabs()
00010 
00011 vifa_int_face_attr_common::
00012 vifa_int_face_attr_common(vdgl_fit_lines_params*    fitter_params,
00013                           vifa_group_pgram_params*  gpp_s,
00014                           vifa_group_pgram_params*  gpp_w,
00015                           vifa_coll_lines_params*   cpp,
00016                           vifa_norm_params*         np) :
00017   vifa_int_face_attr_common_params(fitter_params, gpp_s, gpp_w, cpp, np)
00018 {
00019   this->init();
00020 }
00021 
00022 vifa_int_face_attr_common::~vifa_int_face_attr_common()
00023 {
00024 }
00025 
00026 
00027 // ------------------------------------------------------------
00028 // Data access & computation for non-attributes
00029 //
00030 
00031 
00032 edge_2d_list& vifa_int_face_attr_common::
00033 GetFittedEdges()
00034 {
00035   if (!fitted_edges_.size())
00036     this->fit_lines();
00037 
00038   return fitted_edges_;
00039 }
00040 
00041 coll_list& vifa_int_face_attr_common::
00042 get_collinear_lines()
00043 {
00044   if (!cpp_)
00045     cpp_ = new vifa_coll_lines_params;
00046 
00047   if (!collinear_lines_.size())
00048     this->find_collinear_lines();
00049 
00050   return collinear_lines_;
00051 }
00052 
00053 double vifa_int_face_attr_common::
00054 col_collapse()
00055 {
00056   double  collapsed_count = 0;
00057   double  total_count = 0;
00058 
00059   for (coll_iterator c = collinear_lines_.begin();
00060        c != collinear_lines_.end(); ++c)
00061   {
00062     total_count++;
00063 
00064     if ((*c)->get_discard_flag())
00065       collapsed_count++;
00066   }
00067 
00068   if (total_count == 0)
00069     return 0;
00070 
00071   return collapsed_count / total_count;
00072 }
00073 
00074 double vifa_int_face_attr_common::
00075 get_contrast_across_edge(vtol_edge_sptr  e, double dflt_cont)
00076 {
00077   double    cont = dflt_cont;
00078   face_list faces; e->faces(faces);
00079 
00080   // Expect only one or two intensity faces for 2-D case
00081   if (faces.size() == 2)
00082   {
00083     vtol_intensity_face*  f1 = faces[0]->cast_to_intensity_face();
00084     vtol_intensity_face*  f2 = faces[1]->cast_to_intensity_face();
00085 
00086     if (f1 && f2)
00087       cont = vcl_fabs(f1->Io() - f2->Io());
00088   }
00089   return cont;
00090 }
00091 
00092 vifa_coll_lines_sptr vifa_int_face_attr_common::
00093 get_line_along_edge(vtol_edge* edge)
00094 {
00095   vifa_coll_lines_sptr  ret(0);
00096   vtol_vertex_sptr    ev1 = edge->v1();
00097   vtol_vertex_sptr    ev2 = edge->v2();
00098 
00099   for (coll_iterator c = collinear_lines_.begin();
00100        c != collinear_lines_.end(); ++c)
00101   {
00102     edge_2d_list&  c_edges = (*c)->get_contributors();
00103 
00104     for (edge_2d_iterator e = c_edges.begin(); e != c_edges.end(); ++e)
00105     {
00106       vtol_vertex_sptr  v1 = (*e)->v1();
00107       vtol_vertex_sptr  v2 = (*e)->v2();
00108 
00109       if (((*ev1 == *v1) && (*ev2 == *v2)) ||
00110           ((*ev1 == *v2) && (*ev2 == *v1)))
00111         ret = *c;
00112     }
00113   }
00114 
00115   return ret;
00116 }
00117 
00118 
00119 // ------------------------------------------------------------
00120 // Individual attribute computation
00121 //
00122 
00123 
00124 // Compute measure of projective parallelism, ratio of edges that have some
00125 // projective overlap to total edge length.  Computes fitted_edges_ if needed.
00126 float vifa_int_face_attr_common::
00127 StrongParallelSal()
00128 {
00129   if (para_sal_strong_ < 0)
00130   {
00131     if (!gpp_s_.ptr())
00132     {
00133       const float  angle_increment = 5.f;
00134       gpp_s_ = new vifa_group_pgram_params(angle_increment);
00135     }
00136 
00137     para_sal_strong_ = this->compute_parallel_sal(gpp_s_);
00138   }
00139 
00140   return para_sal_strong_;
00141 }
00142 
00143 float vifa_int_face_attr_common::
00144 WeakParallelSal()
00145 {
00146   if (para_sal_weak_ < 0)
00147   {
00148     if (!gpp_w_.ptr())
00149     {
00150       const float  angle_increment = 20.f;
00151       gpp_w_ = new vifa_group_pgram_params(angle_increment);
00152     }
00153 
00154     para_sal_weak_ = this->compute_parallel_sal(gpp_w_);
00155   }
00156 
00157   return para_sal_weak_;
00158 }
00159 
00160 
00161 // ------------------------------------------------------------
00162 // Protected methods
00163 //
00164 
00165 
00166 void vifa_int_face_attr_common::
00167 init()
00168 {
00169   attributes_valid_    = false;
00170   complexity_        = -1;
00171   weighted_complexity_  = -1;
00172   aspect_ratio_      = -1;
00173   peri_length_      = -1;
00174   weighted_peri_length_  = -1;
00175   para_sal_weak_      = -1;
00176   para_sal_strong_    = -1;
00177 }
00178 
00179 // Fit edges of face_ with straight lines, but only if cached versions
00180 // are not available.  Sets fitter_params_ with defaults if empty.
00181 // Results are added to fitted_edges_.
00182 void vifa_int_face_attr_common::
00183 fit_lines()
00184 {
00185   edge_2d_list  edges_in_vect = this->GetEdges();
00186 
00187 #ifdef DEBUG
00188     vcl_cout << "ifac::fit_lines(): " << edges_in_vect.size()
00189              << " edges available\n";
00190 #endif
00191 
00192   if (!edges_in_vect.size())
00193   {
00194     vcl_cerr << "vifa_int_face_attr_common::fit_lines: face_ is not set\n";
00195     return;
00196   }
00197 
00198   vcl_vector<vdgl_digital_curve_sptr>  curves_in;
00199   for (edge_2d_iterator ei = edges_in_vect.begin();
00200        ei != edges_in_vect.end(); ei++)
00201   {
00202     vsol_curve_2d_sptr c = (*ei)->curve();
00203     vdgl_digital_curve_sptr dc = c->cast_to_vdgl_digital_curve();
00204     if (!dc)
00205       continue;
00206     curves_in.push_back(dc);
00207   }
00208 
00209   if (!fitter_params_.ptr())
00210   {
00211     const int  fit_length = 6;
00212     fitter_params_ = new vdgl_fit_lines_params(fit_length);
00213   }
00214 
00215   // Call the line fitting routine (thanks Joe!)
00216   vdgl_fit_lines  fitter(*(fitter_params_.ptr()));
00217   fitter.set_curves(curves_in);
00218   vcl_vector<vsol_line_2d_sptr>&  segs = fitter.get_line_segs();
00219 
00220 #ifdef DEBUG
00221     vcl_cout << "ifac::fit_lines(): " << segs.size() << " segments from fitter\n";
00222 #endif
00223 
00224   // Convert fitter output to edges & update statistics
00225   vcl_vector<vsol_line_2d_sptr>::iterator  segi = segs.begin();
00226   for (; segi != segs.end(); segi++)
00227   {
00228     vsol_line_2d_sptr  seg = *segi;
00229     vtol_vertex_2d_sptr  v1 = new vtol_vertex_2d(*(seg->p0()));
00230     vtol_vertex_2d_sptr  v2 = new vtol_vertex_2d(*(seg->p1()));
00231     vtol_edge_2d_sptr  e = new vtol_edge_2d(v1, v2);
00232     fitted_edges_.push_back(e);
00233 
00234     // Update statistics
00235     fitted_edges_stats_.add_sample(seg->length());
00236   }
00237 }
00238 
00239 void vifa_int_face_attr_common::
00240 find_collinear_lines()
00241 {
00242   // sort fitted edges by length into f_edges
00243   edge_2d_list  unsorted_edges = this->GetFittedEdges();
00244   edge_2d_list  f_edges;
00245   for (edge_2d_iterator e = unsorted_edges.begin();
00246        e != unsorted_edges.end(); ++e)
00247   {
00248     double        len = (*e)->curve()->length();
00249     edge_2d_iterator  slot = f_edges.begin();
00250     for (; slot != f_edges.end(); ++slot)
00251       if ((*slot)->curve()->length() < len)
00252       {
00253         f_edges.insert(slot, *e);
00254         break;
00255       }
00256   }
00257 
00258   // build up a list of collinear line buckets
00259   coll_list    unfiltered_lines;
00260   coll_iterator  match;
00261 
00262 #ifdef DEBUG
00263   vcl_cout << "Collineating: ";
00264 #endif
00265   for (edge_2d_iterator e = f_edges.begin(); e != f_edges.end(); ++e)
00266   {
00267 #ifdef DEBUG
00268     vcl_cout << '.';
00269 #endif
00270 
00271     if ((*e)->curve()->length() == 0)
00272       continue;
00273 
00274     bool  match_flag = find_collinear_match(*e,
00275                                             unfiltered_lines,
00276                                             cpp_->midpt_distance(),
00277                                             match);
00278 
00279     if (!match_flag)
00280     {
00281       vifa_coll_lines_sptr  cl(new vifa_coll_lines(*e, cpp_->angle_tolerance()));
00282 
00283       unfiltered_lines.push_back(cl);
00284     }
00285     else
00286       (*match)->add_and_update(*e);
00287   }
00288 
00289 #ifdef DEBUG
00290   vcl_cout << vcl_endl;
00291 #endif
00292 
00293   // remove lines whose support is too low
00294   for (coll_iterator c = unfiltered_lines.begin();
00295        c != unfiltered_lines.end(); ++c)
00296   {
00297     double  span = (*c)->spanning_length();
00298     double  support = (*c)->support_length();
00299 
00300     if ((support/span) >= cpp_->discard_threshold())
00301     {
00302       collinear_lines_.push_back(*c);
00303       col_span_.add_sample(span);
00304       col_support_.add_sample(support);
00305       col_contrib_.add_sample((*c)->get_contributors().size());
00306     }
00307     else
00308     {
00309       // Unwind the unsupported line
00310       edge_2d_list&  contrib = (*c)->get_contributors();
00311       for (edge_2d_iterator e = contrib.begin(); e != contrib.end(); ++e)
00312       {
00313         vifa_coll_lines_sptr  cl(new vifa_coll_lines(*e,
00314                                                      cpp_->angle_tolerance(),
00315                                                      cpp_->endpt_distance(),
00316                                                      true));
00317 
00318         collinear_lines_.push_back(cl);
00319 
00320         double  span = cl->spanning_length();
00321         double  support = cl->support_length();
00322 
00323         col_span_.add_sample(span);
00324         col_support_.add_sample(support);
00325         col_contrib_.add_sample(cl->get_contributors().size());
00326       }
00327     }
00328   }
00329 
00330 #ifdef DEBUG
00331   vcl_cout << unfiltered_lines.size() << " raw collinear lines; "
00332            << collinear_lines_.size() << " lines above discard threshold "
00333            << cpp_->discard_threshold_ << vcl_endl;
00334 #endif
00335 }
00336 
00337 bool vifa_int_face_attr_common::
00338 find_collinear_match(vtol_edge_2d_sptr edge,
00339                      coll_list&        lines,
00340                      double            dist_threshold,
00341                      coll_iterator&    result)
00342 {
00343   double      min_dist = dist_threshold;
00344   coll_iterator  match = lines.end();
00345   for (coll_iterator c = lines.begin(); c != lines.end(); ++c)
00346   {
00347     double  dist = (*c)->get_measure(edge);
00348     if ((dist < dist_threshold) && (dist < min_dist))
00349     {
00350       min_dist = dist;
00351       match = c;
00352     }
00353   }
00354 
00355   if (match == lines.end())
00356   {
00357     return false;
00358   }
00359 
00360   result = match;
00361   return true;
00362 }
00363 
00364 float vifa_int_face_attr_common::
00365 compute_parallel_sal(vifa_group_pgram_params_sptr  gpp)
00366 {
00367   float      sal = 0.f;
00368   edge_2d_list  fedges = this->GetFittedEdges();
00369 
00370 #ifdef DEBUG
00371   vcl_cout << "ifac::compute_parallel_sal(): " << fedges.size()
00372            << " edges found\n";
00373 #endif
00374 
00375   if (fedges.size())
00376   {
00377 #ifdef DEBUG
00378     vcl_cout << (*fitter_params_);
00379 #endif
00380 
00381     float    total_len = 0.f;
00382     int      nlines = 0;
00383     imp_line_list    lg_filtered;
00384     for (edge_2d_iterator ei = fedges.begin(); ei != fedges.end(); ++ei)
00385     {
00386       vsol_curve_2d_sptr  cur = (*ei)->curve();
00387       float        len = float(cur->length());
00388       total_len += len;
00389 
00390       if (len >= fitter_params_->min_fit_length_)
00391       {
00392         const vgl_point_2d<double>&  p1 = cur->p0()->get_p();
00393         const vgl_point_2d<double>&  p2 = cur->p1()->get_p();
00394         imp_line_sptr        filt_line  = new imp_line(p1, p2);
00395 
00396         lg_filtered.push_back(filt_line);
00397         nlines++;
00398       }
00399     }
00400 
00401 #ifdef DEBUG
00402     vcl_cout << "ifac::compute_parallel_sal(): " << nlines
00403              << " lines after filtering, total_len = " << total_len << vcl_endl;
00404 #endif
00405 
00406     // compute the score for the set of fitted lines
00407     if (nlines > 2)
00408     {
00409       // Insert the lines into the parallelogram orientation index
00410       vifa_group_pgram  gp(lg_filtered, *gpp);
00411       gp.SetTemp1(total_len);
00412 
00413       // Get the resultant value
00414       sal = float(gp.norm_parallel_line_length());
00415     }
00416   }
00417 
00418   return sal;
00419 }

Generated on Thu Jan 10 14:47:30 2008 for contrib/gel/vifa by  doxygen 1.4.4