00001 /*! @file ObjRec/test-LabelMeSaliency.C get saliency information from */ 00002 /* the label me data set */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00006 // by the 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: Lior Elazary <elazary@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/ObjRec/test-LabelMeSaliency.C $ 00036 // $Id: test-LabelMeSaliency.C 10982 2009-03-05 05:11:22Z itti $ 00037 // 00038 00039 00040 #include "Component/ModelManager.H" 00041 #include "Image/Image.H" 00042 #include "Image/ImageSet.H" 00043 #include "Image/ShapeOps.H" 00044 #include "Image/DrawOps.H" 00045 #include "Image/FilterOps.H" 00046 #include "Image/ColorOps.H" 00047 #include "Image/Transforms.H" 00048 #include "Image/MathOps.H" 00049 #include "Neuro/StdBrain.H" 00050 #include "Neuro/VisualCortex.H" 00051 #include "Neuro/NeuroOpts.H" 00052 #include "Neuro/NeuroSimEvents.H" 00053 #include "Neuro/TaskRelevanceMap.H" 00054 #include "Neuro/SaliencyMap.H" 00055 #include "Media/TestImages.H" 00056 #include "Media/SceneGenerator.H" 00057 #include "Media/MediaSimEvents.H" 00058 #include "Channels/DescriptorVec.H" 00059 #include "Channels/ComplexChannel.H" 00060 #include "Simulation/SimEventQueue.H" 00061 #include "Simulation/SimulationOpts.H" 00062 #include "Simulation/SimEventQueueConfigurator.H" 00063 #include "Channels/SubmapAlgorithmBiased.H" 00064 #include "GUI/DebugWin.H" 00065 #include "ObjRec/MaskBiaser.H" 00066 00067 00068 00069 Point2D<int> evolveBrain(Image<PixRGB<byte> > &img, Image<float> &SMap, float *interestLevel, 00070 nub::soft_ref<SimEventQueue> seq); 00071 00072 ModelManager *mgr; 00073 void biasVC(ComplexChannel &vc, Image<float> &mask); 00074 bool debug = 1; 00075 int main(const int argc, const char **argv) 00076 { 00077 00078 MYLOGVERB = LOG_INFO; 00079 mgr = new ModelManager("Test LabelMeSaliency"); 00080 00081 nub::soft_ref<SimEventQueueConfigurator> 00082 seqc(new SimEventQueueConfigurator(*mgr)); 00083 mgr->addSubComponent(seqc); 00084 00085 //our brain 00086 nub::ref<StdBrain> brain(new StdBrain(*mgr)); 00087 mgr->addSubComponent(brain); 00088 00089 00090 mgr->exportOptions(MC_RECURSE); 00091 mgr->setOptionValString(&OPT_RawVisualCortexChans, "IOC"); 00092 //mgr.setOptionValString(&OPT_RawVisualCortexChans, "I"); 00093 //mgr->setOptionValString(&OPT_RawVisualCortexChans, "GNO"); 00094 //mgr.setOptionValString(&OPT_RawVisualCortexChans, "N"); 00095 //manager.setOptionValString(&OPT_UseOlderVersion, "false"); 00096 // set the FOA and fovea radii 00097 mgr->setOptionValString(&OPT_SaliencyMapType, "Fast"); 00098 mgr->setOptionValString(&OPT_SMfastInputCoeff, "1"); 00099 00100 mgr->setOptionValString(&OPT_WinnerTakeAllType, "Fast"); 00101 mgr->setOptionValString(&OPT_SimulationTimeStep, "0.2"); 00102 00103 mgr->setModelParamVal("FOAradius", 128, MC_RECURSE); 00104 mgr->setModelParamVal("FoveaRadius", 128, MC_RECURSE); 00105 00106 mgr->setOptionValString(&OPT_IORtype, "Disc"); 00107 00108 if (mgr->parseCommandLine( 00109 (const int)argc, (const char**)argv, "<path to images>", 1, 1) == false); 00110 00111 nub::soft_ref<SimEventQueue> seq = seqc->getQ(); 00112 00113 mgr->start(); 00114 //nub::ref<StdBrain> brain = dynCastWeak<StdBrain>(mgr->subComponent("Brain")); 00115 00116 //"/lab/ilab15/tmp/objectsDB/mit/labelMe/05june05_static_indoor", 00117 00118 ComplexChannel *cc = 00119 &*dynCastWeak<ComplexChannel>(brain->getVC()); 00120 00121 TestImages testImages(mgr->getExtraArg(0).c_str(), TestImages::MIT_LABELME); 00122 00123 Image<float> allObjImg = Raster::ReadFloat("allObjImg.pfm", RASFMT_PFM); 00124 inplaceNormalize(allObjImg, 0.0F, 1.0F); 00125 00126 printf("## \"Filename\", \"Size\",\"fovea Radius\",\"Number of objects\",\"Salient Location\", \"Hits\","); 00127 printf("\"Obj Saliency Max\",\"Obj Saliency Min\",\"Obj Saliency Sum\",\"Obj Saliency Area\""); 00128 printf("\"Dist Saliency Max\",\"Dist Saliency Min\",\"Dist Saliency Sum\",\"Dist Saliency Area\""); 00129 printf("\n"); 00130 00131 for(uint scene=0; scene<testImages.getNumScenes(); scene++) 00132 { 00133 00134 //get the image 00135 LINFO("Get scene %i", scene); 00136 Image<PixRGB<byte> > img = testImages.getScene(scene); 00137 std::string sceneFile = testImages.getSceneFilename(scene); 00138 LINFO("Size %ix%i", img.getWidth(), img.getHeight()); 00139 00140 00141 //set the fovea and foa radius to be 1/4 the size of the image width 00142 int fRadius = 128; //(img.getWidth()/16); 00143 //TODO: fixme 00144 //brain->getSM()->setFoveaRadius(fRadius); 00145 //brain->getSM()->setFOAradius(fRadius); 00146 00147 initRandomNumbers(); 00148 00149 if (testImages.getNumObj() > 0) //if we have any labled objects 00150 { 00151 00152 //bias the vc 00153 Image<float> mask = rescale(allObjImg, img.getDims()); 00154 biasVC(*cc, mask); 00155 //evolve the brain 00156 00157 Image<float> SMap; 00158 00159 rutz::shared_ptr<SimEventInputFrame> //place the image in the queue 00160 e(new SimEventInputFrame(brain.get(), GenericFrame(img), 0)); 00161 seq->post(e); 00162 00163 //set the task relevance map 00164 00165 Point2D<int> winner; 00166 float interestLevel=100.0F; 00167 int nHits=0; 00168 int nTimes=95; 00169 00170 printf("[ "); 00171 Point2D<int> lastLoc(-1,-1); 00172 while(interestLevel > 0.01F && nTimes < 100) //do until no more activation 00173 { 00174 nTimes++; 00175 LINFO("InterestLevel %f", interestLevel); 00176 Point2D<int> currentWinner = evolveBrain(img, SMap, &interestLevel, seq); 00177 00178 if (debug) 00179 { 00180 if (lastLoc.isValid()) 00181 { 00182 drawLine(img, lastLoc, currentWinner, 00183 PixRGB<byte>(0, 255, 0), 4); 00184 } else { 00185 drawCircle(img, currentWinner, fRadius-10, PixRGB<byte>(255,0,0), 3); 00186 } 00187 lastLoc = currentWinner; 00188 00189 00190 drawCircle(img, currentWinner, fRadius, PixRGB<byte>(0,255,0), 3); 00191 } 00192 00193 //check if the winner is inside an object (all objects) 00194 int hit = -1; 00195 for (uint obj=0; obj<testImages.getNumObj(); obj++) 00196 { 00197 int lineWidth = int(img.getWidth()*0.003); 00198 std::vector<Point2D<int> > objPoly = testImages.getObjPolygon(obj); 00199 if (debug) 00200 { 00201 Point2D<int> p1 = objPoly[0]; 00202 for(uint i=1; i<objPoly.size(); i++) 00203 { 00204 drawLine(img, p1, objPoly[i], PixRGB<byte>(255, 0, 0), lineWidth); 00205 p1 = objPoly[i]; 00206 } 00207 drawLine(img, p1, objPoly[0], PixRGB<byte>(255, 0, 0), lineWidth); //close the polygon 00208 } 00209 00210 // if (testImages.pnpoly(objPoly, winner)) 00211 // hit = 1; 00212 if (testImages.pnpoly(objPoly, currentWinner)) 00213 { 00214 hit = obj; 00215 } 00216 00217 } 00218 printf("%i ", hit); 00219 if (hit != -1) 00220 { 00221 winner = currentWinner; 00222 nHits++; 00223 } 00224 00225 } 00226 00227 if (debug) 00228 { 00229 Raster::WriteRGB(img, "IORSaliency.ppm"); 00230 Image<PixRGB<byte> > tmp = rescale(img, 512, 512); 00231 SHOWIMG(tmp); 00232 } 00233 printf("] "); 00234 printf("\"%s\",\"%ix%i\",\"%i\",\"%i\",\"(%i,%i)\",\"%i\"", 00235 sceneFile.c_str(), img.getWidth(), img.getHeight(), fRadius, 00236 testImages.getNumObj(), winner.i, winner.j, nHits); 00237 printf("\n"); 00238 00239 if (debug) 00240 { 00241 Image<PixRGB<byte> > tmp = rescale(img, 512, 512); 00242 SHOWIMG(tmp); 00243 00244 } 00245 00246 00247 //Compute the saliency ratio 00248 /*Image<byte> imgMask; 00249 //get the obj mask 00250 for (uint obj=0; obj<testImages.getNumObj(); obj++) 00251 { 00252 LINFO("Adding obj %i", obj); 00253 Image<byte> objMask = testImages.getObjMask(obj); 00254 if (imgMask.initialized()) 00255 imgMask += objMask; 00256 else 00257 imgMask = objMask; 00258 } 00259 if (debug) SHOWIMG(rescale((Image<float>)imgMask, 512, 512)); 00260 00261 LINFO("Mask %ix%i", imgMask.getWidth(), imgMask.getHeight()); 00262 Image<float> distMask = chamfer34(imgMask, (byte)255); 00263 Image<float> objMask = binaryReverse(distMask, 255.0F); 00264 00265 //normalize mask from 0 to 1 00266 inplaceNormalize(objMask, 0.0F, 1.0F); 00267 inplaceNormalize(distMask, 0.0F, 1.0F); 00268 00269 if (debug) SHOWIMG(rescale((Image<float>)objMask, 512, 512)); 00270 if (debug) SHOWIMG(rescale((Image<float>)distMask, 512, 512)); 00271 00272 //resize the saliency map to the orig img size 00273 SMap = rescale(SMap, imgMask.getDims()); 00274 00275 float objMin, objMax, objSum, objArea; 00276 getMaskedMinMaxSumArea(SMap, objMask, objMin, objMax, objSum, objArea); 00277 00278 float distMin, distMax, distSum, distArea; 00279 getMaskedMinMaxSumArea(SMap, distMask, distMin, distMax, distSum, distArea); 00280 00281 printf("\"%f\",\"%f\",\"%f\",\"%f\",\"%f\",\"%f\",\"%f\",\"%f\"", 00282 objMax, objMin, objSum, objArea, 00283 distMax, distMin, distSum, distArea); 00284 printf("\n"); 00285 */ 00286 } else { 00287 printf("##%s has no objects \n", sceneFile.c_str()); 00288 } 00289 } 00290 00291 } 00292 00293 Point2D<int> evolveBrain(Image<PixRGB<byte> > &img, Image<float> &SMap, float *interestLevel, 00294 nub::soft_ref<SimEventQueue> seq) 00295 { 00296 00297 nub::ref<StdBrain> brain = dynCastWeak<StdBrain>(mgr->subComponent("Brain")); 00298 00299 00300 *interestLevel = 0.0F; 00301 if (mgr->started() && img.initialized()){ //give the image to the brain 00302 00303 00304 SimTime end_time = seq->now() + SimTime::MSECS(3.0); 00305 while (seq->now() < end_time) 00306 { 00307 brain->evolve(*seq); //evolve the brain 00308 00309 // Any new WTA winner? 00310 if (SeC<SimEventWTAwinner> e = seq->check<SimEventWTAwinner>(brain.get())) 00311 { 00312 const Point2D<int> winner = e->winner().p; 00313 const float winV = e->winner().sv; 00314 *interestLevel = (winV * 1000.0f) * 1; 00315 LINFO("##### Winner (%d,%d) at %fms : %.4f #####\n", 00316 winner.i, winner.j, seq->now().msecs(), winV * 1000.0f); 00317 00318 //get the saliency map output 00319 if (debug) 00320 { 00321 if (SeC<SimEventSaliencyMapOutput> smo = 00322 seq->check<SimEventSaliencyMapOutput>(brain.get(), SEQ_ANY)) 00323 { 00324 //Image<float> img = smo->sm(); 00325 //SHOWIMG(img); 00326 //SHOWIMG(rescale(img, img.getWidth()*16, img.getHeight()*16)); 00327 } 00328 } 00329 seq->evolve(); 00330 00331 return winner; 00332 } 00333 seq->evolve(); 00334 } 00335 } 00336 00337 return Point2D<int>(); 00338 00339 } 00340 00341 void biasVC(ComplexChannel &vc, Image<float> &mask) 00342 { 00343 //Set mean and sigma to bias submap 00344 MaskBiaser mb(mask, true); 00345 vc.accept(mb); 00346 00347 setSubmapAlgorithmBiased(vc); 00348 } 00349