ContourBoundaryDetector.H

Go to the documentation of this file.
00001 /*!@file Gist/ContourBoundaryDetector.H Detect meaningful contours by
00002    weighting longer countour chains more */
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Gist/ContourBoundaryDetector.H $
00035 // $Id: $
00036 //
00037 //////////////////////////////////////////////////////////////////////////
00038 //
00039 // Detect meaningful contours by weighting longer countour chains more
00040 // 
00041 // Based on Hidayat's Variance Ridge boundary detector. 
00042 // However, we thin and parameterize the boundary to contours.
00043 //
00044 //
00045 // Real-time texture boundary detection from ridges
00046 // in the standard deviation space
00047 // Ray Hidayat and Richard Green
00048 // BMCV 2009
00049 
00050 #ifndef CONTOUR_BOUNDARY_DETECTOR
00051 #define CONTOUR_BOUNDARY_DETECTOR
00052 
00053 #define NUM_GRADIENT_DIRECTIONS   8
00054 #define NUM_RIDGE_DIRECTIONS      NUM_GRADIENT_DIRECTIONS/2
00055 #define BOUNDARY_STEP_SIZE        NUM_GRADIENT_DIRECTIONS
00056 #define DEFAULT_NEIGHBORHOOD_RAD  8
00057 
00058 #include "Image/Image.H"
00059 #include "Raster/Raster.H"
00060 
00061 #include "GUI/XWinManaged.H"
00062 
00063 struct Edgel
00064 {
00065   Edgel() { };
00066 
00067   Edgel(const Point2D<int> inPt,
00068         const float inAngle,
00069         const int inAngleIndex,
00070         const float inVal) :
00071     pt(inPt),
00072     angle(inAngle),
00073     angleIndex(inAngleIndex),
00074     val(inVal)
00075   {
00076   }
00077 
00078   Point2D<int> pt;
00079   float angle;
00080   int angleIndex; // -1 means no value
00081   float val;
00082 
00083   bool operator < (const Edgel& e)
00084   {
00085     return val < e.val;
00086   }
00087 };
00088 
00089 struct Contour
00090 {
00091   Contour() { };
00092 
00093   Contour(const std::vector<rutz::shared_ptr<Edgel> > inEdgels) :
00094     edgels(inEdgels)
00095   {
00096   }
00097 
00098   std::vector<rutz::shared_ptr<Edgel> > edgels;
00099 };
00100 
00101 
00102 //! Contour boundary detector implementing:
00103 //! Real-time texture boundary detection from ridges
00104 //! in the standard deviation space
00105 //! Ray Hidayat and Richard Green
00106 //! BMCV 2009
00107 class ContourBoundaryDetector
00108 {
00109 public:
00110 
00111   // ######################################################################
00112   //! @name Constructor, assigment and destructor
00113   //@{
00114 
00115   //! constructor
00116   ContourBoundaryDetector();
00117 
00118   //! destructor
00119   ~ContourBoundaryDetector();
00120 
00121   //@}
00122 
00123   // ######################################################################
00124   //! @name Compute functions
00125   //@{
00126 
00127   //! the full procedure to calculate
00128   //! contour boundary 
00129   void computeContourBoundary
00130   (Image<PixRGB<byte> > ima, int r = -1);
00131 
00132   //! get the variance ridge boundary
00133   Image<float> getVarianceRidgeBoundaryMap
00134   (Image<PixRGB<byte> > ima, int r = -1);
00135 
00136   //! get the contour boundary map
00137   //! assume computeContourBoundary or
00138   //! or other compute functions that includes
00139   //! variance ridge boundary map computation
00140   //! is already called on the same image
00141   Image<float> getVarianceRidgeBoundaryMap();
00142 
00143   //! get the Non-max Suppressed 
00144   //! Variance Ridge (VR) boundary
00145   Image<float> getNmsBoundaryMap
00146   (Image<PixRGB<byte> > ima, int r = -1);
00147 
00148   //! get the non-max suppressed VR boundary map
00149   //! assume computeContourBoundary or
00150   //! or other necessary compute functions, which includes
00151   //! Non-max Suppressed VR boundary map computation
00152   //! is already called on the same image
00153   Image<float> getNmsBoundaryMap();
00154 
00155   // get the contour boundary edgels 
00156   Image<float> getEdgelBoundaryMap
00157   (Image<PixRGB<byte> > ima, int r = -1);
00158 
00159   //! get the non-max suppressed VR boundary map
00160   //! assume computeContourBoundary or
00161   //! or other necessary compute functions, which includes
00162   //! edgel boundary map computation
00163   //! is already called on the same image
00164   Image<float> getEdgelBoundaryMap();
00165 
00166   //! get the contour boundary map
00167   Image<PixRGB<byte> > getContourBoundaryMap
00168   (Image<PixRGB<byte> > ima, int r = -1);
00169 
00170   //! get the contour boundary map
00171   //! assume computeContourBoundary or
00172   //! or other necessary compute functions, which includes
00173   //! contour boundary map computation
00174   //! are already called on the same image
00175   Image<PixRGB<byte> > getContourBoundaryMap();
00176 
00177   //! display the gradient magnitude image 
00178   void displayGradImage(std::vector<Image<float> > gradImg);
00179 
00180   //@}
00181 
00182   // ######################################################################
00183   //! @name Access functions
00184   //@{
00185   
00186   //! get contour boundaries
00187   inline std::vector<rutz::shared_ptr<Contour> > getContourBoundaries();
00188 
00189   //@}
00190 
00191 private:
00192 
00193   // ######################################################################
00194   //! @name Compute functions (all the inner-working functions)
00195   //@{
00196 
00197   //! compute the Variance Ridge Boundary map
00198   void computeVarianceRidgeBoundaryMap();
00199 
00200   //! compute the non-max suppressed
00201   //! variance ridge boundary map
00202   void computeNmsBoundaryMap();
00203 
00204   //! compute the contour boundary edgels
00205   void computeContourBoundaryEdgels();
00206 
00207   //! compute the contour boundary map
00208   void computeContourBoundaryMap();
00209 
00210   //! calculate the local standard deviation of the image
00211   Image<float> getLabStandardDeviation
00212   (Image<PixRGB<byte> > ima, int r = 8);
00213 
00214   //! VarianceRidgeDetector: box-blur the image for local mean
00215   Image<float> boxBlur
00216   (Image<float> ridgeImg, int rad);
00217 
00218   //! VarianceRidgeDetector: square combine the Lab channels
00219   Image<float> sqCombine
00220   (Image<float> a, Image<float> b, Image<float> c);
00221 
00222   //!  VarianceRidgeDetector: 
00223   //!    calculate gradient of the standard dev. image
00224   std::vector<Image<float> > calculateGradient
00225   (Image<float> varImg, int r = 8);
00226 
00227   //!  VarianceRidgeDetector: 
00228   //!    compute the ridge of the gradient image
00229   Image<float>  getRidge
00230   (std::vector<Image<float> > gradImg, int r = 8);
00231 
00232   //! substract the gradient magnitude from the ridge image
00233   Image<float> substractGradImg
00234   (Image<float> ridgeImg, std::vector<Image<float> >  gradImg);
00235 
00236   //! compute the contour boundary edgels
00237   Image<float> getContourBoundaryEdgels();
00238 
00239   //! compute the non-max suppresion image 
00240   Image<float> getNonMaxSuppression(Image<float> bImg);
00241 
00242   //! group the boundary edgels to contours
00243   void connectContourEdgels();
00244 
00245   //! check if the contour can be lengthened with the new edgel
00246   bool addEdgelToContour
00247   (int &i, int &j, 
00248    rutz::shared_ptr<Edgel> &edgel, 
00249    rutz::shared_ptr<Contour> &contour,
00250    int sign);
00251 
00252   //! get the location of where to look for next edgels
00253   //! given a direction
00254   void getEdgelDirectionNeighborhood
00255   (int ci, int cj, int dir, int sign, 
00256    int &ni1, int &nj1, int &ni2, int &nj2, int &ni3, int &nj3);
00257 
00258   //! given two edgels 
00259   //! figure out if the they can be connected
00260   bool isLegalDirection
00261   (int ci, int cj, int cd, int sign, 
00262    int ni, int nj, int nd);
00263 
00264   //! create an image representation of the contours
00265   Image<PixRGB<byte> > getContourBoundaryImage();
00266 
00267   //! display contour boundary 1 contour at a time
00268   void displayContourBoundary();
00269 
00270   //@}
00271 
00272   //! its current input image
00273   Image<PixRGB<byte> > itsImage;
00274  
00275   //! the radius of considered neighborhood
00276   int itsRadius;
00277 
00278   //! the ridge direction map
00279   std::vector<Image<float> > itsRidgeDirection;
00280 
00281   //! the maximum values (for each pixel) of the ridge direction map
00282   std::vector<Image<float> > itsRidgeDirectionMax;
00283 
00284   //! the winning index (for each pixel) of the ridge direction map
00285   Image<float> itsRidgeDirectionIndex;
00286   
00287   //! boundary map image (from Variance Ridge Detector)
00288   Image<float> itsBoundaryImage;
00289 
00290   //! the ridge direction map
00291   std::vector<Image<float> > itsRidgeDirectionNMS;
00292 
00293   //! the non-max suppressed version of the boundary map
00294   //! We use our own 5x5 kernel 
00295   Image<float> itsBoundaryImageNMS;
00296 
00297   //! the raw gradient standard deviation values 
00298   std::vector<std::vector<Image<float> > > itsDVin; 
00299 
00300   //! list of edgels in all RF edgel locations
00301   Image<std::vector<rutz::shared_ptr<Edgel> > > itsEdgels;
00302 
00303   //! edgel boundary map image
00304   Image<float> itsEdgelBoundaryImage;
00305 
00306   //! the list of contour Boundaries
00307   std::vector<rutz::shared_ptr<Contour> > itsContourBoundaries;
00308 
00309   //! contour storage based on location
00310   Image<rutz::shared_ptr<Contour> > itsContourMap;
00311 
00312   //! contour boundary image
00313   Image<PixRGB<byte> > itsContourBoundaryImage;
00314 
00315   //! region segmentation image 
00316   Image<PixRGB<byte> > itsRegionSegmentationImage;
00317 
00318   //! debug window
00319   rutz::shared_ptr<XWinManaged> itsWin;
00320 };
00321 
00322 // ######################################################################
00323 // Implementation for ContourBoundaryDetector inline functions
00324 // ######################################################################
00325 inline std::vector<rutz::shared_ptr<Contour> > 
00326 ContourBoundaryDetector::getContourBoundaries()
00327 { return itsContourBoundaries; }
00328 
00329 #endif
00330 
00331 // ######################################################################
00332 /* So things look consistent in everyone's emacs... */
00333 /* Local Variables: */
00334 /* indent-tabs-mode: nil */
00335 /* End: */
Generated on Sun May 8 08:40:39 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3