mbariFunctions.C

Go to the documentation of this file.
00001 /*!@file MBARI/mbariFunctions.C a few functions used by MBARI programs
00002  */
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2002   //
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: Dirk Walther <walther@caltech.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/MBARI/mbariFunctions.C $
00035 // $Id: mbariFunctions.C 10712 2009-02-01 06:22:17Z itti $
00036 //
00037 
00038 
00039 #include "MBARI/mbariFunctions.H"
00040 #include "Image/ColorOps.H"
00041 #include "Image/FilterOps.H"
00042 #include "Image/Image.H"
00043 #include "Image/MathOps.H"
00044 #include "Image/Transforms.H"
00045 #include "Media/MediaSimEvents.H"
00046 #include "MBARI/BitObject.H"
00047 #include "Neuro/Brain.H"
00048 #include "Neuro/NeuroSimEvents.H"
00049 #include "Simulation/SimEventQueue.H"
00050 #include "Util/Timer.H"
00051 #include "rutz/shared_ptr.h"
00052 
00053 
00054 // ######################################################################
00055 std::list<BitObject> extractBitObjects(const Image<byte>& bImg,
00056                                        Rectangle region,
00057                                        int minSize)
00058 {
00059   Timer timer;
00060   Image<byte> bitImg = replaceVals(bImg, byte(0), byte(0), byte(1));
00061   int tmask = 0, tobj = 0;
00062   std::list<BitObject> bos;
00063   region = region.getOverlap(bitImg.getBounds());
00064   Image<byte> labelImg(bitImg.getDims(),ZEROS);
00065 
00066   for (int ry = region.top(); ry < region.bottomO(); ++ry)
00067     for (int rx = region.left(); rx < region.rightO(); ++rx)
00068       {
00069         // this location doesn't have anything -> never mind
00070         if (bitImg.getVal(rx,ry) == 0) continue;
00071 
00072         // got this guy already -> never mind
00073         if (labelImg.getVal(rx,ry) > 0) continue;
00074 
00075         //Image<byte> dest(bitImg.getDims(), ZEROS);
00076 
00077         //timer.reset();
00078         //if (floodClean(bitImg,labelImg, Point2D<int>(rx,ry), byte(1), byte(1)) < minSize)
00079         //continue
00080         //int area = floodClean(bitImg,dest, Point2D<int>(rx,ry), byte(1), byte(1));
00081         //tflood += timer.get();
00082         //labelImg = takeMax(labelImg, dest);
00083         //if (area < minSize) continue;
00084 
00085         timer.reset();
00086         BitObject obj;
00087         Image<byte> dest = obj.reset(bitImg, Point2D<int>(rx,ry));
00088         tobj += timer.get();
00089 
00090         timer.reset();
00091         labelImg = takeMax(labelImg, dest);
00092         tmask += timer.get();
00093 
00094         if (obj.getArea() > minSize) bos.push_back(obj);
00095         //bos.push_back(BitObject(bitImg,Point2D<int>(rx,ry)));
00096         //bos.push_back(BitObject(dest));
00097 
00098         //LINFO("found object of size: %d",bos.back().getArea());
00099       }
00100   LINFO("tobj = %i; tmask = %i",tobj,tmask);
00101   return bos;
00102 }
00103 
00104 // ######################################################################
00105 std::list<BitObject> getLargestObjects(const Image<byte>& bImg,
00106                                        Rectangle region,
00107                                        int numObjects,
00108                                        int minSize)
00109 {
00110   std::list<BitObject> objs = extractBitObjects(bImg, region, minSize);
00111   std::list<BitObject> result;
00112 
00113   for (int i = 0; i < numObjects; ++i)
00114     {
00115       int maxSize = 0;
00116       std::list<BitObject>::iterator mx, cur;
00117 
00118       if (objs.empty()) break;
00119       for (cur = objs.begin(); cur != objs.end(); ++cur)
00120         {
00121           if (cur->getArea() > maxSize)
00122             {
00123               maxSize = cur->getArea();
00124               mx = cur;
00125             }
00126         }
00127 
00128       result.push_back(*mx);
00129       objs.erase(mx);
00130     }
00131   return result;
00132 }
00133 
00134 // ######################################################################
00135 std::list<BitObject> getSalRegions(nub::soft_ref<Brain> brain,
00136                                    nub::soft_ref<SimEventQueue> q,
00137                                    const Image< PixRGB<byte> >& img,
00138                                    const Image<byte>& bitImg,
00139                                    float maxEvolveTime,
00140                                    int maxNumSalSpots,
00141                                    int minSize)
00142 {
00143   // this should be 2^(smlev - 1)
00144   const int rectRad = 8;
00145 
00146   std::list<BitObject> bos;
00147   brain->reset(MC_RECURSE);
00148 
00149   rutz::shared_ptr<SimEventInputFrame>
00150     e(new SimEventInputFrame(brain.get(), GenericFrame(img), 0));
00151   q->post(e); // post the image to the brain
00152 
00153   int numSpots = 0;
00154   while ((q->now().secs() < maxEvolveTime) && (numSpots < maxNumSalSpots))
00155     {
00156       q->evolve();
00157 
00158       if (SeC<SimEventWTAwinner> e = q->check<SimEventWTAwinner>(0))
00159         {
00160           const Point2D<int> winner = e->winner().p;
00161 
00162           ++numSpots;
00163 
00164           // extract all the bitObjects at the salient location
00165           Rectangle region =
00166             Rectangle::tlbrI(winner.j - rectRad, winner.i - rectRad,
00167                             winner.j + rectRad, winner.i + rectRad);
00168           region = region.getOverlap(bitImg.getBounds());
00169           std::list<BitObject> sobjs = extractBitObjects(bitImg,region,minSize);
00170 
00171           // loop until we find a new object that doesn't overlap with anything
00172           // that we have found so far, or until we run out of objects
00173           bool keepGoing = true;
00174           while(keepGoing)
00175             {
00176               // no object left -> go to the next salient point
00177               if (sobjs.empty()) break;
00178 
00179               std::list<BitObject>::iterator biter, siter, largest;
00180 
00181               // find the largest object
00182               largest = sobjs.begin();
00183               int maxSize = 0;
00184               for (siter = sobjs.begin(); siter != sobjs.end(); ++siter)
00185                 if (siter->getArea() > maxSize)
00186                   {
00187                     maxSize = siter->getArea();
00188                     largest = siter;
00189                   }
00190 
00191               // does the largest objects intersect with any of the already stored guys?
00192               keepGoing = false;
00193               for (biter = bos.begin(); biter != bos.end(); ++biter)
00194                 if (biter->doesIntersect(*largest))
00195                   {
00196                     // no need to store intersecting objects -> get rid of largest
00197                     // and look for the next largest
00198                     sobjs.erase(largest);
00199                     keepGoing = true;
00200                     break;
00201                   }
00202 
00203               // so, did we end up finding a BitObject that we can store?
00204               if (!keepGoing) bos.push_back(*largest);
00205 
00206             } // end while keepGoing
00207 
00208         } // end if we found a winner
00209 
00210     } // end while we keep looking for salient points
00211 
00212   return bos;
00213 }
00214 
00215 // ######################################################################
00216 Image<byte> showAllObjects(std::list<BitObject>& objs)
00217 {
00218   Image<byte> result;
00219   std::list<BitObject>::iterator currObj;
00220   for (currObj = objs.begin(); currObj != objs.end(); ++currObj)
00221     {
00222       Image<byte> mask = currObj->getObjectMask(byte(255));
00223       if (result.initialized())
00224         result = takeMax(result,mask);
00225       else
00226         result = mask;
00227     }
00228   return result;
00229 }
00230 
00231 // ######################################################################
00232 /* So things look consistent in everyone's emacs... */
00233 /* Local Variables: */
00234 /* indent-tabs-mode: nil */
00235 /* End: */
Generated on Sun May 8 08:40:59 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3