test-FOEopticFlow.C

Go to the documentation of this file.
00001 
00002 /*!@file Robots/Beobot2/Navigation/FOE_Navigation/test-FOEopticFlow.C
00003   find the optic flow (Shi Tomasi) and the focus of expansion (Perrone 1992) */
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: Christian Siagian <siagian@usc.edu>
00035 // $HeadURL: $
00036 // $Id: $
00037 
00038 //
00039 
00040 #define MAX_CORNERS        500   
00041 
00042 // OpenCV must be first to avoid conflicting defs of int64, uint64
00043 #include "Image/OpenCVUtil.H"
00044 
00045 #include <cstdio>
00046 
00047 #include "Component/ModelManager.H"
00048 #include "Media/FrameSeries.H"
00049 
00050 #include "Image/Image.H"
00051 #include "Image/CutPaste.H"
00052 #include "Image/ColorOps.H"
00053 #include "Image/MathOps.H"
00054 #include "Image/ShapeOps.H"
00055 #include "Image/Pixels.H"
00056 #include "Raster/Raster.H"
00057 
00058 #include "SIFT/Keypoint.H"
00059 #include "SIFT/VisualObject.H"
00060 #include "SIFT/VisualObjectMatch.H"
00061 
00062 
00063 #include "Util/Timer.H"
00064 
00065 #include "Robots/Beobot2/Navigation/FOE_Navigation/FoeDetector.H"
00066 #include "Robots/Beobot2/Navigation/FOE_Navigation/MotionOps.H"
00067 
00068 // return the optic flow
00069 //Image<float> getOpticFlow(Image<byte> image1, Image<byte> image2);
00070 Image<float> getOpticFlow2(Image<float> image1, Image<float> image2);
00071 
00072 // get the ground truth
00073 std::vector<Point2D<int> > getGT(std::string gtFilename);
00074 
00075 Image<byte>  calculateShift
00076 (Image<byte> prevLum, Image<byte> lum, nub::ref<OutputFrameSeries> ofs);
00077 
00078 Image<byte> shiftImage(SIFTaffine aff, Image<byte> ref, Image<byte> tst);
00079 
00080 std::vector<std::vector<Point2D<int> > > getGTandData();
00081 
00082 // ######################################################################
00083 int main(const int argc, const char **argv)
00084 {
00085   MYLOGVERB = LOG_INFO;  // suppress debug messages
00086 
00087   // instantiate a model manager:
00088   ModelManager manager("Test Optic Flow");
00089 
00090   nub::ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00091   manager.addSubComponent(ifs);
00092 
00093   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00094   manager.addSubComponent(ofs);
00095 
00096   nub::ref<FoeDetector> fd(new FoeDetector(manager));
00097   manager.addSubComponent(fd);
00098 
00099   manager.exportOptions(MC_RECURSE);
00100 
00101   if (manager.parseCommandLine((const int)argc, (const char**)argv,
00102                                "", 0, 0) == false)
00103     return(1);
00104 
00105   // get some options
00106   // if(manager.numExtraArgs() >  0)
00107   //   {
00108   //     outFilename = manager.getExtraArg(0);
00109   //     LINFO("save to: %s", outFilename.c_str());
00110   //   }
00111 
00112   // get ground truth file 
00113   //std::string gtFilename
00114   //  ("/lab/tmpib/u/siagian/neuroscience/Data/FOE/driving_nat_3.txt");
00115   //std::vector<Point2D<int> > gt = getGT(gtFilename);
00116   //int ldpos = gtFilename.find_last_of('.');
00117   //std::string prefix = gtFilename.substr(0, ldpos);
00118 
00119   std::string pprefix
00120     ("/lab/tmpib/u/siagian/neuroscience/Data/FOE/driving_nat_3");
00121 
00122   std::string folder("/lab/tmpib/u/siagian/neuroscience/Data/FOE/");
00123   std::string ciofmPrefix("DARPA_nv2_2011/Germany_K_CIOFM/SalMap_CIOFM");
00124   std::string ciofsPrefix("DARPA_nv2_2011/Germany_K_CIOFs/SalMap_CIOFs");
00125 
00126   // let's do it!
00127   manager.start();
00128 
00129   Timer timer(1000000);
00130   timer.reset();  // reset the timer
00131   int frame = 0;
00132   bool keepGoing = true;
00133 
00134   const FrameState is = ifs->updateNext();
00135   Image< PixRGB<byte> > prevImage;
00136   if (is == FRAME_COMPLETE) keepGoing = false;
00137   else prevImage = ifs->readRGB();
00138 
00139   uint width  = prevImage.getWidth();
00140   uint height = prevImage.getHeight();
00141 
00142   // for finding ground truth
00143   rutz::shared_ptr<XWinManaged> win
00144     (new XWinManaged(Dims(width, height), 0, 0, "GT"));
00145 
00146   // GROUND TRUTH 1
00147   //float totalErr = 0.0;
00148   // Image<PixRGB<byte> > d1 =prevImage;
00149   // win->drawImage(d1,0,0);
00150   // LINFO("please click for initial FOE location");
00151   // Raster::waitForKey();
00152   // Point2D<int> pt1 = win->getLastMouseClick();
00153   // LINFO("initial point: [%3d]: %d %d", frame, pt1.i, pt1.j);
00154   // drawCross(d1, pt1, PixRGB<byte>(255,0,0), 10, 2);
00155   // win->drawImage(d1,0,0);
00156   // Raster::waitForKey();
00157   // Point2D<int> lastPt = pt1;
00158 
00159   //std::vector<std::vector<Point2D<int> > > foePts =
00160   //  getGTandData();
00161   //Raster::waitForKey();
00162   // std::vector<PixRGB<byte> > colors(foePts.size());
00163   // colors[0] = PixRGB<byte>(255,   0,   0);
00164   // colors[1] = PixRGB<byte>(  0, 255,   0);
00165   // colors[2] = PixRGB<byte>(  0,   0, 255);
00166   // colors[3] = PixRGB<byte>(255, 255,   0);
00167 
00168   Image<byte> prevLum = Image<byte>(luminance(prevImage));
00169   win->setDims(Dims(640,720));
00170   while (keepGoing)
00171     {
00172       if (ofs->becameVoid())
00173         {
00174           LINFO("quitting because output stream was closed or became void");
00175           break;
00176         }
00177 
00178       const FrameState is = ifs->updateNext();
00179       if (is == FRAME_COMPLETE) break; // done receiving frames
00180 
00181       Image< PixRGB<byte> > currImage = ifs->readRGB();
00182       Image<byte> lum = Image<byte>(luminance(currImage));
00183 
00184       // saliency map result
00185      
00186       Image< PixRGB<byte> > ciofm = Raster::ReadRGB
00187         (folder+sformat("%s_%06d.ppm", ciofmPrefix.c_str(), frame));
00188       Image< PixRGB<byte> > ciofs = Raster::ReadRGB
00189         (folder+sformat("%s_%06d.ppm", ciofsPrefix.c_str(), frame));
00190 
00191       Image< PixRGB<byte> > salImg(640,720,ZEROS);
00192       inplacePaste(salImg, zoomXY(prevImage,2), Point2D<int>(0,0));
00193       inplacePaste(salImg, ciofm, Point2D<int>(0  ,480));
00194       inplacePaste(salImg, ciofs, Point2D<int>(320,480));
00195 
00196       drawLine(salImg, Point2D<int>(0,480), Point2D<int>(640,480), 
00197                PixRGB<byte>(255,255,255), 3);
00198       drawLine(salImg, Point2D<int>(320,480), Point2D<int>(320,720), 
00199                PixRGB<byte>(255,255,255), 3);
00200 
00201       win->drawImage(salImg,0,0); 
00202       Raster::waitForKey();
00203     
00204       Raster::WriteRGB
00205         (salImg, sformat("%s_res_%06d.ppm", pprefix.c_str(), frame));
00206 
00207       Raster::waitForKey();
00208 
00209       // =====================================================
00210       // Ground truthing
00211       // Image< PixRGB<byte> > dispGT = prevImage;
00212       // //drawCross(dispGT, gt[frame], PixRGB<byte>(0,255,0), 10, 2);
00213       // //LINFO("[%3d]: %d %d", frame, gt[frame].i, gt[frame].j);
00214       // //win->drawImage(dispGT,0,0);
00215       // //Raster::waitForKey();
00216 
00217       // Point2D<int> pt = win->getLastMouseClick();
00218       // while(!pt.isValid()) 
00219       //   pt = win->getLastMouseClick();
00220       // if(pt.isValid() && !(pt == lastPt)) lastPt = pt;
00221 
00222       // LINFO("[%3d]: pt %d %d", frame, pt.i, pt.j);
00223       // drawCross(dispGT, lastPt, PixRGB<byte>(255,0,0), 10, 2);
00224       // win->drawImage(dispGT,0,0);
00225 
00226       // FILE *gtfp; 
00227       // LINFO("[%3d] gt file: %s: %d %d", 
00228       //       frame, gtFilename.c_str(), lastPt.i, lastPt.j);
00229       // if((gtfp = fopen(gtFilename.c_str(),"at")) == NULL)
00230       //   LFATAL("not found");
00231       // fputs(sformat("%d %d \n", lastPt.i, lastPt.j).c_str(), gtfp);
00232       // fclose (gtfp);
00233 
00234 
00235       // for performance display
00236       // Image<PixRGB<byte> > pimg = prevImage;
00237       // for(uint i = 0; i < foePts.size(); i++)
00238       //   {
00239       //     if(!(foePts[i][frame].i == -1 && foePts[i][frame].j == -1)) 
00240       //       drawCross(pimg, foePts[i][frame], colors[i], 10, 2);
00241       //   }
00242       // Raster::WriteRGB(pimg, sformat("%s_res_%06d.ppm", pprefix.c_str(), frame));
00243       // ofs->writeRGB(pimg, "Performance");
00244       // Raster::waitForKey();
00245 
00246       // =====================================================
00247 
00248       // calculate planar shift using SIFT 
00249       //lum = calculateShift(prevLum, lum, ofs);
00250 
00251       // compute the optic flow
00252       //rutz::shared_ptr<OpticalFlow> flow =
00253       //  getLucasKanadeOpticFlow
00254       //(Image<byte>(luminance(prevImage)), 
00255       //Image<byte>(luminance(currImage)));
00256 
00257       // rutz::shared_ptr<OpticalFlow> flow =
00258       //   getLucasKanadeOpticFlow(prevLum, lum);
00259       // Image<PixRGB<byte> > opticFlow = drawOpticFlow(prevImage, flow);
00260       // Image< PixRGB<byte> > disp(4*width, height, ZEROS);
00261       // inplacePaste(disp, prevImage, Point2D<int>(0    ,0));
00262       // inplacePaste(disp, currImage, Point2D<int>(width,0));
00263 
00264       // // compute the focus of expansion (FOE)
00265       // Point2D<int> foe = 
00266       //   fd->getFoe(flow, FOE_METHOD_AVERAGE, false);
00267       // //fd->getFoe(flow, FOE_METHOD_TEMPLATE);
00268       // float err = foe.distance(gt[frame]); 
00269       // totalErr += err;
00270       // LINFO("Foe: %d %d: GT: %d %d --> %f --> avg: %f", 
00271       //       foe.i, foe.j, gt[frame].i, gt[frame].j, 
00272       //       err, totalErr/(frame+1));
00273 
00274 
00275       // drawCross(opticFlow, foe      , PixRGB<byte>(0,255,0), 10, 2);
00276       // //drawCross(opticFlow, gt[frame], PixRGB<byte>(255,0,0), 10, 2);
00277       // Image<float> foem = fd->getFoeMap();
00278 
00279       // inplacePaste(disp, opticFlow, Point2D<int>(width*2,0));
00280       // inplaceNormalize(foem, 0.0F, 255.0F);
00281       // inplacePaste(disp, toRGB(zoomXY(Image<byte>(foem),MAX_NEIGHBORHOOD)), 
00282       //              Point2D<int>(width*3,0));
00283       // ofs->writeRGB(disp, "Optic Flow");
00284       // const FrameState os = ofs->updateNext();
00285 
00286       // // write the file
00287       // //Image<PixRGB<byte> > simg = prevImage;
00288       // //drawCross(simg, foe      , PixRGB<byte>(0,255,0), 10, 2);
00289       // //drawCross(simg, gt[frame], PixRGB<byte>(255,0,0), 10, 2);
00290       // //Raster::WriteRGB(simg, sformat("%s_%06d.ppm", prefix.c_str(), frame));
00291 
00292       // //Raster::waitForKey();
00293 
00294       // if (os == FRAME_FINAL)
00295       //   break;
00296 
00297       prevImage = currImage;
00298       prevLum   = lum;
00299       frame++;
00300 
00301       //FILE *fp;      
00302       //LINFO("FOE %d %d", foe.i, foe.j);
00303       //if((fp = fopen("LK_CB_Germany.txt","at")) == NULL) LFATAL("not found");
00304       //fputs(sformat("%d %d \n", foe.i, foe.j).c_str(), fp);
00305       //fclose (fp);  
00306 
00307     }
00308 
00309   //LINFO("%d frames in %gs (%.2ffps)\n", 
00310   //      frame, timer.getSecs(), frame / timer.getSecs());
00311 
00312   // stop all our ModelComponents
00313   manager.stop();
00314 
00315   // all done!
00316   return 0;
00317 
00318 }
00319 
00320 // ######################################################################
00321 std::vector<std::vector<Point2D<int> > > getGTandData()
00322 {
00323   uint nSystems = 3;
00324   std::vector<std::vector<Point2D<int> > > data(nSystems+1);
00325 
00326   std::string folder("/lab/tmpib/u/siagian/neuroscience/Data/FOE/");
00327 
00328   // Browning
00329   // std::string gt("driving_nat_Browning_2.txt");
00330   // std::string f1("DARPA_nv2_2011/Browning_K_CIOFs/ST_PS_Browning.txt");
00331   // std::string f2("DARPA_nv2_2011/Browning_K_CIOFs/BMG_Browning.txt");
00332   // std::string f3("DARPA_nv2_2011/Browning_K_CIOFs/LK_CB_Browning.txt");
00333 
00334   // Las Vegas
00335   // std::string gt("driving_nat_2b_1.txt");
00336   // std::string f1("DARPA_nv2_2011/LasVegas_K_CIOFs/ST_PS_LasVegas.txt");
00337   // std::string f2("DARPA_nv2_2011/LasVegas_K_CIOFs/BMG_LasVegas.txt");
00338   // std::string f3("DARPA_nv2_2011/LasVegas_K_CIOFs/LK_CB_LasVegas.txt");
00339   
00340   // Germany  
00341   std::string gt("driving_nat_3_1.txt");
00342   std::string f1("DARPA_nv2_2011/Germany_K_CIOFs/ST_PS_Germany.txt");
00343   std::string f2("DARPA_nv2_2011/Germany_K_CIOFs/BMG_Germany.txt");
00344   std::string f3("DARPA_nv2_2011/Germany_K_CIOFs/LK_CB_Germany.txt");
00345 
00346 
00347   // get data
00348   data[0] = getGT(folder+gt);
00349   data[1] = getGT(folder+f1);
00350   data[2] = getGT(folder+f2);
00351   data[3] = getGT(folder+f3);
00352 
00353   // calculate errors as well
00354   for(uint i = 1; i < nSystems+1; i++) 
00355     {
00356       float totalErr = 0.0;
00357       uint totalPt = 0;
00358       for(uint j = 0; j < data[i].size(); j++)
00359         {
00360           // if systems is not ready 
00361           // just skip the point
00362           if(data[i][j].i == -1 && data[i][j].j == -1)
00363             continue;
00364               
00365           // if point is out of bounds just move it to the closest edge
00366           // also change the data
00367           Point2D<int> newPt = data[i][j];          
00368           if(newPt.i <    0) newPt.i =   0;
00369           if(newPt.i >= 320) newPt.i = 319;
00370           if(newPt.j <    0) newPt.j =   0;
00371           if(newPt.j >= 320) newPt.j = 319;
00372           data[i][j] = newPt;
00373           
00374           // compare with ground truth
00375           float err = newPt.distance(data[0][j]);
00376           
00377           LDEBUG("[%3d %3d] - [%3d %3d]: %f",
00378                  newPt.i, newPt.j, data[0][j].i, data[0][j].j,
00379                  err);
00380   
00381           totalErr += err; 
00382           totalPt++;
00383         }
00384  
00385       if(totalPt == 0) LINFO("s[%3d] err: 0/0 = 0", i);
00386       else
00387         LINFO("s[%3d] err: %f/%d = %f", 
00388               i, totalErr, totalPt, totalErr/totalPt);
00389     }
00390   return data;
00391 }
00392 
00393 // ######################################################################
00394 std::vector<Point2D<int> > getGT(std::string gtFilename)
00395 {
00396   std::vector<Point2D<int> > gt;
00397 
00398   FILE *fp;  char inLine[200]; //char comment[200];
00399 
00400   LINFO("ground truth file: %s",gtFilename.c_str());
00401   if((fp = fopen(gtFilename.c_str(),"rb")) == NULL)
00402     { LINFO("not found"); return gt; }
00403 
00404   // populate the trial information
00405   uint nFrames = 0;
00406   while(fgets(inLine, 200, fp) != NULL)
00407     {
00408       int x, y;
00409       sscanf(inLine, "%d %d", &x, &y);      
00410       LINFO("[%3d] x: %d y: %d", nFrames, x, y);
00411       gt.push_back(Point2D<int>(x,y));
00412 
00413       nFrames++;
00414     }
00415   Raster::waitForKey();
00416   return gt;
00417 }
00418 
00419 // ######################################################################
00420 Image<float> getOpticFlow2(Image<float> image1, Image<float> image2)
00421 {
00422 
00423   // Load two images and allocate other structures
00424   inplaceNormalize(image1, 0.0F, 255.0F);
00425   Image<byte> img1(image1);
00426   IplImage* imgA = img2ipl(img1); 
00427   inplaceNormalize(image2, 0.0F, 255.0F);
00428   Image<byte> img2(image2);
00429   IplImage* imgB = img2ipl(img2);
00430 
00431   CvSize img_sz = cvGetSize( imgA );
00432   int win_size = 15;
00433   
00434   IplImage* imgC =img2ipl(img1);
00435 
00436   // Get the features for tracking
00437   IplImage* eig_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );
00438   IplImage* tmp_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );
00439   
00440   int corner_count = MAX_CORNERS;
00441   CvPoint2D32f* cornersA = new CvPoint2D32f[ MAX_CORNERS ];
00442   
00443   cvGoodFeaturesToTrack( imgA, eig_image, tmp_image, 
00444                          cornersA, &corner_count,
00445                          0.05, 5.0, 0, 3, 0, 0.04 );
00446   
00447 
00448   cvFindCornerSubPix( imgA, cornersA, corner_count, 
00449                       cvSize( win_size, win_size ),
00450                       cvSize( -1, -1 ), 
00451                       cvTermCriteria( CV_TERMCRIT_ITER | 
00452                                       CV_TERMCRIT_EPS, 20, 0.03 ) );
00453   
00454   // Call Lucas Kanade algorithm
00455   char features_found[ MAX_CORNERS ];
00456   float feature_errors[ MAX_CORNERS ];
00457   
00458   CvSize pyr_sz = cvSize( imgA->width+8, imgB->height/3 );
00459   
00460   IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );
00461   IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );
00462   
00463   CvPoint2D32f* cornersB = new CvPoint2D32f[ MAX_CORNERS ];
00464   
00465   cvCalcOpticalFlowPyrLK( imgA, imgB, pyrA, pyrB, 
00466                           cornersA, cornersB, corner_count, 
00467                           cvSize( win_size, win_size ), 5, 
00468                           features_found, feature_errors,
00469                           cvTermCriteria( CV_TERMCRIT_ITER | 
00470                                           CV_TERMCRIT_EPS, 20, 0.3 ), 0 );
00471   
00472   // Make an image of the results
00473   
00474   for( int i=0; i < MAX_CORNERS; i++ )
00475     {
00476       LINFO("Error is %f/n", feature_errors[i]);
00477       //continue;
00478 
00479       //printf("Got it/n");
00480       CvPoint p0 = cvPoint( cvRound( cornersA[i].x ), 
00481                             cvRound( cornersA[i].y ) );
00482       CvPoint p1 = cvPoint( cvRound( cornersB[i].x ), 
00483                             cvRound( cornersB[i].y ) );
00484       cvLine( imgC, p0, p1, CV_RGB(255,0,0), 2 );
00485     }
00486 
00487   return ipl2gray(imgC);
00488 }
00489 
00490 // ######################################################################
00491 Image<byte> calculateShift(Image<byte> prevLum, Image<byte> lum,
00492                            nub::ref<OutputFrameSeries> ofs)
00493 {
00494   VisualObjectMatchAlgo voma(VOMA_SIMPLE);
00495 //   if (strcmp(argv[1], "KDTree") == 0) voma = VOMA_KDTREE;
00496 //   else if (strcmp(argv[1], "KDBBF") == 0) voma = VOMA_KDTREEBBF;
00497 //   else if (strcmp(argv[1], "Simple") != 0)
00498 //     LFATAL("Unknown matching method %s", argv[0]);
00499 
00500   // create visual objects:
00501   rutz::shared_ptr<VisualObject> vo1(new VisualObject("plum", "", prevLum));
00502   rutz::shared_ptr<VisualObject> vo2(new VisualObject("lum" , "", lum));
00503 
00504   // compute the matching keypoints:
00505   VisualObjectMatch match(vo1, vo2, voma);
00506   LDEBUG("Found %u matches", match.size());
00507 
00508   // let's prune the matches:
00509   uint np = match.prune();
00510   LDEBUG("Pruned %u outlier matches.", np);
00511 
00512   // show our final affine transform:
00513   SIFTaffine s = match.getSIFTaffine();
00514   LDEBUG("[tstX]   [ %- .3f %- .3f ] [refX]   [%- .3f]", s.m1, s.m2, s.tx);
00515   LDEBUG("[tstY] = [ %- .3f %- .3f ] [refY] + [%- .3f]", s.m3, s.m4, s.ty);
00516 
00517 
00518   LDEBUG("getKeypointAvgDist = %f", match.getKeypointAvgDist());
00519   LDEBUG("getAffineAvgDist = %f",   match.getAffineAvgDist());
00520   LDEBUG("getScore = %f", match.getScore());
00521 
00522   if (match.checkSIFTaffine() == false)
00523     LINFO("### Affine is too weird -- BOGUS MATCH");
00524 
00525   // get an image showing the matches:
00526   Image< PixRGB<byte> > mimg = match.getMatchImage(1.0F);
00527   Image< PixRGB<byte> > fimg = match.getFusedImage(0.25F);
00528 
00529   // LINFO("prevLum");
00530   // ofs->writeRGB
00531   //   (toRGB(prevLum), "test-FOE Main", FrameInfo("foe output", SRC_POS));
00532   // Raster::waitForKey();
00533 
00534   // LINFO("lum");
00535   // ofs->writeRGB
00536   //   (toRGB(lum), "test-FOE Main", FrameInfo("foe output", SRC_POS));
00537   // Raster::waitForKey();
00538 
00539   LINFO("Shift: %f %f", s.tx, s.ty);
00540   // ofs->writeRGB
00541   //   (fimg, "test-FOE Main", FrameInfo("foe output", SRC_POS));
00542   // Raster::waitForKey();
00543 
00544   Image<byte> res = shiftImage(s, prevLum, lum);
00545 
00546   // LINFO("shifted result");
00547   // ofs->writeRGB
00548   //   (toRGB(res), "test-FOE Main", FrameInfo("foe output", SRC_POS));
00549   // Raster::waitForKey();
00550 
00551   //Point2D<float> shift(s.tx,s.ty);
00552   return res;
00553 }
00554 
00555 // ######################################################################
00556  Image<byte> shiftImage(SIFTaffine aff, Image<byte> refi, Image<byte> tsti)
00557 {
00558   // we loop over all pixel locations in the ref image, transform the
00559   // coordinates using the forward affine transform, get the pixel
00560   // value in the test image, and mix:
00561 
00562   uint w = refi.getWidth(), h = refi.getHeight();
00563   Image<byte> result(w, h, ZEROS);
00564   Image<byte>::const_iterator rptr = refi.begin();
00565   Image<byte>::iterator dptr = result.beginw();
00566 
00567   for (uint j = 0; j < h; j ++)
00568     for (uint i = 0; i < w; i ++)
00569       {
00570         float u, v;
00571         aff.transform(float(i), float(j), u, v);
00572         byte rval = *rptr++;
00573 
00574         if (tsti.coordsOk(u, v))
00575           {
00576             byte tval = tsti.getValInterp(u, v);
00577             //PixRGB<byte> mval = PixRGB<byte>(rval * mix + tval * (1.0F - mix));
00578             *dptr++ = tval;
00579           }
00580         else
00581           //*dptr++ = PixRGB<byte>(rval * mix);
00582           *dptr++ = byte(rval);
00583       }
00584 
00585   return result; 
00586  }
00587 
00588 // ######################################################################
00589 /* So things look consistent in everyone's emacs... */
00590 /* Local Variables: */
00591 /* indent-tabs-mode: nil */
00592 /* End: */
Generated on Sun May 8 08:41:18 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3