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

vifa_int_faces_attr.cxx

Go to the documentation of this file.
00001 // This is gel/vifa/vifa_int_faces_attr.cxx
00002 #include <vcl_algorithm.h>
00003 #include <vcl_cmath.h>
00004 #include <vcl_map.h>
00005 #include <vcl_utility.h>
00006 #include <vtol/vtol_edge.h>
00007 #include <vifa/vifa_incr_var.h>
00008 #include <vifa/vifa_int_faces_attr.h>
00009 #include <vifa/vifa_parallel.h>
00010 
00011 
00012 // Establish the attribute vector for histogrammed attributes.  These
00013 // are vifa_int_face_attr methods to get an attribute val for one face.  Each
00014 // attribute type is histogrammed in this class.  Length must be
00015 // NUM_HIST_ATTRIBUTES.
00016 AttrFuncPtr vifa_int_faces_attr::
00017 attr_get_funcs[] =
00018 {
00019   &vifa_int_face_attr::IntMax,    // region intensity maxima
00020   &vifa_int_face_attr::IntMin,    // region intensity minima
00021   &vifa_int_face_attr::IntMean,    // region intensities
00022   &vifa_int_face_attr::IntVar,    // region intensity variances
00023   &vifa_int_face_attr::Area,      // region area
00024   &vifa_int_face_attr::AspectRatio,
00025   &vifa_int_face_attr::PerimeterLength,
00026   &vifa_int_face_attr::WeightedPerimeterLength,
00027   &vifa_int_face_attr::Complexity,
00028   &vifa_int_face_attr::WeightedComplexity,
00029   &vifa_int_face_attr_common::StrongParallelSal,
00030   &vifa_int_face_attr_common::WeakParallelSal,
00031   &vifa_int_face_attr::TwoPeakParallel,
00032   &vifa_int_face_attr::FourPeakParallel,
00033   &vifa_int_face_attr::EightyPercentParallel
00034 };
00035 
00036 const char* const vifa_int_faces_attr::
00037 attr_names[] =
00038 {
00039   "IntMax",
00040   "IntMin",
00041   "IntMean",
00042   "IntVar",
00043   "Area",
00044   "AspectRatio",
00045   "PerimeterLength",
00046   "WeightedPerimeterLength",
00047   "Complexity",
00048   "WeightedComplexity",
00049   "StrongParallel",
00050   "WeakParallel",
00051   "TwoPeakParallel",
00052   "FourPeakParallel",
00053   "EightyPercentParallel"
00054 };
00055 
00056 // Set some minimumm values
00057 
00058 float vifa_int_faces_attr::
00059 attr_min_vals[] = {
00060   0.0039f,      // 1/255
00061   0.0039f,
00062   0.0039f,
00063   0.0001f,      //... not sure what the minimum variance should be
00064   1.0f,         // min area
00065   1.0f,         // min aspect ratio
00066   1.0f,         // min perimeter
00067   1.0f,         // min weighted perimeter
00068   1.0f,         // min complexity
00069   1.0f,         // min weighted complexity
00070   0.05f,        // min strong parallel
00071   0.05f,        // min weak parallel
00072   1e-5f,
00073   1e-5f,
00074   1e-5f
00075 };
00076 
00077 void vifa_int_faces_attr::
00078 init()
00079 {
00080   centroid_.reserve(2);
00081   centroid_[0] = -1;
00082   centroid_[1] = -1;
00083   perimeter_ = -1;
00084   weighted_perimeter_ = -1;
00085   // attr_map_ is allocated in ComputeSingleFaceAttributes.
00086 
00087   cached_2_parallel_ = -1;
00088   cached_4_parallel_ = -1;
00089   cached_80_parallel_ = -1;
00090 
00091   npobj_ = 0;
00092 
00093   attr_vec_.reserve(NumHistAttributes());
00094   for (int i=0; i < NumHistAttributes(); i++)
00095   {
00096     // can't do it below; garbage values trap in unref
00097     attr_vec_.push_back(NULL);
00098   }
00099 
00100   perimeter_ = -1.f;
00101 }
00102 
00103 vifa_int_faces_attr::
00104 vifa_int_faces_attr(vdgl_fit_lines_params*    fitter_params,
00105                     vifa_group_pgram_params*  gpp_s,
00106                     vifa_group_pgram_params*  gpp_w,
00107                     vifa_coll_lines_params*    cpp,
00108                     vifa_norm_params*      np,
00109                     vifa_int_face_attr_factory*  factory)
00110   : vifa_int_face_attr_common(fitter_params, gpp_s, gpp_w, cpp, np)
00111 {
00112   this->init();
00113   factory_ = factory;
00114 }
00115 
00116 vifa_int_faces_attr::
00117 vifa_int_faces_attr(iface_list&          v,
00118                     vdgl_fit_lines_params*      fitter_params,
00119                     vifa_group_pgram_params*    gpp_s,
00120                     vifa_group_pgram_params*    gpp_w,
00121                     vifa_coll_lines_params*     cpp,
00122                     vifa_norm_params*           np,
00123                     vifa_int_face_attr_factory* factory)
00124   : vifa_int_face_attr_common(fitter_params, gpp_s, gpp_w, cpp, np),
00125     faces_(v)
00126 {
00127   this->init();
00128   factory_ = factory;
00129   attributes_valid_ = this->ComputeAttributes();
00130 }
00131 
00132 vifa_int_faces_attr::
00133 ~vifa_int_faces_attr()
00134 {
00135   delete npobj_;
00136 }
00137 
00138 // ----------------------------------------------------------------
00139 // Data access for non-attributes
00140 // ---
00141 
00142 
00143 float vifa_int_faces_attr::
00144 CallAttrFunction(vifa_int_face_attr* seed_attr,int i)
00145 {
00146   return (seed_attr->*(attr_get_funcs[i]))();
00147 }
00148 
00149 void vifa_int_faces_attr::
00150 SetFaces(iface_list& v)
00151 {
00152   // Save the new faces
00153   faces_ = v;
00154 
00155   // Reset everything
00156   delete npobj_;
00157   this->init();
00158 
00159   // Recompute the attributes
00160   attributes_valid_ = this->ComputeAttributes();
00161 }
00162 
00163 edge_2d_list& vifa_int_faces_attr::
00164 GetEdges()
00165 {
00166   // don't compute again if already there
00167   if (!edges_.empty())
00168     return edges_;
00169 
00170   if (faces_.empty())
00171   {
00172     vcl_cerr << "vifa_int_faces_attr::GetEdges: faces_ is not set\n";
00173     return edges_;
00174   }
00175 
00176   // Get edges from all faces, remove duplicates
00177   for (iface_iterator f = faces_.begin(); f != faces_.end(); ++f)
00178   {
00179     edge_list fedges; (*f)->edges(fedges);
00180     edge_2d_iterator  edges_pos_;
00181     for (edge_iterator ei = fedges.begin(); ei != fedges.end(); ei++)
00182     {
00183       vtol_edge_2d*  e_ptr = (*ei)->cast_to_edge_2d();
00184 
00185       if (e_ptr)
00186       {
00187         vtol_edge_2d_sptr  e = vtol_edge_2d_sptr(e_ptr);
00188 
00189         edges_pos_ = vcl_find(edges_.begin(), edges_.end(), e);
00190         if (edges_pos_ == edges_.end())
00191           edges_.push_back(e);
00192       }
00193     }
00194   }
00195 
00196   return edges_;
00197 }
00198 
00199 
00200 // Compute centroid as the area-weighted mean of face centroids
00201 // (center of mass).
00202 void vifa_int_faces_attr::
00203 ComputeCentroid()
00204 {
00205   if ((centroid_[0] < 0) && !attr_map_.empty())
00206   {
00207     float  area_sum = 0;
00208     float  x_area_sum = 0;
00209     float  y_area_sum = 0;
00210 
00211     for (attr_iterator ai = attr_map_.begin();
00212          ai != attr_map_.end(); ++ai)
00213     {
00214       float  area = (*ai)->Area();
00215       area_sum += area;
00216       x_area_sum += area * (*ai)->Xo();
00217       y_area_sum += area * (*ai)->Yo();
00218     }
00219 
00220     if (!area_sum)
00221       return;
00222 
00223     centroid_[0] = x_area_sum / area_sum;
00224     centroid_[1] = y_area_sum / area_sum;
00225   }
00226 }
00227 
00228 // Compute X coord of centroid of all regions
00229 float vifa_int_faces_attr::
00230 Xo()
00231 {
00232   if ((centroid_[0] < 0) && !attr_map_.empty())
00233     this->ComputeCentroid();
00234 
00235   return centroid_[0];
00236 }
00237 
00238 // Compute Y coord of centroid of all regions
00239 float vifa_int_faces_attr::
00240 Yo()
00241 {
00242   if ((centroid_[1] < 0) && !attr_map_.empty())
00243     this->ComputeCentroid();
00244 
00245   return centroid_[1];
00246 }
00247 
00248 // ------------------------------------------------------------
00249 // Attribute computation
00250 //
00251 
00252 // Compute single-face attributes (vifa_int_face_attr objects) for each
00253 // individual face.
00254 bool vifa_int_faces_attr::
00255 ComputeSingleFaceAttributes(bool forceP)
00256 {
00257   if (!forceP && attributes_valid_)
00258     return true;
00259 
00260   attr_map_.clear();
00261   for (iface_iterator f = faces_.begin(); f != faces_.end(); ++f)
00262   {
00263     vifa_int_face_attr_sptr fattr = factory_new_attr(*f);
00264 
00265     if (!(fattr->valid_p()))
00266       return false;
00267 
00268     attr_map_.push_back(fattr);
00269   }
00270 
00271   return true;
00272 }
00273 
00274 bool vifa_int_faces_attr::
00275 ComputeAttributes()
00276 {
00277   if (!this->ComputeSingleFaceAttributes(true))
00278     attributes_valid_ = false;
00279   else
00280   {
00281     // Compute histogrammed attributes, including generation of
00282     // histograms
00283     for (int i = 0; i < NumHistAttributes(); i++)
00284       this->GetMeanAttr(i);
00285 
00286     attributes_valid_ = true;
00287   }
00288 
00289   return valid_p();
00290 }
00291 
00292 // Populate a vector containing all attributes, including inherited ones.
00293 bool vifa_int_faces_attr::
00294 GetAttributes(vcl_vector<float>& attrs)
00295 {
00296   // No inherited attributes. The class qualifier is necessary to
00297   // prevent this call from going to children that define this method
00298   // also.
00299   return this->vifa_int_faces_attr::GetNativeAttributes(attrs);
00300 }
00301 
00302 // Populate a vector containing attributes native to this class (not
00303 // inherited).
00304 bool vifa_int_faces_attr::
00305 GetNativeAttributes(vcl_vector<float>& attrs)
00306 {
00307   if (!this->ComputeAttributes())
00308   {
00309     vcl_cerr << "Couldn't compute group attributes?\n";
00310     return false;
00311   }
00312 
00313   attrs.push_back(this->Area());
00314   attrs.push_back(this->PerimeterLength());
00315   attrs.push_back(this->WeightedPerimeterLength());
00316   attrs.push_back(this->Complexity());
00317   attrs.push_back(this->WeightedComplexity());
00318   attrs.push_back(this->StrongParallelSal());
00319   attrs.push_back(this->WeakParallelSal());
00320   attrs.push_back(this->TwoPeakParallel());
00321   attrs.push_back(this->FourPeakParallel());
00322   attrs.push_back(this->EightyPercentParallel());
00323 
00324   for (int i = 0; i < this->NumHistAttributes(); i++)
00325     attrs.push_back(this->GetMeanAttr(i));
00326 
00327   for (int i = 0; i < this->NumHistAttributes(); i++)
00328     attrs.push_back(this->GetSDAttr(i));
00329 
00330   return true;
00331 }
00332 
00333 // KEEP IN SYNC WITH GETNATIVEATTRIBUTES
00334 
00335 void vifa_int_faces_attr::
00336 GetAttributeNames(vcl_vector<vcl_string>& names)
00337 {
00338   names.push_back("gArea");
00339   names.push_back("gPerimeterLength");
00340   names.push_back("gWeightedPerimeterLength");
00341   names.push_back("gComplexity");
00342   names.push_back("gWeightedComplexity");
00343   names.push_back("gStrongParallel");
00344   names.push_back("gWeakParallel");
00345   names.push_back("gTwoPeakParallel");
00346   names.push_back("gFourPeakParallel");
00347   names.push_back("gEightyPercentParallel");
00348 
00349   for (int i = 0; i < NUM_HIST_ATTRIBUTES; i++)
00350   {
00351     vcl_string  name(attr_names[i]);
00352     names.push_back("mean" + name);
00353   }
00354 
00355   for (int i = 0; i < NUM_HIST_ATTRIBUTES; i++)
00356   {
00357     vcl_string  name(attr_names[i]);
00358     names.push_back("sd" + name);
00359   }
00360 }
00361 
00362 const char* vifa_int_faces_attr::
00363 GetBaseAttrName(int i)
00364 {
00365   return vifa_int_faces_attr::attr_names[i];
00366 }
00367 
00368 
00369 // Create a histogram of attribute values from the supplied list of
00370 // values.  This histogram must be deleted by the caller when done!
00371 vifa_histogram_sptr vifa_int_faces_attr::
00372 MakeAttrHist(vcl_vector<float>& attr_vals)
00373 {
00374   this->ComputeSingleFaceAttributes(false);
00375 
00376   // Set the number of bins as sqrt(n), with a minimum of 20
00377   int    num_bins = vcl_max(20, (int)vcl_sqrt( static_cast<float>(attr_vals.size()) ));
00378 
00379   // Get value range
00380   float  max_val = 0;
00381   float  min_val = 1000000;
00382   for (vcl_vector<float>::iterator vali = attr_vals.begin();
00383        vali != attr_vals.end(); ++vali)
00384   {
00385     float val = *vali;
00386 
00387     if (val > max_val)
00388       max_val = val;
00389 
00390     if (val < min_val)
00391       min_val = val;
00392   }
00393 
00394   // Create empty histogram
00395   vifa_histogram_sptr val_hist = new vifa_histogram(num_bins,
00396                                                     min_val,
00397                                                     max_val);
00398 
00399   // Populate histogram
00400   for (vcl_vector<float>::iterator vali = attr_vals.begin();
00401        vali != attr_vals.end(); ++vali)
00402     val_hist->UpCount(*vali);
00403 
00404   return val_hist;
00405 }
00406 
00407 // Get or compute mean value of an vifa_int_face_attr attribute.  Computes
00408 // histogram if necessary.  Not weighted by area.
00409 float vifa_int_faces_attr::
00410 GetMeanAttr(int attr_index)
00411 {
00412   if (!attr_map_.empty())
00413   {
00414     if (!(attr_vec_[attr_index].ptr()))
00415     {
00416       attr_vec_[attr_index] = new vifa_incr_var;
00417 
00418       // Create list of attr vals and attr histogram
00419       vcl_vector<float>  vals(attr_map_.size());
00420       int          index = 0;
00421       for (attr_iterator ai = attr_map_.begin();
00422            ai != attr_map_.end(); ++ai, ++index)
00423       {
00424         vifa_int_face_attr_sptr  attr_ptr = *ai;
00425         vals[index] = CallAttrFunction(attr_ptr.ptr(), attr_index);
00426         attr_vec_[attr_index]->add_sample(vals[index]);
00427       }
00428     }
00429 
00430     return float(attr_vec_[attr_index]->get_mean());
00431   }
00432   else
00433   {
00434     // If no faces in neighborhood...
00435     return -1.f;
00436   }
00437 }
00438 
00439 // Get or compute standard deviation of an vifa_int_face_attr attribute.
00440 // Computes histogram if necessary.  Not weighted by area.
00441 float vifa_int_faces_attr::
00442 GetSDAttr(int attr_index)
00443 {
00444   if (!attr_map_.empty())
00445   {
00446     if (!attr_vec_[attr_index].ptr())
00447     {
00448       // Create attr histogram by side effect
00449       this->GetMeanAttr(attr_index);
00450     }
00451 
00452     return (float)vcl_sqrt(attr_vec_[attr_index]->get_var());
00453   }
00454   else
00455   {
00456     // If there are no faces in neighborhood...
00457     return -1;
00458   }
00459 }
00460 
00461 // Get or compute min value of an vifa_int_face_attr attribute.
00462 // Computes histogram if necessary.  Not weighted by area.
00463 float vifa_int_faces_attr::
00464 GetMinAttr(int attr_index)
00465 {
00466   if (!attr_map_.empty())
00467   {
00468     if (!attr_vec_[attr_index].ptr())
00469     {
00470       // Create attr histogram by side effect
00471       this->GetMeanAttr(attr_index);
00472     }
00473 
00474     return float(attr_vec_[attr_index]->get_min());
00475   }
00476   else
00477     return -1.f;
00478 }
00479 
00480 // Get or compute max value of an vifa_int_face_attr attribute.
00481 // Computes histogram if necessary.  Not weighted by area.
00482 float vifa_int_faces_attr::
00483 GetMaxAttr(int attr_index)
00484 {
00485   if (!attr_map_.empty())
00486   {
00487     if (!attr_vec_[attr_index].ptr())
00488     {
00489       // Create attr histogram by side effect
00490       this->GetMeanAttr(attr_index);
00491     }
00492 
00493     return float(attr_vec_[attr_index]->get_max());
00494   }
00495   else
00496     return -1.f;
00497 }
00498 
00499 // ---------------------------------------------------------------------
00500 // Non-histogrammed attributes.  One value per vifa_int_faces_attr.
00501 
00502 // area of all faces
00503 float vifa_int_faces_attr::
00504 Area()
00505 {
00506   if (!attr_map_.empty())
00507   {
00508     area_ = 0;
00509     for (attr_iterator ai = attr_map_.begin(); ai != attr_map_.end(); ++ai)
00510       area_ += (*ai)->Area();
00511 
00512     return area_;
00513   }
00514   else
00515     return 0.f;
00516 }
00517 
00518 // ratio of major moments of union of all faces
00519 float vifa_int_faces_attr::
00520 AspectRatio()
00521 {
00522   return 0.f;
00523 }
00524 
00525 // a helper function
00526 edge_list* vifa_int_faces_attr::
00527 GetPerimeterEdges()
00528 {
00529   edge_list*  p_edges = new edge_list;
00530 
00531   if (faces_.empty())
00532   {
00533     vcl_cerr << "no faces to calculate perimeter!\n";
00534     return p_edges;
00535   }
00536 
00537   // Maps edgeID to # of appearances
00538   vcl_map<int, int>      edge_count;
00539   vcl_map<int, int>::iterator  edge_count_pos;
00540 
00541   int  edge_index = 0;
00542   for (iface_iterator f = faces_.begin(); f != faces_.end(); ++f)
00543   {
00544     edge_list edges; (*f)->edges(edges);
00545 
00546     for (edge_iterator ei = edges.begin(); ei != edges.end(); ei++)
00547     {
00548       vtol_edge_sptr  e = *ei;
00549       int        e_id = e->get_id();
00550 
00551       if (e_id == 0)
00552       {
00553         e_id = ++edge_index;
00554         e->set_id(e_id);
00555       }
00556 
00557       int  count;
00558       edge_count_pos = edge_count.find(e_id);
00559       if (edge_count_pos == edge_count.end())
00560         count = 1;
00561       else
00562         count = edge_count_pos->second + 1;
00563 
00564       edge_count.insert(vcl_pair<int, int>(e_id, count));
00565     }
00566   }
00567 
00568   int  unique_count = 0;
00569   for (iface_iterator f = faces_.begin(); f != faces_.end(); ++f)
00570   {
00571     edge_list edges; (*f)->edges(edges);
00572     for (edge_iterator ei = edges.begin(); ei != edges.end(); ei++)
00573     {
00574       vtol_edge_sptr  e = *ei;
00575       int        count;
00576 
00577       edge_count_pos = edge_count.find(e->get_id());
00578       if (edge_count_pos == edge_count.end())
00579       {
00580         vcl_cerr << "Inconsistency in vifa_int_faces_attr::perimeter()?\n";
00581         continue;
00582       }
00583       else
00584         count = edge_count_pos->second;
00585 
00586       if (count == 1)
00587       {
00588         unique_count++;
00589         p_edges->push_back(e);
00590       }
00591     }
00592   }
00593 
00594   return p_edges;
00595 }
00596 
00597 
00598 // length of boundary of face group, in pixels.  Includes hole boundaries.
00599 float vifa_int_faces_attr::
00600 PerimeterLength()
00601 {
00602   if (perimeter_ >= 0)
00603   {
00604     // Wary of "if ... == -1.0f"
00605     return perimeter_;
00606   }
00607 
00608   perimeter_ = 0;
00609 
00610   edge_list*  p_edges = this->GetPerimeterEdges();
00611   if (p_edges)
00612   {
00613     for (edge_iterator eit = p_edges->begin(); eit != p_edges->end(); ++eit)
00614     {
00615       vtol_edge_2d*  e = (*eit)->cast_to_edge_2d();
00616 
00617       if (e)
00618         perimeter_ += float(e->curve()->length());
00619     }
00620 
00621     delete p_edges;
00622   }
00623 
00624   return perimeter_;
00625 }
00626 
00627 float vifa_int_faces_attr::
00628 WeightedPerimeterLength()
00629 {
00630   if (weighted_perimeter_ >= 0)
00631     return weighted_perimeter_;
00632 
00633 //  vcl_cout << "In vifsa::WeightedPerimeterSum()...\n";
00634 
00635   weighted_perimeter_ = 0;
00636 
00637   edge_list*  p_edges = this->GetPerimeterEdges();
00638   if (p_edges)
00639   {
00640     // uh-oh, we've lost the face information for defining
00641     // "the other face"...
00642 
00643     float  weighted_perimeter_sum = 0;
00644     float  contrast_sum = 0;
00645     for (edge_iterator eit = p_edges->begin(); eit != p_edges->end(); ++eit)
00646     {
00647       vtol_edge_2d*  e = (*eit)->cast_to_edge_2d();
00648 
00649       if (e)
00650       {
00651         face_list edge_faces; e->faces(edge_faces);
00652         iface_list  in_faces;
00653         iface_list  out_faces;
00654 
00655 //        vcl_cout << edge_faces->size() << " faces found" << endl;
00656 
00657         for (face_iterator fi=edge_faces.begin(); fi != edge_faces.end(); ++fi)
00658         {
00659           vtol_intensity_face*  int_f = (*fi)->cast_to_intensity_face();
00660 
00661           if (!int_f)
00662           {
00663             vcl_cerr << "vifa_int_faces_attr::WeightedPerimeterLength() -"
00664                      << " Face is not an intensity face\n";
00665             continue;
00666           }
00667 
00668           bool in_face = false;
00669           for (iface_iterator f = faces_.begin(); f != faces_.end(); ++f)
00670           {
00671             if (**f == *int_f)
00672             {
00673               in_face = true;
00674               in_faces.push_back(int_f);
00675               break;
00676             }
00677           }
00678 
00679           if (!in_face)
00680             out_faces.push_back(int_f);
00681         }
00682 
00683 //        vcl_cout << in_faces.size() << " in_faces, " << out_faces.size()
00684 //                 << " out_faces\n";
00685 
00686         //  this might emphasize large, high-gradient faces too much...
00687 
00688         float  i_intensity_sum = 0;
00689         float  i_area_sum = 0;
00690         for (iface_iterator f = in_faces.begin(); f != in_faces.end(); ++f)
00691         {
00692           i_intensity_sum += ((*f)->Io() * (*f)->Npix());
00693           i_area_sum += (*f)->Npix();
00694         }
00695 
00696 //        vcl_cout << "i_intensity_sum = " << i_intensity_sum
00697 //                 << ", i_area_sum = " << i_area_sum << vcl_endl;
00698 
00699         float  i_intensity = (i_area_sum > 0) ?  i_intensity_sum / i_area_sum : 0.f;
00700 
00701         float  o_intensity_sum = 0;
00702         float  o_area_sum = 0;
00703         for (iface_iterator f = out_faces.begin();
00704              f != out_faces.end(); ++f)
00705         {
00706           o_intensity_sum += ((*f)->Io() * (*f)->Npix());
00707           o_area_sum += (*f)->Npix();
00708         }
00709 
00710 //        vcl_cout << "o_intensity_sum = " << o_intensity_sum
00711 //                 << ", o_area_sum = " << o_area_sum << vcl_endl;
00712 
00713         float  o_intensity = (o_area_sum > 0) ?  o_intensity_sum / o_area_sum : 0.f;
00714 
00715         float  intensity_gradient = vcl_fabs(i_intensity - o_intensity);
00716 
00717 //        vcl_cout << "intensity_gradient = " << intensity_gradient
00718 //                 << ", curve length = " << e->curve()->length() << vcl_endl;
00719 
00720         weighted_perimeter_sum +=
00721           float(e->curve()->length()) * intensity_gradient;
00722         contrast_sum += intensity_gradient;
00723       }
00724       else
00725         vcl_cerr << "(*eit)->cast_to_edge_2d() returned NULL\n";
00726     }
00727 
00728 //    vcl_cout << "weighted_perimeter_sum = " << weighted_perimeter_sum
00729 //             << ", contrast_sum = " << contrast_sum << vcl_endl;
00730 
00731     weighted_perimeter_ = weighted_perimeter_sum / contrast_sum;
00732     delete p_edges;
00733   }
00734 
00735 //  vcl_cout << "Leaving vifsa::WeightedPerimeterSum()\n";
00736 
00737   return weighted_perimeter_;
00738 }
00739 
00740 // edge length^2 / detection area
00741 float vifa_int_faces_attr::
00742 Complexity()
00743 {
00744   if (this->Area() <= 0)
00745     return 0.f;
00746 
00747   float  p = this->PerimeterLength();
00748   return p * p / this->Area();
00749 }
00750 
00751 
00752 float vifa_int_faces_attr::
00753 WeightedComplexity()
00754 {
00755   if (this->Area() <= 0)
00756     return 0.f;
00757 
00758   float  wp = this->WeightedPerimeterLength();
00759   return wp * wp / this->Area();
00760 }
00761 
00762 void vifa_int_faces_attr::
00763 SetNP()
00764 {
00765   if (npobj_)
00766     npobj_->reset();
00767   else
00768     npobj_ = new vifa_parallel(faces_, true);
00769 }
00770 
00771 float vifa_int_faces_attr::
00772 TwoPeakParallel()
00773 {
00774   if (cached_2_parallel_ < 0)
00775   {
00776     SetNP();
00777     float  max_angle;
00778     float  std_dev;
00779     float  scale;
00780 
00781     for (int i=0; i<1; i++)
00782     {
00783       npobj_->map_gaussian(max_angle, std_dev, scale);
00784       npobj_->remove_gaussian(max_angle, std_dev, scale);
00785     }
00786 
00787     cached_2_parallel_ = npobj_->area();
00788   }
00789 
00790   return cached_2_parallel_;
00791 }
00792 
00793 float vifa_int_faces_attr::
00794 FourPeakParallel()
00795 {
00796   if (cached_4_parallel_ < 0)
00797   {
00798     SetNP();
00799     float  max_angle;
00800     float  std_dev;
00801     float  scale;
00802 
00803     for (int i=0; i<3; i++)
00804     {
00805       npobj_->map_gaussian(max_angle, std_dev, scale);
00806       npobj_->remove_gaussian(max_angle, std_dev, scale);
00807     }
00808 
00809     cached_4_parallel_ = npobj_->area();
00810   }
00811 
00812   return cached_4_parallel_;
00813 }
00814 
00815 float vifa_int_faces_attr::
00816 EightyPercentParallel()
00817 {
00818   if (cached_80_parallel_ < 0)
00819   {
00820     SetNP();
00821 
00822     for (int i=0; i < 20 && npobj_->area() > 0.3f; ++i)
00823     {
00824       float  max_angle, std_dev, scale;
00825       npobj_->map_gaussian(max_angle, std_dev, scale);
00826       npobj_->remove_gaussian(max_angle, std_dev, scale);
00827       cached_80_parallel_ = float(i);
00828     }
00829   }
00830 
00831   return cached_80_parallel_;
00832 }
00833 
00834 vifa_int_face_attr_sptr vifa_int_faces_attr::
00835 factory_new_attr(vtol_intensity_face_sptr face)
00836 {
00837   if (factory_)
00838     return factory_->obtain_int_face_attr(face,
00839                                           fitter_params_.ptr(),
00840                                           gpp_s_.ptr(),
00841                                           gpp_w_.ptr(),
00842                                           np_.ptr());
00843   else
00844     return new vifa_int_face_attr(face,
00845                                   fitter_params_.ptr(),
00846                                   gpp_s_.ptr(),
00847                                   gpp_w_.ptr(),
00848                                   np_.ptr());
00849 }

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