test-envObjRec.C

Go to the documentation of this file.
00001 /*! @file ObjRec/test-envObjRec.C test various obj rec alg */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the 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: Lior Elazary <elazary@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/ObjRec/test-envObjRec.C $
00035 // $Id: test-envObjRec.C 13716 2010-07-28 22:07:03Z itti $
00036 //
00037 
00038 
00039 #include "Image/OpenCVUtil.H"
00040 #include "Component/ModelManager.H"
00041 #include "Image/Image.H"
00042 #include "Image/ImageSet.H"
00043 #include "Image/ShapeOps.H"
00044 #include "Image/CutPaste.H"
00045 #include "Image/DrawOps.H"
00046 #include "Image/FilterOps.H"
00047 #include "Image/ColorOps.H"
00048 #include "Image/Transforms.H"
00049 #include "Image/MathOps.H"
00050 #include "Image/fancynorm.H"
00051 #include "Transport/FrameInfo.H"
00052 #include "Raster/Raster.H"
00053 #include "Raster/GenericFrame.H"
00054 #include "GUI/DebugWin.H"
00055 #include "Neuro/EnvVisualCortex.H"
00056 #include "Media/FrameSeries.H"
00057 #include "Util/Timer.H"
00058 
00059 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00060 #define OPENCV_HOUGH 1    // opencv hough transform
00061 //#define SALIENCY_HOUGH 1    // opencv hough transform
00062 #define ORI_QUE 1           //use orientation que
00063 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00064 ModelManager *mgr;
00065 
00066 bool debug = 0;
00067 Timer timer;
00068 int smap_level = 0;
00069 
00070 #define halfPi ((float)(CV_PI*0.5))
00071 #define Pi     ((float)CV_PI)
00072 #define a0  0 /*-4.172325e-7f*/   /*(-(float)0x7)/((float)0x1000000); */
00073 #define a1 1.000025f        /*((float)0x1922253)/((float)0x1000000)*2/Pi; */
00074 #define a2 -2.652905e-4f    /*(-(float)0x2ae6)/((float)0x1000000)*4/(Pi*Pi); */
00075 #define a3 -0.165624f       /*(-(float)0xa45511)/((float)0x1000000)*8/(Pi*Pi*Pi); */
00076 #define a4 -1.964532e-3f    /*(-(float)0x30fd3)/((float)0x1000000)*16/(Pi*Pi*Pi*Pi); */
00077 #define a5 1.02575e-2f      /*((float)0x191cac)/((float)0x1000000)*32/(Pi*Pi*Pi*Pi*Pi); */
00078 #define a6 -9.580378e-4f    /*(-(float)0x3af27)/((float)0x1000000)*64/(Pi*Pi*Pi*Pi*Pi*Pi); */
00079 
00080 #define _sin(x) ((((((a6*(x) + a5)*(x) + a4)*(x) + a3)*(x) + a2)*(x) + a1)*(x) + a0)
00081 #define _cos(x) _sin(halfPi - (x))
00082 #define NUMANGLE 180
00083 float tabSin[NUMANGLE];
00084 float tabCos[NUMANGLE];
00085 
00086 
00087 void display(Image<PixRGB<byte> > &leftImg,
00088     const Image<PixRGB<byte> > &leftSmap,
00089     const Image<PixRGB<byte> > &hough,
00090     const Point2D<int> &leftWinner,
00091     const byte maxVal,
00092     const Point2D<int> &targetLoc,
00093     nub::ref<OutputFrameSeries> ofs);
00094 
00095 
00096 int biasProc(const char *tagName,
00097     env_size_t clev,
00098     env_size_t slev,
00099     struct env_image *cmap,
00100     const struct env_image *center,
00101     const struct env_image *surround)
00102 {
00103   //intg32* src = cmap->pixels;
00104 
00105   ENV_SHOWIMG(cmap, 512, 512);
00106 
00107   //uint foveaWidth = (FSIZE >> smap_level)/2;
00108   //uint foveaHeight = (FSIZE >> smap_level)/2;
00109 
00110   //struct env_image *outImg = new struct env_image;
00111  // env_img_init(outImg, cmap->dims);
00112   //intg32* outSrc = outImg->pixels;
00113 
00114   return 0;
00115 }
00116 
00117 void putLine(Image<PixRGB<byte> > &img, float r, float m)
00118 {
00119   double a = cos(m), b = sin(m);
00120   double x0 = a*r, y0 = b*r;
00121   Point2D<int> p1(cvRound(x0 + 1000*(-b)), cvRound(y0 + 1000*(a)));
00122   Point2D<int> p2(cvRound(x0 - 1000*(-b)), cvRound(y0 - 1000*(a)));
00123 
00124   drawLine(img, p1, p2, PixRGB<byte>(255,0,0));
00125 
00126 }
00127 
00128 Image<float> houghTrans(const Image<float> &edge, const Image<float> &ori,
00129     const Image<float> &smap)
00130 {
00131 
00132   int w = edge.getWidth();
00133   int h = edge.getHeight();
00134   float theta = CV_PI/180;
00135   int rho = 1;
00136   int numangle = int(CV_PI/theta);
00137   int numrho = int(((w+h)*2 +1) / rho);
00138 
00139   Image<float> acc(numrho+2,numangle+2,ZEROS); //the accumulator
00140 
00141 
00142   Image<float>::const_iterator magPtr = edge.begin();
00143   Image<float>::iterator accPtr = acc.beginw();
00144 
00145 #ifdef ORI_QUE
00146   Image<float>::const_iterator oriPtr = ori.begin();
00147 #endif
00148 
00149   for(int y=0; y<h; y++)
00150     for(int x=0; x<w; x++)
00151     {
00152       float val = magPtr[y*w+x];
00153       if (val > 100)
00154       {
00155         int minOri = 0, maxOri = numangle;
00156 #ifdef ORI_QUE
00157         int oriQue = int((oriPtr[y*w+x]*180/M_PI));
00158         if (oriQue < 0) oriQue += 180;
00159 
00160         minOri = (oriQue - 25); if (minOri < 0) minOri = 0;
00161         maxOri = (oriQue + 25); if (maxOri > numangle) maxOri = numangle-1;
00162 #endif
00163 
00164         for(int m=minOri; m<maxOri; m++)
00165         {
00166           int r = int(x*tabCos[m] + y*tabSin[m]);
00167           r += (numrho -1) /2;
00168           accPtr[(m+1) * (numrho+2) + r+1] += val;
00169         }
00170       }
00171     }
00172 
00173   return acc;
00174 
00175 }
00176 
00177 Image<PixRGB<byte> > showHough(const Image<float> &acc, const Image<float> &mag)
00178 {
00179 
00180   Image<float> tmpAcc = acc; //(acc.getDims(), ZEROS);
00181   Image<PixRGB<byte> > retImg = mag;
00182  // int thresh = 1;
00183   int numrho = acc.getWidth()-2;
00184  // int numangle = acc.getHeight()-2;
00185 
00186   Point2D<int> maxPos;
00187   float maxVal;
00188 
00189   /*//Image<float>::const_iterator accPtr = acc.begin();
00190   //find local maximums
00191   for(int r=0; r<numrho; r++)
00192     for(int m=0; m<numangle; m++)
00193     {
00194       int base = (m+1)* (numrho+2) + r+1;
00195       if (acc[base] > thresh &&
00196           acc[base] > acc[base-1] && acc[base] >= acc[base+1] &&
00197           acc[base] > acc[base - numrho - 2] && acc[base] >= acc[base + numrho + 2])
00198       {
00199         tmpAcc[base] = acc[base];
00200         //float rho = (r - (numrho - 1)*0.5f);
00201         //float theta = (m * CV_PI/180);
00202         //printf("Base %f\n", acc[base]);
00203         //putLine(retImg, rho, theta);
00204 
00205       }
00206     }
00207   */
00208 
00209   for(int i=0; i<10; i++)
00210   {
00211     findMax(tmpAcc, maxPos, maxVal);
00212     int r = maxPos.i;
00213     int m = maxPos.j;
00214     float rho = (r - (numrho - 1)*0.5f);
00215     float theta = (m * CV_PI/180);
00216     putLine(retImg, rho, theta);
00217 
00218     drawDisk(tmpAcc, Point2D<int>(r,m), 5 , float(0)); //IOR
00219    // SHOWIMG(tmpAcc);
00220    // SHOWIMG(retImg);
00221   }
00222 
00223 
00224   return retImg;
00225 }
00226 
00227 float w (float *p, int k)
00228 {
00229         int i;
00230         float x=0.0;
00231 
00232         for (i=1; i<=k; i++) x += p[i];
00233         return x;
00234 }
00235 
00236 float u (float *p, int k)
00237 {
00238         int i;
00239         float x=0.0;
00240 
00241         for (i=1; i<=k; i++) x += (float)i*p[i];
00242         return x;
00243 }
00244 
00245 float nu (float *p, int k, float ut, float vt)
00246 {
00247         float x, y;
00248 
00249         y = w(p,k);
00250         x = ut*y - u(p,k);
00251         x = x*x;
00252         y = y*(1.0-y);
00253         if (y>0) x = x/y;
00254          else x = 0.0;
00255         return x/vt;
00256 }
00257 
00258 
00259 Image<float> segmentProb(const Image<float> &img)
00260 {
00261   Image<float> retImg = img;
00262   int hist[260];
00263   float p[260];
00264 
00265   inplaceNormalize(retImg, 0.0F, 255.0F);
00266 
00267   for(int i=0; i<260; i++)
00268   {
00269     hist[i] = 0; //set histogram to 0
00270     p[i] = 0; //set prob to 0
00271   }
00272 
00273   for (int y=0; y<retImg.getHeight(); y++)
00274     for(int x=0; x<retImg.getWidth(); x++)
00275     {
00276       int val = (int)retImg.getVal(x,y);
00277       hist[val+1]++;
00278     }
00279 
00280   //nomalize into a distribution
00281   for (int i=1; i<=256; i++)
00282     p[i] = (float)hist[i]/(float)retImg.getSize();
00283 
00284   //find the global mean
00285   float ut = 0.0;
00286   for(int i=1; i<=256; i++)
00287     ut += (float)i*p[i];
00288 
00289   //find the global variance
00290   float vt = 0.0;
00291   for(int i=1; i<=256; i++)
00292     vt += (i-ut)*(i-ut)*p[i];
00293 
00294   int j=-1, k=-1;
00295   for(int i=1; i<=256; i++)
00296   {
00297     if ((j<0) && (p[i] > 0.0)) j = i; //first index
00298     if (p[i] > 0.0) k = i; //last index
00299   }
00300 
00301   float z = -1.0;
00302   int m = -1;
00303   for (int i=j; i<=k; i++)
00304   {
00305     float y = nu(p,i,ut,vt); //compute nu
00306 
00307     if (y>=z)
00308     {
00309       z = y;
00310       m = i;
00311     }
00312   }
00313 
00314   int t = m;
00315 
00316   if (t < 0)
00317     LINFO("ERROR");
00318   else
00319     LINFO("THreshold is %i", t);
00320 
00321   //threshold
00322   for (int y=0; y<retImg.getHeight(); y++)
00323     for(int x=0; x<retImg.getWidth(); x++)
00324     {
00325       int val = (int)retImg.getVal(x,y);
00326       if (val < t)
00327         retImg.setVal(x,y,0);
00328       else
00329         retImg.setVal(x,y,255.0);
00330 
00331     }
00332 
00333 
00334   return retImg;
00335 }
00336 
00337 float entropy (float *h, int a, float p)
00338 {
00339         if (h[a] > 0.0 && p>0.0)
00340           return -(h[a]/p * (float)log((double)(h[a])/p));
00341         return 0.0;
00342 }
00343 
00344 
00345 Image<float> segment(const Image<float> &img)
00346 {
00347   Image<float> retImg = img;
00348   float hist[300];
00349   float pt[300];
00350   float F[300];
00351 
00352   inplaceNormalize(retImg, 0.0F, 255.0F);
00353 
00354   for(int i=0; i<256; i++)
00355   {
00356     hist[i] = 0; //set histogram to 0
00357     pt[i] = 0; //set prob to 0
00358   }
00359 
00360   for (int y=0; y<retImg.getHeight(); y++)
00361     for(int x=0; x<retImg.getWidth(); x++)
00362     {
00363       int val = (int)retImg.getVal(x,y);
00364       hist[val]++;
00365     }
00366 
00367   //nomalize into a distribution
00368   for (int i=0; i<256; i++)
00369     hist[i] = (float)hist[i]/(float)retImg.getSize();
00370 
00371   //compute factors
00372   pt[0] = hist[0];
00373   for(int i=1; i<256; i++)
00374     pt[i] = pt[i-1] + hist[i];
00375 
00376   int t = -1;
00377 
00378   for(int i=0; i<256; i++)
00379   {
00380     float Hb = 0, Hw = 0;
00381     for(int j=0; j<256; j++)
00382       if (j<=i)
00383         Hb += entropy(hist, j, pt[i]);
00384       else
00385         Hw += entropy(hist, j, 1.0-pt[i]);
00386     F[i] = Hb+Hw;
00387     if (i>0 && F[i] > F[t]) t = i;
00388   }
00389   if (t < 0)
00390     LINFO("ERROR");
00391   else
00392     LINFO("THreshold is %i", t);
00393 
00394   //threshold
00395   for (int y=0; y<retImg.getHeight(); y++)
00396     for(int x=0; x<retImg.getWidth(); x++)
00397     {
00398       int val = (int)retImg.getVal(x,y);
00399       if (val < t)
00400         retImg.setVal(x,y,0);
00401       else
00402         retImg.setVal(x,y,255.0);
00403 
00404     }
00405 
00406 
00407   return retImg;
00408 }
00409 
00410 
00411 
00412 int main(const int argc, const char **argv)
00413 {
00414 
00415   MYLOGVERB = LOG_INFO;
00416   mgr = new ModelManager("Test ObjRec");
00417 
00418   nub::ref<InputFrameSeries> ifs(new InputFrameSeries(*mgr));
00419   mgr->addSubComponent(ifs);
00420 
00421   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr));
00422   mgr->addSubComponent(ofs);
00423 
00424   nub::ref<EnvVisualCortex> evc(new EnvVisualCortex(*mgr));
00425   mgr->addSubComponent(evc);
00426 
00427   mgr->exportOptions(MC_RECURSE);
00428   //mgr->setOptionValString(&OPT_EvcMaxnormType, "None");
00429   //mgr->setOptionValString(&OPT_EvcLevelSpec, "0,2,5,6,0");
00430   //mgr->setOptionValString(&OPT_EvcLevelSpec, "0,4,1,4,0");
00431   //mgr->setOptionValString(&OPT_EvcLevelSpec, "0,2,3,4,2");
00432   //mgr->setOptionValString(&OPT_EvcLevelSpec, "0,1,8,8,0");
00433 
00434 
00435   //evc->setIweight(0);
00436   evc->setFweight(0);
00437   evc->setMweight(0);
00438   evc->setCweight(0);
00439   evc->setOweight(0);
00440 
00441   if (mgr->parseCommandLine(
00442         (const int)argc, (const char**)argv, "image", 0, 0) == false)
00443     return 1;
00444 
00445   mgr->start();
00446 
00447   // do post-command-line configs:
00448 
00449   //start streaming
00450   ifs->startStream();
00451 
00452   //build the sin/cos tables
00453   float ang;
00454   int i;
00455   for(ang =0,i=0; i < 180; ang += CV_PI/180, i++)
00456   {
00457     tabSin[i] = (float)(sin(ang));
00458     tabCos[i] = (float)(cos(ang));
00459   }
00460 
00461   while(1)
00462   {
00463     Image< PixRGB<byte> > inputImg;
00464     const FrameState is = ifs->updateNext();
00465     LINFO("Frame %i\n", ifs->frame());
00466     if (is == FRAME_COMPLETE)
00467       break;
00468 
00469     //grab the images
00470     GenericFrame input = ifs->readFrame();
00471     if (!input.initialized())
00472       break;
00473     inputImg = input.asRgb();
00474 
00475     int fw = 100;
00476     Image<PixRGB<byte> > fimg = crop(inputImg,
00477         Point2D<int>((inputImg.getWidth()/2)-(fw/2), (inputImg.getHeight()/2)-(fw/2)), Dims(fw,fw));
00478   //  SHOWIMG(rescale(inputImg, 512, 512));
00479 
00480     //evc->setSubmapPostNormProc(&biasProc);
00481     //evc->setSubmapPreProc(&biasProc);
00482     //evc->setSubmapPostProc(NULL);
00483 
00484     fimg = rescale(fimg, inputImg.getDims());
00485     evc->input(fimg);
00486 
00487     Image<float> vcxMap = evc->getVCXmap();
00488     Image<float> lum = luminance(fimg);
00489 
00490 
00491     vcxMap = rescale(vcxMap, inputImg.getDims());
00492     lum = rescale(lum, inputImg.getDims());
00493 
00494     Image<float> mag, ori;
00495     gradientSobel(lum, mag, ori, 3);
00496     //inplaceNormalize(vcxMap, 0.0F, 255.0F);
00497     //inplaceNormalize(mag, 0.0F, 255.0F);
00498     mag = (vcxMap);
00499 
00500 
00501     Image<float> seg = segment(mag);
00502 
00503     gradientSobel(lum, mag, ori, 3);
00504     lum =mag;
00505 
00506     Image<PixRGB<byte> > salHoughDisp;
00507     Image<PixRGB<byte> > opencvHoughDisp;
00508 
00509     //calculate the hough
00510     Image<float> acc = houghTrans(mag, ori, vcxMap);
00511 
00512     //show the lines
00513     salHoughDisp = showHough(acc, mag);
00514 
00515 
00516 
00517 #ifdef SALIENCY_HOUGH
00518     Image<float> mag, ori;
00519     gradientSobel(vcxMap, mag, ori, 3);
00520     mag *= vcxMap; //weight the orientations by the saliency
00521     inplaceNormalize(mag, 0.0F, 255.0F);
00522 
00523     //calculate the hough
00524     Image<float> acc = houghTrans(mag, ori, vcxMap);
00525 
00526     //show the lines
00527     salHoughDisp = showHough(acc, mag);
00528 #endif
00529 
00530 #ifdef OPENCV_HOUGH
00531 
00532     //Opencv hough
00533     inplaceNormalize(lum, 0.0F, 255.0F);
00534     CvMemStorage* storage = cvCreateMemStorage(0);
00535     IplImage *dst = cvCreateImage( cvGetSize(img2ipl(lum)), 8, 1 );
00536     cvCanny( img2ipl((Image<byte>)lum), dst, 150, 200, 3 );
00537 
00538     Image<float> edge = ipl2float(dst);
00539     opencvHoughDisp = edge;
00540 
00541     /*CvSeq *lines = cvHoughLines2(dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 50 , 0, 0);
00542 
00543     for(int i = 0; i < MIN(lines->total,10); i++ )
00544     {
00545     ccb
00546       float rho = line[0];
00547       float theta = line[1];
00548       CvPoint pt1, pt2;
00549       double a = cos(theta), b = sin(theta);
00550       double x0 = a*rho, y0 = b*rho;
00551       pt1.x = cvRound(x0 + 1000*(-b));
00552       pt1.y = cvRound(y0 + 1000*(a));
00553       pt2.x = cvRound(x0 - 1000*(-b));
00554       pt2.y = cvRound(y0 - 1000*(a));
00555 
00556       drawLine(opencvHoughDisp, Point2D<int>(pt1.x,pt1.y), Point2D<int>(pt2.x, pt2.y), PixRGB<byte>(255,0,0));
00557     }*/
00558 
00559 
00560     CvSeq *lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 10, 5, 1 );
00561     for( i = 0; i < lines->total; i++ )
00562     {
00563         CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
00564         drawLine(opencvHoughDisp, Point2D<int>(line[0].x,line[0].y), Point2D<int>(line[1].x, line[1].y), PixRGB<byte>(255,0,0));
00565     }
00566 
00567 #endif
00568 
00569 
00570     display(inputImg, vcxMap, lum, Point2D<int>(-1, -1), 2, Point2D<int>(-1, -1), ofs);
00571 
00572 
00573   }
00574 
00575 
00576 
00577   // stop all our ModelComponents
00578   mgr->stop();
00579 
00580   return 0;
00581 
00582 }
00583 
00584 
00585 void display(Image<PixRGB<byte> > &leftImg,
00586     const Image<PixRGB<byte> > &leftSmap,
00587     const Image<PixRGB<byte> > &hough,
00588     const Point2D<int> &leftWinner,
00589     const byte maxVal,
00590     const Point2D<int> &targetLoc,
00591     nub::ref<OutputFrameSeries> ofs)
00592 {
00593   static int avgn = 0;
00594   static uint64 avgtime = 0;
00595   static double fps = 0;
00596   char msg[255];
00597 
00598   Image<PixRGB<byte> > outDisp(leftImg.getWidth()*2,leftImg.getHeight()*2+20, ZEROS);
00599 
00600 
00601   //Left Image
00602   inplacePaste(outDisp, leftImg, Point2D<int>(0,0));
00603   inplacePaste(outDisp, leftSmap, Point2D<int>(0,leftImg.getHeight()));
00604   inplacePaste(outDisp, hough, Point2D<int>(leftImg.getWidth(),leftImg.getHeight()));
00605 
00606 
00607   //calculate fps
00608   avgn++;
00609   avgtime += timer.getReset();
00610   if (avgn == 20)
00611   {
00612     fps = 1000.0F / double(avgtime) * double(avgn);
00613     avgtime = 0;
00614     avgn = 0;
00615   }
00616 
00617   sprintf(msg, "%.1ffps ", fps);
00618 
00619   Image<PixRGB<byte> > infoImg(leftImg.getWidth()*2, 20, NO_INIT);
00620   writeText(infoImg, Point2D<int>(0,0), msg,
00621         PixRGB<byte>(255), PixRGB<byte>(127));
00622   inplacePaste(outDisp, infoImg, Point2D<int>(0,leftImg.getHeight()*2));
00623 
00624   ofs->writeRGB(outDisp, "output", FrameInfo("output", SRC_POS));
00625 }
00626 
00627 
Generated on Sun May 8 08:05:30 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3