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

vifa_group_pgram.cxx

Go to the documentation of this file.
00001 // This is gel/vifa/vifa_group_pgram.cxx
00002 #include <vifa/vifa_group_pgram.h>
00003 //:
00004 // \file
00005 
00006 #include <vcl_cmath.h>
00007 #include <vnl/vnl_math.h>
00008 #include <vgl/vgl_clip.h>
00009 #include <vgl/vgl_vector_2d.h>
00010 
00011 #ifndef DEGTORAD
00012 #define DEGTORAD  (vnl_math::pi / 180.0)
00013 #endif
00014 
00015 
00016 vifa_group_pgram::
00017 vifa_group_pgram(imp_line_list&                  lg,
00018                  const vifa_group_pgram_params&  old_params,
00019                  double                          angle_range)
00020   : vifa_group_pgram_params(old_params)
00021 {
00022   angle_range_ = angle_range;
00023   th_dim_ = (int)vcl_ceil(angle_range_/angle_increment());
00024   th_dim_++; //Include both 0 and angle_range_
00025   bb_ = new vifa_bbox;
00026 
00027   for (int i = 0; i < th_dim_; i++)
00028   {
00029     imp_line_list*  illp = new imp_line_list;
00030     curves_.push_back(illp);
00031   }
00032   this->Index(lg);
00033 }
00034 
00035 //------------------------------------------------------------
00036 //: Destructor
00037 vifa_group_pgram::
00038 ~vifa_group_pgram()
00039 {
00040   for (imp_line_table::iterator ilti = curves_.begin(); ilti != curves_.end();
00041        ilti++)
00042   {
00043     imp_line_list*  illp = (*ilti);
00044     for (imp_line_iterator ili = illp->begin(); ili != illp->end(); ili++)
00045     {
00046       (*ili) = 0;
00047     }
00048 
00049     delete illp;
00050   }
00051 }
00052 
00053 //-----------------------------------------------------
00054 //: Add an ImplicitLine to the index
00055 void vifa_group_pgram::
00056 Index(imp_line_sptr il)
00057 {
00058   int  ang_bin = this->AngleLoc(il);
00059   curves_[ang_bin]->push_back(il);
00060 
00061   this->touch();
00062 }
00063 
00064 //------------------------------------------------------------
00065 //: Add a set of ImplicitLines to the angular index
00066 void vifa_group_pgram::
00067 Index(imp_line_list& lg)
00068 {
00069   for (imp_line_iterator ili = lg.begin(); ili != lg.end(); ili++)
00070     Index(*ili);
00071 }
00072 
00073 //------------------------------------------------------------
00074 //: Clear all lines from the index
00075 void vifa_group_pgram::
00076 Clear()
00077 {
00078   for (imp_line_table::iterator ilti = curves_.begin(); ilti != curves_.end();
00079        ilti++)
00080   {
00081     imp_line_list*  illp = (*ilti);
00082     for (imp_line_iterator ili = illp->begin(); ili != illp->end(); ili++)
00083       (*ili) = 0;
00084 
00085     delete illp;
00086     (*ilti) = new imp_line_list;
00087   }
00088 
00089   this->touch();
00090 }
00091 
00092 //-----------------------------------------------------------------
00093 //: Compute a histogram of parallel line coverage
00094 //
00095 vifa_histogram_sptr vifa_group_pgram::
00096 GetCoverageHist(void)
00097 {
00098   vifa_histogram_sptr  h = new vifa_histogram(th_dim_, 0.0f, float(angle_range_));
00099 
00100   float*  cnts = h->GetCounts();
00101   for (int i = 0; i < th_dim_; i++)
00102     cnts[i] = float(this->LineCoverage(i));
00103   return h;
00104 }
00105 
00106 //--------------------------------------------------------------
00107 //: Get a populated line coverage corresponding to a given angle bin
00108 //
00109 vifa_line_cover_sptr vifa_group_pgram::
00110 GetLineCover(int  angle_bin)
00111 {
00112   imp_line_sptr  il = this->LineAtAngle(angle_bin);
00113 
00114   // Get all the lines which are within +- angular resolution of angle_bin.
00115   imp_line_list  lg;
00116   this->CollectAdjacentLines(angle_bin, lg);
00117 
00118   if (!lg.size())
00119   {
00120     return NULL;
00121   }
00122 
00123   // Construct a bounding box from the ROI and clip
00124   // the line defined by angle_bin
00125   double  bx;
00126   double  by;
00127   double  ex;
00128   double  ey;
00129   this->CheckUpdateBoundingBox();
00130   if (!vgl_clip_line_to_box(il->a(), il->b(), il->c(),
00131                             bb_->min_x(), bb_->min_y(),
00132                             bb_->max_x(), bb_->max_y(),
00133                             bx, by, ex, ey))
00134   {
00135     vcl_cerr << "In vifa_group_pgram::GetLineCover(): No intersection found\n";
00136     return NULL;
00137   }
00138 
00139   // Here we set the clipping bounds.
00140   vgl_point_2d<double>  b(bx, by);
00141   vgl_point_2d<double>  e(ex, ey);
00142   il->set_points(b, e);
00143 
00144   // The line is cut into 1 pixel bins
00145   int len = int(il->length());
00146   if (!len)
00147   {
00148     return NULL;
00149   }
00150 
00151   vifa_line_cover_sptr  cov = new vifa_line_cover(il, len);
00152   for (imp_line_iterator ili = lg.begin(); ili != lg.end(); ili++)
00153   {
00154     cov->InsertLine(*ili);
00155   }
00156 
00157   return cov;
00158 }
00159 
00160 //--------------------------------------------------------------
00161 //: Compute parallel line overlap on a line at the same orientation with midpoint at the center of the region of the line group.
00162 //
00163 double vifa_group_pgram::
00164 LineCoverage(int  angle_bin)
00165 {
00166   vifa_line_cover_sptr  lc = this->GetLineCover(angle_bin);
00167   return lc ? lc->GetCoverage() : 0.0;
00168 }
00169 
00170 //--------------------------------------------------------------
00171 //: Collect implicit line(s) from the angle array at orientations +- the given bin orientation.
00172 //  Wrap around the end of the array so that 0 degrees and 180 degrees are considered parallel.
00173 void vifa_group_pgram::
00174 CollectAdjacentLines(int             angle_bin,
00175                      imp_line_list&  lg)
00176 {
00177   if (angle_bin >= 0 && angle_bin < th_dim_)
00178   {
00179     if (angle_bin == 0)
00180     {
00181       // Case I - At the beginning of the array
00182       lg.insert(lg.end(), curves_[th_dim_ - 1]->begin(),
00183                 curves_[th_dim_ - 1]->end());
00184       lg.insert(lg.end(), curves_[0]->begin(),
00185                 curves_[0]->end());
00186       lg.insert(lg.end(), curves_[1]->begin(),
00187                 curves_[1]->end());
00188     }
00189     else if (angle_bin == th_dim_ - 1)
00190     {
00191       // Case II - At the end of the array
00192       lg.insert(lg.end(), curves_[th_dim_ - 2]->begin(),
00193                 curves_[th_dim_ - 2]->end());
00194       lg.insert(lg.end(), curves_[th_dim_ - 1]->begin(),
00195                 curves_[th_dim_ - 1]->end());
00196       lg.insert(lg.end(), curves_[0]->begin(),
00197                 curves_[0]->end());
00198     }
00199     else
00200     {
00201       // Case III - not near ends of the array
00202       lg.insert(lg.end(), curves_[angle_bin - 1]->begin(),
00203                 curves_[angle_bin - 1]->end());
00204       lg.insert(lg.end(), curves_[angle_bin]->begin(),
00205                 curves_[angle_bin]->end());
00206       lg.insert(lg.end(), curves_[angle_bin + 1]->begin(),
00207                 curves_[angle_bin + 1]->end());
00208     }
00209   }
00210   else
00211     vcl_cerr << "vifa_group_pgram::CollectAdjacentLines(): bad angle_bin\n";
00212 }
00213 
00214 //------------------------------------------------------------------
00215 //: Get Total length of parallel lines adjacent and including a bin
00216 //
00217 double vifa_group_pgram::
00218 GetAdjacentPerimeter(int  bin)
00219 {
00220   imp_line_list  lg;
00221   this->CollectAdjacentLines(bin, lg);
00222 
00223   double  sum = 0;
00224   for (imp_line_iterator ili = lg.begin(); ili != lg.end(); ili++)
00225   {
00226     vgl_vector_2d<double>  v = (*ili)->point2() - (*ili)->point1();
00227     sum += v.length();
00228   }
00229 
00230   return sum;
00231 }
00232 
00233 //------------------------------------------------------
00234 //: Compute the total length of parallel lines normalized by the total edge perimeter
00235 double vifa_group_pgram::
00236 norm_parallel_line_length(void)
00237 {
00238   this->ComputeDominantDirs();
00239   if (dominant_dirs_.size() < 1)
00240   {
00241     // No basis
00242     return 0.0;
00243   }
00244 
00245   double max_cover = 0.0;
00246   int    max_dir = 0;
00247   vcl_vector<int>::iterator  iit = dominant_dirs_.begin();
00248   for (; iit != dominant_dirs_.end(); iit++)
00249   {
00250     int            dir = (*iit);
00251     vifa_line_cover_sptr  lc = this->GetLineCover(dir);
00252     if (!(lc.ptr()))
00253     {
00254 //      vcl_cout << "vgg::norm_parallel_line_length(): "
00255 //               << "No line cover found for dir " << dir << vcl_endl;
00256 
00257       // Is this right?  What about other dominant directions?
00258       // return 0.0;
00259       continue;
00260     }
00261 
00262     double  cov = lc->GetCoverage();
00263 
00264     if (cov > max_cover)
00265     {
00266       max_cover = cov;
00267       max_dir = dir;
00268     }
00269   }
00270 
00271   double  per = this->GetAdjacentPerimeter(max_dir);
00272 
00273 //  vcl_cout << "vgg::norm_parallel_line_length(): per = " << per
00274 //           << ", tmp1_ = " << tmp1_ << vcl_endl;
00275 
00276   return 1.5 * per / tmp1_;
00277 }
00278 
00279 //---------------------------------------------------------
00280 //: Find the angle bin corresponding to an implicit_line
00281 int vifa_group_pgram::
00282 AngleLoc(imp_line_sptr  il)
00283 {
00284   // Compute angle index
00285   double  angle = vcl_fmod(il->slope_degrees(), 180.0);
00286   if (angle < 0.0)
00287     angle += 180.0;
00288 
00289   if (angle > angle_range_)
00290   {
00291     vcl_cerr << "In vifa_group_pgram::AngleLoc(): angle " << angle
00292              << " was outside the angle range " << angle_range_ << vcl_endl;
00293     return 0;
00294   }
00295 
00296   return (int)(vcl_floor(angle / angle_increment()));
00297 }
00298 
00299 //--------------------------------------------------------------
00300 //: Define a line passing through the center of the Hough ROI and at an angle correspoinding the angle bin
00301 imp_line_sptr vifa_group_pgram::
00302 LineAtAngle(int  angle_bin)
00303 {
00304   // Get the new line's direction unit vector
00305   double          ang_rad = DEGTORAD * angle_bin * angle_increment();
00306   vgl_vector_2d<double>  d(vcl_cos(ang_rad), vcl_sin(ang_rad));
00307 
00308   // Get the new line's midpoint (bounding box centroid)
00309   this->CheckUpdateBoundingBox();
00310   vgl_point_2d<double>  m = bb_->centroid();
00311 
00312   // Return a new line
00313   imp_line_sptr      il = new imp_line(d, m);
00314   return il;
00315 }
00316 
00317 //------------------------------------------------------
00318 //: Compute the bounding box of the current index
00319 //
00320 void vifa_group_pgram::
00321 ComputeBoundingBox(void)
00322 {
00323   // Reset the bounding box
00324   bb_->empty();
00325 
00326   for (imp_line_table::iterator ilti = curves_.begin(); ilti != curves_.end();
00327        ilti++)
00328   {
00329     imp_line_list*  illp = (*ilti);
00330     for (imp_line_iterator ili = illp->begin(); ili != illp->end(); ili++)
00331     {
00332       imp_line_sptr  il = (*ili);
00333 
00334       bb_->add(il->point1());
00335       bb_->add(il->point2());
00336     }
00337   }
00338 
00339   // Update the bounding box timestamp
00340   bb_->touch();
00341 }
00342 
00343 //---------------------------------------------------------
00344 //: Compute the dominant directions using the coverage histogram.
00345 //  A dominant direction is a local maximum in the coverage distribution.
00346 //
00347 void vifa_group_pgram::
00348 ComputeDominantDirs(void)
00349 {
00350   dominant_dirs_.clear();
00351 
00352   // Get the coverage histogram and do find local maxima.
00353   vifa_histogram_sptr  h = this->GetCoverageHist();
00354   vifa_histogram_sptr  h_sup = h->NonMaximumSupress(max_suppress_radius(), true);
00355   float*               cnts = h_sup->GetCounts();
00356   int                  max_idx = h_sup->GetRes();
00357 
00358   // Rebuild the dominant direction array
00359   for (int i = 0; i < max_idx; i++)
00360     if (cnts[i] > 0)
00361       dominant_dirs_.push_back(i);
00362 
00363 //  vcl_cout << "vgg::ComputeDominantDirs(): max_idx = " << max_idx << ", "
00364 //           << dominant_dirs_.size() << " dominant directions found\n";
00365 }

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