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