test-VarianceRidgeDetector.C

00001 
00002 /*!@file Gist/test-SuperPixel.C testing SuperPixel segmentation algorithm */
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 //                                                       d               //
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/test-SuperPixel.C $
00035 // $Id: test-SuperPixel.C 12962 2010-03-06 02:13:53Z irock $
00036 //
00037 //////////////////////////////////////////////////////////////////////////
00038 //
00039 // Implementation of boundary detection algorithm described in:
00040 //
00041 // Real-time texture boundary detection from ridges
00042 // in the standard deviation space
00043 // Ray Hidayat and Richard Green
00044 // BMCV 2009
00045 
00046 #ifndef TEST_VARIANCE_RIDGE_DETECTOR
00047 #define TEST_VARIANCE_RIDGE_DETECTOR
00048 
00049 //#include "Image/OpenCVUtil.H"
00050 
00051 #include "Component/ModelManager.H"
00052 #include "Media/FrameSeries.H"
00053 #include "Transport/FrameIstream.H"
00054 
00055 #include "Raster/Raster.H"
00056 #include "Image/CutPaste.H"     // for inplacePaste()
00057 #include "Image/LowPass.H"
00058 
00059 #include "Image/ColorOps.H"
00060 #include "Image/MathOps.H"
00061 
00062 
00063 
00064 #include "Image/DrawOps.H"
00065 #include "Image/Kernels.H"
00066 #include "Image/FilterOps.H"
00067 
00068 #include "Image/ImageSet.H"
00069 #include "Image/PyramidOps.H"
00070 #include "Raster/Raster.H"
00071 
00072 #include "Util/Timer.H"
00073 #include  <cstdio>
00074 
00075 #include "Gist/ContourBoundaryDetector.H"
00076 
00077 Image<float> getGabor(Image<float> img,
00078                       float angle, float filter_period,
00079                       float elongation, int size);
00080 
00081 //Image<float> getCanny(Image<byte> img);
00082 
00083 
00084 
00085 int main(int argc, char **argv)
00086 {
00087   // instantiate a model manager:
00088   ModelManager manager("test VRD Boundary Detection");
00089 
00090   // Instantiate our various ModelComponents:
00091 
00092   nub::soft_ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00093   manager.addSubComponent(ifs);
00094 
00095   nub::soft_ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00096   manager.addSubComponent(ofs);
00097 
00098   rutz::shared_ptr<ContourBoundaryDetector> 
00099     cbd(new ContourBoundaryDetector());
00100 
00101   manager.exportOptions(MC_RECURSE);
00102 
00103   // Parse command-line:
00104   if (manager.parseCommandLine(argc, argv, "[window_size] ", 0, 1)
00105       == false) return(1);
00106 
00107   // get the operation mode
00108   int r = 8;
00109   if(manager.numExtraArgs() >  0)
00110     r = manager.getExtraArgAs<uint>(0);
00111 
00112   // let's do it!
00113   manager.start();
00114 
00115   ifs->updateNext();
00116   Image<PixRGB<byte> > ima = ifs->readRGB();
00117   // ima = Image<PixRGB<byte> >(ima.getDims(),ZEROS);
00118   // drawFilledRect(ima, 
00119   //       Rectangle(Point2D<int>(180, 100), Dims(100, 100)), 
00120   //       PixRGB<byte>(255,0,0));
00121 
00122   Image<float> fIma(luminance(ima));
00123   Image<float> tempFIma = fIma;
00124   inplaceNormalize(tempFIma, 0.0f,255.0f);  
00125   Image<byte>  bIma(tempFIma); 
00126 
00127   Timer timer(1000000); timer.reset();
00128   Image<float> boundaryMap = cbd->getVarianceRidgeBoundaryMap(ima, r);
00129   LINFO("time: %f ms", timer.get()/1000.0);
00130 
00131   // get non-max suppressed boundary map image
00132   
00133   float mVal = 32;
00134   float bVal = 255 - mVal;
00135   inplaceNormalize(boundaryMap, 0.0f,bVal);
00136   Image<byte> dBmapc(boundaryMap);
00137 
00138   Image<byte> dImaR, dImaG, dImaB;
00139   getComponents(ima, dImaR, dImaG, dImaB);
00140   inplaceNormalize(dImaR, byte(0), byte(mVal));
00141   inplaceNormalize(dImaG, byte(0), byte(mVal));
00142   inplaceNormalize(dImaB, byte(0), byte(mVal));
00143   Image<PixRGB<byte> > dBmap = toRGB(dBmapc);
00144   Image<PixRGB<byte> > dIma  = makeRGB(dImaR,dImaG,dImaB);
00145 
00146   // the non-max suppressed boundary map image
00147   Image<float> dBmapNMStemp = cbd->getNmsBoundaryMap();
00148   inplaceNormalize(dBmapNMStemp, 0.0F, 255.0F);
00149   Image<PixRGB<byte> > dBmapNMS = toRGB(Image<byte>(dBmapNMStemp));
00150 
00151   // the contour boundary map image
00152   Image<float> dCBmapTemp = cbd->getEdgelBoundaryMap();
00153   inplaceNormalize(dCBmapTemp, 0.0F, bVal);
00154   Image<PixRGB<byte> > dCBmap = toRGB(Image<byte>(dCBmapTemp));
00155 
00156   // setup the display map
00157   uint w = ima.getWidth();
00158   uint h = ima.getHeight();
00159   Image<PixRGB<byte> > dispIma(4*w,2*h,ZEROS);
00160   inplacePaste(dispIma, ima, Point2D<int>(0,0));
00161   inplacePaste(dispIma, Image<PixRGB<byte> >(dBmap), Point2D<int>(w,0));
00162   //inplacePaste(dispIma, Image<PixRGB<byte> >(dIma+dBmap), Point2D<int>(w,0));
00163   inplacePaste(dispIma, dBmapNMS, Point2D<int>(0,h));
00164   inplacePaste(dispIma,  Image<PixRGB<byte> >(dIma+dCBmap), Point2D<int>(w,h));
00165   inplacePaste(dispIma,  cbd->getContourBoundaryMap(), Point2D<int>(2*w,0));
00166 
00167   // angle at 4th param: 0 degrees
00168   //Image<float> gaborImg = getGabor(fIma, 0.0, 2.50, 1.0, 5);
00169   // Image<float> gaborImg = getGabor(fIma,0,7,1,9);
00170   // --------------
00171   // Image<float> gaborImg = getCanny(fIma);
00172   // inplaceNormalize(gaborImg, 0.0F, 255.0F);
00173   // Image<PixRGB<byte> > dGaborImg = toRGB(Image<byte>(gaborImg));
00174   // inplacePaste(dispIma, Image<PixRGB<byte> >(dGaborImg), 
00175   //           Point2D<int>(w,h));  
00176 
00177   // Image<float> rDir0 = itsRDirMax[0];
00178   // inplaceNormalize(rDir0, 0.0F, 255.0F);
00179   // Image<PixRGB<byte> > dRDir0 = toRGB(Image<byte>(rDir0));
00180   // inplacePaste(dispIma, dRDir0, Point2D<int>(2*w,0));
00181 
00182   // Image<float> rDir1 = itsRDirMax[1];
00183   // inplaceNormalize(rDir1, 0.0F, 255.0F);
00184   // Image<PixRGB<byte> > dRDir1 = toRGB(Image<byte>(rDir1));
00185   // inplacePaste(dispIma, dRDir1, Point2D<int>(3*w,0));
00186 
00187   // Image<float> rDir2 = itsRDirMax[2];
00188   // inplaceNormalize(rDir2, 0.0F, 255.0F);
00189   // Image<PixRGB<byte> > dRDir2 = toRGB(Image<byte>(rDir2));
00190   // inplacePaste(dispIma, dRDir2, Point2D<int>(2*w,h));
00191 
00192   // Image<float> rDir3 = itsRDirMax[3];
00193   // inplaceNormalize(rDir3, 0.0F, 255.0F);
00194   // Image<PixRGB<byte> > dRDir3 = toRGB(Image<byte>(rDir3));
00195   // inplacePaste(dispIma, dRDir3, Point2D<int>(3*w,h));
00196 
00197   // 300, 140
00198   drawRect(dispIma, 
00199            Rectangle(Point2D<int>(w+156, 68), Dims(8, 8)), 
00200            PixRGB<byte>(255,0,0));
00201   drawRect(dispIma, 
00202            Rectangle(Point2D<int>(w+152, 64), Dims(16, 16)), 
00203            PixRGB<byte>(255,255,0));
00204 
00205   drawRect(dispIma, 
00206            Rectangle(Point2D<int>(156, h+68), Dims(8, 8)), 
00207            PixRGB<byte>(255,0,0));
00208   drawRect(dispIma, 
00209            Rectangle(Point2D<int>(152, h+64), Dims(16, 16)), 
00210            PixRGB<byte>(255,255,0));
00211 
00212   //ofs->writeRGB(boundaryMap, "VRD Boundary Detection");
00213   ofs->writeRGB(dispIma, "VRD Boundary Detection");
00214   ofs->updateNext();
00215   Raster::waitForKey();
00216 
00217   return 0;
00218 }
00219 
00220 // ######################################################################
00221 Image<float> getGabor
00222 (Image<float> img, float angle, float filter_period, 
00223  float elongation, int size)
00224 {
00225   const double major_stddev = filter_period / 3.0;
00226   const double minor_stddev = major_stddev * elongation;
00227 
00228   // We have to add 90 to the angle here when constructing the gabor
00229   // filter. That's because the angle used to build the gabor filter
00230   // actually specifies the direction along which the grating
00231   // varies. This direction is orthogonal to the the direction of the
00232   // contours that the grating will detect.
00233   const double theta = angle + 90.0f;
00234 
00235   // In concept, we want to filter with four phases of the filter: odd
00236   // on+off, and even on+off (that would be xox, oxo, xo, and ox). But
00237   // since the on version just produces the negation of the off version,
00238   // we can get the summed output of both by just taking the absolute
00239   // value of the outputs of one of them. So we only need to convolve
00240   // with the filter in two phases, then take the absolute value (i.e.,
00241   // we're doing |xox| and |xo|).
00242 
00243   Image<float> g0 = gaborFilter3(major_stddev, minor_stddev,
00244                                  filter_period, 0.0f, theta, size);
00245   Image<float> g90 = gaborFilter3(major_stddev, minor_stddev,
00246                                   filter_period, 90.0f, theta, size);
00247 
00248   LDEBUG("angle = %.2f, period = %.2f pix, size = %dx%d pix",
00249          angle, filter_period, g0.getWidth(), g0.getHeight());
00250 
00251   Image<float> f0, f90;
00252   Image<float> result(img.getDims(), NO_INIT);
00253 
00254   Image<float> temp = energyNorm(img);
00255   f0 = optConvolve(temp, g0);
00256   f90 = optConvolve(temp, g90);
00257 
00258   result = f0 + f90;
00259 
00260   return result;
00261 }
00262 
00263 // // ######################################################################
00264 // Image<float> getCanny(Image<byte> img)
00265 // {
00266 //   Image<float> ret;
00267 //   IplImage *cvImg = cvCreateImage(cvGetSize(img2ipl(img)),8,1);  
00268 //   int ap = 7;
00269 //   cvCanny(img2ipl(img),cvImg, ap*ap*100, ap*ap*200, 7);
00270 //   return ipl2gray(cvImg);
00271 // }
00272 
00273 #endif
00274 
00275 // ######################################################################
00276 /* So things look consistent in everyone's emacs... */
00277 /* Local Variables: */
00278 /* indent-tabs-mode: nil */
00279 /* End: */
Generated on Sun May 8 08:40:39 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3