00001
00002 #include "vifa_int_faces_adj_attr.h"
00003
00004 vifa_int_faces_adj_attr::
00005 vifa_int_faces_adj_attr(void)
00006 : vifa_int_faces_attr(),
00007 closure_valid_(false),
00008 seed_(NULL),
00009 seed_attr_(NULL),
00010 depth_(BAD_DEPTH)
00011 {
00012 init();
00013 ComputeAttributes();
00014 }
00015
00016 vifa_int_faces_adj_attr::
00017 vifa_int_faces_adj_attr(vtol_intensity_face_sptr seed,
00018 int depth,
00019 int size_filter,
00020 vdgl_fit_lines_params* fitter_params,
00021 vifa_group_pgram_params* gpp_s,
00022 vifa_group_pgram_params* gpp_w,
00023 vifa_coll_lines_params* cpp,
00024 vifa_norm_params* np,
00025 vifa_int_face_attr_factory* factory,
00026 float junk_area_percentage)
00027 : vifa_int_faces_attr(fitter_params, gpp_s, gpp_w, cpp, np, factory),
00028 closure_valid_(false),
00029 seed_(seed),
00030 seed_attr_(NULL),
00031 depth_(depth),
00032 size_filter_(size_filter),
00033 junk_area_percentage_(junk_area_percentage),
00034 junk_count_(0)
00035 {
00036 init();
00037 ComputeAttributes();
00038 }
00039
00040 vifa_int_faces_adj_attr::
00041 vifa_int_faces_adj_attr(vtol_intensity_face_sptr seed,
00042 int depth,
00043 iface_list& neighborhood,
00044 int size_filter,
00045 vdgl_fit_lines_params* fitter_params,
00046 vifa_group_pgram_params* gpp_s,
00047 vifa_group_pgram_params* gpp_w,
00048 vifa_coll_lines_params* cpp,
00049 vifa_norm_params* np,
00050 vifa_int_face_attr_factory* factory,
00051 float junk_area_percentage)
00052 : vifa_int_faces_attr(neighborhood, fitter_params, gpp_s, gpp_w, cpp, np, factory),
00053 closure_valid_(false),
00054 seed_(seed),
00055 seed_attr_(NULL),
00056 depth_(depth),
00057 size_filter_(size_filter),
00058 junk_area_percentage_(junk_area_percentage),
00059 junk_count_(0)
00060 {
00061 init();
00062 ComputeAttributes();
00063 }
00064
00065 void vifa_int_faces_adj_attr::
00066 SetSeed(vtol_intensity_face_sptr seed)
00067 {
00068 seed_ = seed;
00069 closure_valid_ = false;
00070 seed_attr_ = factory_new_attr(seed_);
00071 }
00072
00073 iface_list& vifa_int_faces_adj_attr::
00074 GetFaces()
00075 {
00076 if (!closure_valid_)
00077 {
00078 faces_.clear();
00079 this->compute_closure();
00080 }
00081
00082 return faces_;
00083 }
00084
00085
00086 iface_list* vifa_int_faces_adj_attr::
00087 GetFaceList()
00088 {
00089 if (!closure_valid_)
00090 {
00091 faces_.clear();
00092 this->compute_closure();
00093 }
00094
00095 iface_list* v = new iface_list;
00096 for (iface_iterator f = faces_.begin(); f != faces_.end(); ++f)
00097 {
00098 v->push_back(*f);
00099 }
00100
00101 return v;
00102 }
00103
00104 bool vifa_int_faces_adj_attr::
00105 ComputeAttributes()
00106 {
00107 if (!closure_valid_)
00108 this->compute_closure();
00109
00110 if (vifa_int_faces_attr::ComputeAttributes())
00111 {
00112
00113 seed_attr_ = factory_new_attr(seed_);
00114 vifa_int_face_attr* seed_attr_ptr = seed_attr_.ptr();
00115
00116
00117 for (int i = 0; i < this->NumHistAttributes(); i++)
00118 {
00119 float seed_val = (seed_attr_ptr->*(attr_get_funcs[i]))();
00120
00121
00122
00123 float hist_mean = GetMeanAttr(i);
00124 if (hist_mean < attr_min_vals[i])
00125 hist_mean = attr_min_vals[i];
00126 mean_ratios_[i] = (seed_val + 1) / (hist_mean + 1);
00127
00128 float hist_min = GetMinAttr(i);
00129 if (hist_min < attr_min_vals[i])
00130 hist_min = attr_min_vals[i];
00131 min_ratios_[i] = (seed_val + 1) / (hist_min + 1);
00132 }
00133
00134 attributes_valid_ = true;
00135 }
00136
00137 return valid_p();
00138 }
00139
00140 int vifa_int_faces_adj_attr::
00141 NeighborhoodSize()
00142 {
00143 compute_closure();
00144 return faces_.size();
00145 }
00146
00147
00148 bool vifa_int_faces_adj_attr::
00149 GetAttributes(vcl_vector<float>& attrs)
00150 {
00151 if (vifa_int_faces_attr::GetAttributes(attrs))
00152 return this->vifa_int_faces_adj_attr::GetNativeAttributes(attrs);
00153 else
00154 return false;
00155 }
00156
00157
00158
00159 void vifa_int_faces_adj_attr::
00160 GetAttributeNames(vcl_vector<vcl_string>& names)
00161 {
00162 vifa_int_faces_attr::GetAttributeNames(names);
00163
00164 for (int i = 0; i < NUM_HIST_ATTRIBUTES; i++)
00165 {
00166 vcl_string name(attr_names[i]);
00167 names.push_back("ratio" + name);
00168 }
00169
00170 for (int i = 0; i < NUM_HIST_ATTRIBUTES; i++)
00171 {
00172 vcl_string name(attr_names[i]);
00173 names.push_back("minRatio" + name);
00174 }
00175 }
00176
00177
00178
00179
00180 bool vifa_int_faces_adj_attr::
00181 GetNativeAttributes(vcl_vector<float>& attrs)
00182 {
00183 if (!this->ComputeAttributes())
00184 {
00185 vcl_cerr << "Couldn't compute group adj attributes?\n";
00186 return false;
00187 }
00188
00189 for (int i = 0; i < this->NumHistAttributes(); i++)
00190 {
00191 attrs.push_back(this->GetRatioAttr(i));
00192 }
00193
00194 for (int i = 0; i < this->NumHistAttributes(); i++)
00195 {
00196 attrs.push_back(this->GetMinRatioAttr(i));
00197 }
00198
00199
00200
00201 return true;
00202 }
00203
00204 bool vifa_int_faces_adj_attr::
00205 compute_closure()
00206 {
00207
00208
00209 if (!closure_valid_)
00210 {
00211 if (faces_.empty())
00212 {
00213
00214
00215 if ((seed_) && (depth_ != BAD_DEPTH))
00216 {
00217
00218
00219 faces_.push_back(seed_);
00220
00221
00222 this->compute_closure_step(0, seed_);
00223
00224
00225 faces_.erase(faces_.begin());
00226 }
00227 }
00228
00229
00230
00231 float original_area = 0;
00232 float junk_area = 0;
00233 int original_nbrhood_size = faces_.size();
00234 float area_threshold = (seed_->Npix() * junk_area_percentage_);
00235 iface_list keep_faces;
00236 for (iface_iterator f = faces_.begin(); f != faces_.end(); ++f)
00237 {
00238 original_area += (*f)->Npix();
00239
00240 if ((*f)->Npix() >= area_threshold)
00241 keep_faces.push_back(*f);
00242 else
00243 {
00244 junk_count_++;
00245 junk_area += (*f)->Npix();
00246 }
00247 }
00248
00249
00250
00251 faces_ = keep_faces;
00252 junk_percent_ = (float)junk_count_ / original_nbrhood_size;
00253 junk_area_ratio_ = junk_area / original_area;
00254 closure_valid_ = true;
00255 }
00256
00257 #if 0
00258 vcl_cout << "Final faces_: " << faces_.size() << vcl_endl;
00259
00260 for (iface_iterator f = faces_.begin(); f != faces_.end(); ++f)
00261 vcl_cout << " (" << (*f)->Xo() << ", " << (*f)->Yo() << "), "
00262 << (*f)->Npix() << " pixels\n";
00263 #endif
00264
00265
00266
00267 return closure_valid_;
00268 }
00269
00270 float vifa_int_faces_adj_attr::
00271 Collinearity()
00272 {
00273 compute_closure();
00274 get_collinear_lines();
00275
00276 float u_len = 0.0f;
00277 float w_len = 0.0f;
00278 float coll = 0.0f;
00279 edge_list edges; seed_->edges(edges);
00280
00281 for (edge_iterator ei = edges.begin(); ei != edges.end(); ei++)
00282 {
00283 vtol_edge_2d* e = (*ei)->cast_to_edge_2d();
00284
00285 if (e)
00286 {
00287 vifa_coll_lines_sptr clr = get_line_along_edge(e);
00288
00289 if (clr)
00290 {
00291 u_len += float(e->curve()->length());
00292 w_len += float(clr->spanning_length());
00293 }
00294 }
00295 }
00296
00297 if (u_len > 0.0f)
00298 coll = w_len / u_len;
00299
00300 return coll;
00301 }
00302
00303
00304 float vifa_int_faces_adj_attr::
00305 GetRatioAttr(int attr_index)
00306 {
00307 return mean_ratios_[attr_index];
00308 }
00309
00310
00311 float vifa_int_faces_adj_attr::
00312 GetMinRatioAttr(int attr_index)
00313 {
00314 return min_ratios_[attr_index];
00315 }
00316
00317 void vifa_int_faces_adj_attr::
00318 init()
00319 {
00320 junk_percent_ = 0.0f;
00321 junk_area_ratio_ = 0.0f;
00322
00323 int n = NumHistAttributes();
00324 mean_ratios_.reserve(n);
00325 min_ratios_.reserve(n);
00326
00327
00328 for (int i = 0; i < n; i++)
00329 mean_ratios_[i] = min_ratios_[i] = -1;
00330 }
00331
00332 bool vifa_int_faces_adj_attr::
00333 add_unique_face(iface_list& facelist,
00334 vtol_intensity_face_sptr face,
00335 int size_filter)
00336 {
00337 for (iface_iterator check = facelist.begin();
00338 check != facelist.end(); ++check)
00339 {
00340 if ((check->ptr()->Xo() == face->Xo()) &&
00341 (check->ptr()->Yo() == face->Yo()))
00342 return false;
00343 }
00344
00345 if (face->Npix() >= size_filter)
00346 {
00347 facelist.push_back(face);
00348 return true;
00349 }
00350
00351 return false;
00352 }
00353
00354 void vifa_int_faces_adj_attr::
00355 compute_closure_step(int current_depth,
00356 vtol_intensity_face_sptr seed)
00357 {
00358 #ifdef CCS_DEBUG
00359 vcl_cout << "ccs: depth " << current_depth << " of " << depth_;
00360
00361 if (seed)
00362 vcl_cout << " at seed " << seed->Xo() << ", " << seed->Yo();
00363 else
00364 vcl_cout << " with null seed";
00365 #endif
00366
00367 if ((current_depth >= depth_) || (!seed))
00368 {
00369 #ifdef CCS_DEBUG
00370 vcl_cout << "...bailing\n";
00371 #endif
00372 return;
00373 }
00374 #ifdef CCS_DEBUG
00375 else
00376 vcl_cout << vcl_endl;
00377 #endif
00378
00379
00380 iface_list* adj_faces = get_adjacent_faces(seed);
00381 if (adj_faces)
00382 {
00383
00384 iface_iterator fi = adj_faces->begin();
00385 for (; fi != adj_faces->end(); fi++)
00386 {
00387 vtol_intensity_face_sptr adj_face_sptr = (*fi);
00388
00389
00390 if (this->add_unique_face(faces_, adj_face_sptr, size_filter_))
00391 {
00392
00393 this->compute_closure_step(current_depth + 1, adj_face_sptr);
00394 }
00395 }
00396
00397 delete adj_faces;
00398 }
00399 else
00400 vcl_cerr << "vifsaa::compute_closure_step(): No adj. faces found!\n";
00401 }
00402
00403 vtol_intensity_face_sptr vifa_int_faces_adj_attr::
00404 get_adjacent_face_at_edge(vtol_intensity_face_sptr& known_face,
00405 vtol_edge_2d* e)
00406 {
00407 vtol_intensity_face_sptr adj_face = 0;
00408 face_list faces; e->faces(faces);
00409
00410
00411 if (faces.size() == 2)
00412 {
00413 vtol_intensity_face* f1 = faces[0]->cast_to_intensity_face();
00414 vtol_intensity_face* f2 = faces[1]->cast_to_intensity_face();
00415
00416 if (f1 && f2 && *known_face == *f1)
00417 adj_face = f2;
00418 else if (f1 && f2 && *known_face == *f2)
00419 adj_face = f1;
00420 else
00421 {
00422
00423
00424 }
00425 }
00426
00427 return adj_face;
00428 }
00429
00430 iface_list* vifa_int_faces_adj_attr::
00431 get_adjacent_faces(vtol_intensity_face_sptr& known_face)
00432 {
00433 iface_list* faces = NULL;
00434
00435 if (known_face.ptr())
00436 {
00437 edge_list edges; known_face->edges(edges);
00438 faces = new iface_list;
00439
00440 for (edge_iterator ei = edges.begin(); ei != edges.end(); ei++)
00441 {
00442 vtol_edge_2d* e = (*ei)->cast_to_edge_2d();
00443 if (e)
00444 {
00445 vtol_intensity_face_sptr other_f =
00446 this->get_adjacent_face_at_edge(known_face, e);
00447
00448 if (other_f.ptr())
00449 this->add_unique_face(*faces, other_f, 0);
00450 }
00451 }
00452 }
00453
00454 return faces;
00455 }