00001 /*!@file RCBot/trackCMap.C track featuers */ 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: Lior Elazary <lelazary@yahoo.com> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/RCBot/trackCMap.C $ 00035 // $Id: trackCMap.C 9412 2008-03-10 23:10:15Z farhan $ 00036 // 00037 00038 #include "Component/ModelManager.H" 00039 #include "Component/OptionManager.H" 00040 #include "Controllers/PID.H" 00041 #include "Devices/FrameGrabberConfigurator.H" 00042 #include "Devices/sc8000.H" 00043 #include "GUI/XWinManaged.H" 00044 #include "Image/ColorOps.H" 00045 #include "Image/CutPaste.H" 00046 #include "Image/DrawOps.H" 00047 #include "Image/Image.H" 00048 #include "Image/MathOps.H" 00049 #include "Image/Pixels.H" 00050 #include "Image/ShapeOps.H" 00051 #include "Image/Transforms.H" 00052 #include "Image/fancynorm.H" 00053 #include "Neuro/SaliencyMap.H" 00054 #include "Neuro/VisualCortex.H" 00055 #include "Neuro/WTAwinner.H" 00056 #include "Neuro/WinnerTakeAll.H" 00057 #include "RCBot/Motion/MotionEnergy.H" 00058 #include "Raster/Raster.H" 00059 #include "Transport/FrameIstream.H" 00060 #include "Util/Timer.H" 00061 #include "Util/Types.H" 00062 #include "Util/log.H" 00063 #include <math.h> 00064 00065 #define UP_KEY 98 00066 #define DOWN_KEY 104 00067 #define LEFT_KEY 100 00068 #define RIGHT_KEY 102 00069 00070 XWinManaged window(Dims(256, 256), -1, -1, "Test Output 1"); 00071 XWinManaged window1(Dims(256, 256), -1, -1, "S Map"); 00072 XWinManaged window2(Dims(256, 256), -1, -1, "S Map"); 00073 00074 #define sml 0 00075 #define delta_min 3 00076 #define delta_max 4 00077 #define level_min 0 00078 #define level_max 2 00079 #define maxdepth (level_max + delta_max + 1) 00080 #define normtyp (VCXNORM_MAXNORM) 00081 00082 Image<float> ComputeCMAP(const Image<float>& fimg, const PyramidType ptyp, const float ori, const float coeff, Point2D<int>& p, float *bias, bool find_bias) 00083 { 00084 // compute pyramid: 00085 ImageSet<float> pyr = buildPyrGeneric(fimg, 0, maxdepth, ptyp, ori); 00086 00087 // alloc conspicuity map and clear it: 00088 Image<float> *cmap = new Image<float>(pyr[sml].getDims(), ZEROS); 00089 00090 00091 // intensities is the max-normalized weighted sum of IntensCS: 00092 int ii=0; 00093 for (int delta = delta_min; delta <= delta_max; delta ++) 00094 for (int lev = level_min; lev <= level_max; lev ++) 00095 { 00096 Image<float> tmp = centerSurround(pyr, lev, lev + delta, true); 00097 inplaceNormalize(tmp, 0.0F, 255.0F); 00098 if (find_bias){ 00099 //bias the saliency map 00100 for (Image<float>::iterator itr = tmp.beginw(), stop = tmp.endw(); 00101 itr != stop; ++itr) { 00102 *itr = 255.0F - fabs((*itr) - bias[ii]); //corelate the bias 00103 } 00104 00105 } else if (p.isValid()){ 00106 //get the bias points 00107 Point2D<int> newp(p.i / (cmap->getWidth()/tmp.getWidth()), 00108 p.j / (cmap->getHeight()/tmp.getHeight())); 00109 00110 bias[ii] = tmp.getVal(newp); 00111 } 00112 00113 //tmp = downSize(tmp, cmap->getWidth(), cmap->getHeight()); 00114 tmp = rescale(tmp, cmap->getWidth(), cmap->getHeight()); 00115 //inplaceAddBGnoise(tmp, 255.0); 00116 tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp); 00117 *cmap += tmp; 00118 ii++; 00119 } 00120 if (normtyp == VCXNORM_MAXNORM) 00121 *cmap = maxNormalize(*cmap, MAXNORMMIN, MAXNORMMAX, normtyp); 00122 else 00123 *cmap = maxNormalize(*cmap, 0.0f, 0.0f, normtyp); 00124 00125 // multiply by conspicuity coefficient: 00126 *cmap *= coeff; 00127 00128 return *cmap; 00129 } 00130 00131 // ###################################################################### 00132 int main(int argc, char **argv) 00133 { 00134 MYLOGVERB = LOG_INFO; 00135 00136 // instantiate a model manager: 00137 ModelManager manager("Track Features"); 00138 00139 // Instantiate our various ModelComponents: 00140 nub::soft_ref<FrameGrabberConfigurator> 00141 gbc(new FrameGrabberConfigurator(manager)); 00142 manager.addSubComponent(gbc); 00143 00144 // Parse command-line: 00145 if (manager.parseCommandLine(argc, (const char **)argv, "", 0, 0) == false) return(1); 00146 00147 // do post-command-line configs: 00148 nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber(); 00149 if (gb.get() == NULL) 00150 LFATAL("You need to select a frame grabber type via the " 00151 "--fg-type=XX command-line option for this program " 00152 "to be useful -- ABORT"); 00153 // int w = gb->getWidth(), h = gb->getHeight(); 00154 00155 // let's get all our ModelComponent instances started: 00156 manager.start(); 00157 00158 00159 // get the frame grabber to start streaming: 00160 gb->startStream(); 00161 00162 00163 // ########## MAIN LOOP: grab, process, display: 00164 int key = 0; 00165 00166 double time = 0; 00167 00168 float *lum_bias = new float[6]; 00169 float *r_bias = new float[6]; 00170 float *b_bias = new float[6]; 00171 float *g_bias = new float[6]; 00172 00173 float *o0_bias = new float[6]; 00174 float *o45_bias = new float[6]; 00175 float *o90_bias = new float[6]; 00176 float *o135_bias = new float[6]; 00177 00178 float *oldlum_bias = new float[6]; 00179 float *oldr_bias = new float[6]; 00180 float *oldb_bias = new float[6]; 00181 float *oldg_bias = new float[6]; 00182 00183 float *oldo0_bias = new float[6]; 00184 float *oldo45_bias = new float[6]; 00185 float *oldo90_bias = new float[6]; 00186 float *oldo135_bias = new float[6]; 00187 bool track_f = false; 00188 00189 int fr = 40; 00190 while(key != 24){ 00191 // receive conspicuity maps: 00192 // grab an image: 00193 00194 Image< PixRGB<byte> > ima = gb->readRGB(); 00195 /*char filename[255]; 00196 sprintf(filename, "/home/elazary/robot/car/video/frame%i.ppm", fr); 00197 Image< PixRGB<byte> > ima = Raster::ReadRGB(filename);*/ 00198 00199 00200 00201 Image<float> lum = luminance(ima); 00202 Image<byte> rImg, gImg, bImg, yImg; 00203 getRGBY(ima, rImg, gImg, bImg, yImg, (byte)25); 00204 00205 Image<float> cmap; 00206 00207 Point2D<int> location = window.getLastMouseClick(); 00208 if (location.isValid()){ 00209 LINFO("Click at at %i %i", location.i, location.j); 00210 Dims WindowDims = window.getDims(); 00211 00212 float newi = (float)location.i * (float)ima.getWidth()/(float)WindowDims.w(); 00213 float newj = (float)location.j * (float)ima.getHeight()/(float)WindowDims.h(); 00214 location.i = (int)newi; 00215 location.j = (int)newj; 00216 00217 //we got a click, show the featuers at that point 00218 LINFO("Getting the features at %i %i", location.i, location.j); 00219 ComputeCMAP(lum, Gaussian5, 0.0, 1.0F, location, lum_bias, false); 00220 ComputeCMAP(rImg, Gaussian5, 0.0, 1.0F, location, r_bias, false); 00221 ComputeCMAP(gImg, Gaussian5, 0.0, 1.0F, location, g_bias, false); 00222 ComputeCMAP(bImg, Gaussian5, 0.0, 1.0F, location, b_bias, false); 00223 00224 ComputeCMAP(lum, Oriented5, 0.0, 1.0F, location, o0_bias, false); //ori thread 00225 ComputeCMAP(lum, Oriented5, 45.0, 1.0F, location, o45_bias, false); //ori thread 00226 ComputeCMAP(lum, Oriented5, 90.0, 1.0F, location, o90_bias, false); //ori thread 00227 ComputeCMAP(lum, Oriented5, 135.0, 1.0F, location, o135_bias, false); //ori thread 00228 00229 track_f = true; 00230 } 00231 00232 cmap = ComputeCMAP(lum, Gaussian5, 0.0, 1.0F, location, lum_bias, 1); 00233 cmap += ComputeCMAP(rImg, Gaussian5, 0.0, 1.0F, location, r_bias, 1); 00234 cmap += ComputeCMAP(gImg, Gaussian5, 0.0, 1.0F, location, g_bias, 1); 00235 cmap += ComputeCMAP(bImg, Gaussian5, 0.0, 1.0F, location, b_bias, 1); 00236 00237 cmap += ComputeCMAP(lum, Oriented5, 0.0, 1.0F, location, o0_bias, 1); //ori thread 00238 cmap += ComputeCMAP(lum, Oriented5, 45.0, 1.0F, location, o45_bias, 1); //ori thread 00239 cmap += ComputeCMAP(lum, Oriented5, 90.0, 1.0F, location, o90_bias, 1); //ori thread 00240 cmap += ComputeCMAP(lum, Oriented5, 135.0, 1.0F, location, o135_bias, 1); //ori thread 00241 00242 for (int i=0; i<6; i++){ 00243 oldlum_bias[i] = lum_bias[i]; 00244 oldr_bias[i] = r_bias[i]; 00245 oldg_bias[i] = g_bias[i]; 00246 oldb_bias[i] = b_bias[i]; 00247 oldo0_bias[i] = o0_bias[i]; 00248 oldo45_bias[i] = o45_bias[i]; 00249 oldo90_bias[i] = o90_bias[i]; 00250 oldo135_bias[i] = o135_bias[i]; 00251 } 00252 00253 00254 Point2D<int> winner; float maxval; 00255 findMax(cmap, winner, maxval); 00256 drawDisk(ima, winner, 10, PixRGB<byte>(255, 0, 0)); 00257 00258 window.drawImage(rescale(ima, 256, 256)); 00259 window1.drawImage(rescale(cmap, 256, 256)); 00260 00261 if (track_f){ 00262 LINFO("Getting the features from winner at %i %i", winner.i, winner.j); 00263 ComputeCMAP(lum, Gaussian5, 0.0, 1.0F, winner, lum_bias, 0); 00264 ComputeCMAP(rImg, Gaussian5, 0.0, 1.0F, winner, r_bias, 0); 00265 ComputeCMAP(gImg, Gaussian5, 0.0, 1.0F, winner, g_bias, 0); 00266 ComputeCMAP(bImg, Gaussian5, 0.0, 1.0F, winner, b_bias, 0); 00267 00268 ComputeCMAP(lum, Oriented5, 0.0, 1.0F, winner, o0_bias, 0); //ori thread 00269 ComputeCMAP(lum, Oriented5, 45.0, 1.0F, winner, o45_bias, 0); //ori thread 00270 ComputeCMAP(lum, Oriented5, 90.0, 1.0F, winner, o90_bias, 0); //ori thread 00271 ComputeCMAP(lum, Oriented5, 135.0, 1.0F, winner, o135_bias, 0); //ori thread 00272 } 00273 00274 //find how close is the featuere from the old one 00275 double fmag = 0; 00276 for(int i=0; i<6; i++){ 00277 fmag += squareOf(oldlum_bias[i] - lum_bias[i]); 00278 fmag += squareOf(oldr_bias[i] - r_bias[i]); 00279 fmag += squareOf(oldg_bias[i] - g_bias[i]); 00280 fmag += squareOf(oldb_bias[i] - b_bias[i]); 00281 fmag += squareOf(oldo0_bias[i] - o0_bias[i]); 00282 fmag += squareOf(oldo45_bias[i] - o45_bias[i]); 00283 fmag += squareOf(oldo90_bias[i] - o90_bias[i]); 00284 fmag += squareOf(oldo135_bias[i] - o135_bias[i]); 00285 } 00286 fmag = sqrt(fmag); 00287 LINFO("Distance %f\n", fmag); 00288 if (fmag > 200){ 00289 //featuer are too far from what we are tracking 00290 //restore to orignal features 00291 LINFO("Restoring featuers"); 00292 for (int i=0; i<6; i++){ 00293 lum_bias[i] = oldlum_bias[i]; 00294 r_bias[i] = oldr_bias[i]; 00295 g_bias[i] = oldg_bias[i]; 00296 b_bias[i] = oldb_bias[i]; 00297 o0_bias[i] = oldo0_bias[i]; 00298 o45_bias[i] = oldo45_bias[i]; 00299 o90_bias[i] = oldo90_bias[i]; 00300 o135_bias[i] = oldo135_bias[i]; 00301 } 00302 } 00303 00304 00305 00306 time += 0.1; 00307 fr++; 00308 } 00309 00310 00311 00312 // got interrupted; let's cleanup and exit: 00313 manager.stop(); 00314 return 0; 00315 } 00316 00317 00318 // ###################################################################### 00319 /* So things look consistent in everyone's emacs... */ 00320 /* Local Variables: */ 00321 /* indent-tabs-mode: nil */ 00322 /* End: */