test-EdgeDetect.C

Go to the documentation of this file.
00001 /*!@file BeoSub/test-EdgeDetect.C */
00002 
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:
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/BeoSub/test-EdgeDetect.C $
00035 // $Id: test-EdgeDetect.C 7452 2006-11-15 22:49:56Z ilab13 $
00036 //
00037 
00038 #include "GUI/XWindow.H"
00039 //CAMERA STUFF
00040 #include "Image/Image.H"
00041 #include "Image/Pixels.H"
00042 
00043 #include "Component/ModelManager.H"
00044 #include "Devices/FrameGrabberFactory.H"
00045 #include "Util/Timer.H"
00046 #include "Util/Types.H"
00047 #include "Util/log.H"
00048 #include "Image/ColorOps.H"
00049 #include "Image/Image.H"
00050 #include "Image/MathOps.H"
00051 #include "Image/DrawOps.H"
00052 #include "Image/FilterOps.H"
00053 #include "Image/Transforms.H"
00054 #include "Raster/Raster.H"
00055 #include "BeoSub/hysteresis.H"
00056 #include "VFAT/segmentImageTrackMC.H"
00057 #include "rutz/shared_ptr.h"
00058 #include <cstdio>
00059 #include <cstdlib>
00060 #include <cstring>
00061 #include <iostream> //needed for segmentImageTrackMC!
00062 #include <math.h>
00063 
00064 #include "Image/Convolver.H"
00065 //END CAMERA STUFF
00066 
00067 ////////////////////////////////////////////////////
00068 // Canny Edge Detection
00069 // Randolph Voorhies
00070 // 11/15/05
00071 ///////////////////////////////////////////////////
00072 
00073 
00074 #define PI 3.14159265
00075 #define TRACE_CONTOUR_DEPTH_LIMIT 3
00076 
00077 
00078 //Depth limited search to trace contours
00079 bool traceContour(const Image<float> &magnitudeImage, const int x, const int y, const int loThresh, const int hiThresh, const int from, const int steps) {
00080  if(magnitudeImage.getVal(x,y) >= hiThresh)
00081   return true;
00082  if(magnitudeImage.getVal(x,y) < loThresh)
00083   return false;
00084  if(x == 0 || x >= magnitudeImage.getWidth() - 1 || y == 0 || y >= magnitudeImage.getHeight() - 1)
00085   return false;
00086 
00087  if(steps >= TRACE_CONTOUR_DEPTH_LIMIT)
00088   return false;
00089 
00090  if(magnitudeImage.getVal(x-1,y) > loThresh && from != 1)
00091   if(traceContour(magnitudeImage, x-1, y, loThresh, hiThresh, 5, steps+1))
00092    return true;
00093  if(magnitudeImage.getVal(x-1,y-1) > loThresh && from != 2)
00094   if(traceContour(magnitudeImage, x-1, y-1, loThresh, hiThresh, 6, steps+1))
00095    return true;
00096  if(magnitudeImage.getVal(x-1,y+1) > loThresh && from != 8)
00097   if(traceContour(magnitudeImage, x-1, y+1, loThresh, hiThresh, 4, steps+1))
00098    return true;
00099  if(magnitudeImage.getVal(x,y-1) > loThresh && from != 3)
00100   if(traceContour(magnitudeImage, x, y-1, loThresh, hiThresh, 7, steps+1))
00101    return true;
00102  if(magnitudeImage.getVal(x,y+1) > loThresh && from != 7)
00103   if(traceContour(magnitudeImage, x, y+1, loThresh, hiThresh, 3, steps+1))
00104    return true;
00105  if(magnitudeImage.getVal(x+1,y-1) > loThresh && from != 4)
00106   if(traceContour(magnitudeImage, x+1, y-1, loThresh, hiThresh, 8, steps+1))
00107    return true;
00108  if(magnitudeImage.getVal(x+1,y) > loThresh && from != 5)
00109   if(traceContour(magnitudeImage, x+1, y, loThresh, hiThresh, 1, steps+1))
00110    return true;
00111  if(magnitudeImage.getVal(x+1,y+1) > loThresh && from != 6)
00112   if(traceContour(magnitudeImage, x+1, y+1, loThresh, hiThresh, 2, steps+1))
00113    return true;
00114 
00115 return false;
00116 }
00117 
00118 void nonMaxSuppressAndContTrace(Image<byte> &edgeImage, const Image<float> magnitudeImage, const Image<float> orientationImage, const int loThresh, const int hiThresh) {
00119  float mag, pa=0, pb=0, orientDeg;
00120 
00121  for(int x = 1; x < magnitudeImage.getWidth() - 1; x++)
00122   for(int y = 1; y < magnitudeImage.getHeight() - 1; y++) {
00123    mag = magnitudeImage.getVal(x,y);
00124    orientDeg = orientationImage.getVal(x,y)*(180/PI);
00125 
00126    if((orientDeg >= 0 && orientDeg <= 45) || (orientDeg > -180 && orientDeg <= -135)) {
00127      pa = (magnitudeImage.getVal(x+1,y) + magnitudeImage.getVal(x+1,y-1))/2;
00128      pb = (magnitudeImage.getVal(x-1,y) + magnitudeImage.getVal(x-1,y+1))/2;
00129    }
00130    else if((orientDeg > 45 && orientDeg <= 90) || (orientDeg > -135 && orientDeg <= -90)) {
00131      pa = (magnitudeImage.getVal(x+1,y-1) + magnitudeImage.getVal(x,y-1))/2;
00132      pb = (magnitudeImage.getVal(x-1,y+1) + magnitudeImage.getVal(x,y+1))/2;
00133    }
00134    else if((orientDeg > 90 && orientDeg <= 135) || (orientDeg > -90 && orientDeg <= -45)) {
00135      pa = (magnitudeImage.getVal(x,y-1) + magnitudeImage.getVal(x-1,y-1))/2;
00136      pb = (magnitudeImage.getVal(x,y+1) + magnitudeImage.getVal(x+1,y+1))/2;
00137    }
00138    else if((orientDeg > 135 && orientDeg <= 180) || (orientDeg > -45 && orientDeg < 0)) {
00139      pa = (magnitudeImage.getVal(x-1,y-1) + magnitudeImage.getVal(x-1,y))/2;
00140      pb = (magnitudeImage.getVal(x+1,y+1) + magnitudeImage.getVal(x+1,y))/2;
00141    }
00142 
00143    if(mag > pa && mag > pb) {
00144      if(mag < loThresh)
00145       continue;
00146      else if(mag > hiThresh)
00147       edgeImage.setVal(x,y,255);
00148      else if(traceContour(magnitudeImage,x,y,loThresh,hiThresh, -1, 0)) {
00149       edgeImage.setVal(x,y,255);
00150      }
00151     }
00152    }
00153 }
00154 
00155 //TODO: Templates not working correctly: sending a Image<float> as a source breaks it.
00156 template <class T_or_RGB>
00157 Image<byte> cannyEdgeDetect(const Image<T_or_RGB> source, const float sigma, const int loThresh, const int hiThresh) {
00158 
00159  Image<byte> edgeImage(source.getDims(), ZEROS);            //Image to return
00160  Image<float> magnitudeImage(source.getDims(), ZEROS);      //First Derivative Magnitude Image
00161  Image<float> orientationImage(source.getDims(), ZEROS);    //First Derivative Orientation Image
00162 
00163  //gaussian blurred image -- to reduce noise
00164  Image<float> fblurImage = luminance(convGauss(source, sigma, sigma,10));
00165 
00166  //Find the magnitude and orientation
00167  gradient(fblurImage, magnitudeImage, orientationImage);
00168 
00169  //Perform non-maximul suppression and contour tracing to determine edges
00170  nonMaxSuppressAndContTrace(edgeImage, magnitudeImage, orientationImage, loThresh, hiThresh);
00171 
00172  return edgeImage;
00173 }
00174 
00175 
00176 
00177 //good tlo and thi values are 10, 16, with a sigma of 2
00178 int main(int argc, char* argv[]) {
00179 
00180   int loThresh, hiThresh;
00181   float sigma;
00182   Image< PixRGB<byte> > cameraImage;
00183   Image<float> floatImage;
00184 
00185   if(argc != 4) {
00186    std::cout << "USAGE: bin/EdgeDetect sigma Tlow Thigh " << std::endl;
00187    std::cout << "       *Thigh and Tlow are thresholds for the canny algorithm" << std::endl;
00188    std::cout << "       *sigma is used in gaussian mask" << std::endl;
00189    exit(0);
00190   }
00191 
00192   sigma = (float)atoi(argv[1]);
00193   loThresh = atoi(argv[2]);
00194   hiThresh = atoi(argv[3]);
00195 
00196   XWindow* xwin;
00197   XWindow* xwin2;
00198 
00199   ModelManager camManager("ColorTracker Tester");
00200   nub::soft_ref<FrameIstream> gb(makeIEEE1394grabber(camManager, "colorcam", "cocam"));
00201   camManager.addSubComponent(gb);
00202   //camManager.loadConfig("camconfig.pmap");
00203   gb->setModelParamVal("FrameGrabberSubChan", 0);
00204   camManager.start();
00205 
00206   cameraImage = gb->readRGB();
00207 
00208   xwin = new XWindow(cameraImage.getDims());
00209   xwin2 = new XWindow(cameraImage.getDims());
00210 
00211   while(1) {
00212     cameraImage = gb->readRGB();
00213     //floatImage = cameraImage;
00214     xwin->drawImage(cameraImage);
00215     //xwin2->drawImage(cannyEdgeDetect(floatImage, sigma, loThresh, hiThresh));
00216     xwin2->drawImage(cannyEdgeDetect(cameraImage, sigma, loThresh, hiThresh));
00217   }
00218 return 0;
00219 }
00220 
00221 // ######################################################################
00222 /* So things look consistent in everyone's emacs... */
00223 /* Local Variables: */
00224 /* indent-tabs-mode: nil */
00225 /* End: */
Generated on Sun May 8 08:40:20 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3