00001 /*!@file Corba/Parallel/GetSM.C a compute a saliency map from cmap class */ 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/Corba/Parallel/GetSM.C $ 00035 // $Id: GetSM.C 9412 2008-03-10 23:10:15Z farhan $ 00036 // 00037 00038 #include "Component/ModelManager.H" 00039 #include "Devices/DeviceOpts.H" 00040 #include "Devices/FrameGrabberConfigurator.H" 00041 #include "GUI/XWinManaged.H" 00042 #include "GUI/XWindow.H" 00043 #include "Image/ColorOps.H" 00044 #include "Image/CutPaste.H" // for inplacePaste() 00045 #include "Image/DrawOps.H" 00046 #include "Image/FilterOps.H" 00047 #include "Image/Image.H" 00048 #include "Image/Image.H" 00049 #include "Image/ImageSet.H" 00050 #include "Image/MathOps.H" 00051 #include "Image/Pixels.H" 00052 #include "Image/PyramidTypes.H" 00053 #include "Image/ShapeOps.H" // for decX() etc. 00054 #include "Image/Transforms.H" 00055 #include "Neuro/NeuroOpts.H" 00056 #include "Neuro/SaccadeControllers.H" 00057 #include "Psycho/PsychoDisplay.H" 00058 #include "Transport/FrameIstream.H" 00059 #include "Util/Assert.H" 00060 #include "Util/Timer.H" 00061 #include <iostream> 00062 #include <stdlib.h> 00063 #include <sys/resource.h> 00064 #include <sys/time.h> 00065 #include <time.h> 00066 #include <unistd.h> 00067 00068 00069 #include "Corba/ImageOrbUtil.H" 00070 #include "Corba/Parallel/CMapSK.hh" 00071 #include <omniORB4/Naming.hh> 00072 #include <omniORB4/omniURI.h> 00073 00074 OMNI_USING_NAMESPACE(omni); 00075 00076 void getObjectReference(CORBA::ORB_ptr orb); 00077 00078 XWinManaged window(Dims(256, 256), -1, -1, "Test Output"); 00079 00080 #define sml 2 00081 #define delta_min 3 00082 #define delta_max 4 00083 #define level_min 0 00084 #define level_max 2 00085 #define maxdepth (level_max + delta_max + 1) 00086 #define normtyp (VCXNORM_MAXNORM) 00087 00088 #define IWEIGHT 1.0 00089 #define CWEIGHT 1.0 00090 #define OWEIGHT 1.0 00091 #define FWEIGHT 1.5 00092 00093 #define NBCMAP2 8 00094 //! prescale level by which we downsize images before sending them off 00095 #define PRESCALE 2 00096 00097 //!Number of cmap objects that we have running 00098 int nCmapObj =0; 00099 00100 CMap_var CMap_ref[100]; 00101 00102 //!The current cmap object to send the request to 00103 CMap_var getCmapRef(){ 00104 static int current_obj = 0; 00105 00106 //just do a round rubin 00107 current_obj = (current_obj+1)%nCmapObj; 00108 00109 LINFO("Using cmap object number %i\n", current_obj); 00110 return CMap_ref[current_obj]; 00111 } 00112 00113 Image<float> cmap[NBCMAP2]; 00114 00115 00116 class CmapThread : public omni_thread { 00117 00118 public: 00119 CmapThread(Image<byte> &img, int mapid, PyramidType ptype, double ori, double weight){ 00120 th_img1 = img; th_mapid = mapid; th_ptype = ptype; th_ori = ori; th_weight = weight; 00121 LINFO("Starting thread for cmap[%i] with %i %g %g\n",mapid, ptype, ori, weight); 00122 00123 start_undetached(); 00124 //start(); 00125 } 00126 00127 CmapThread(Image<byte> &img1, Image<byte> &img2, int mapid, PyramidType ptype, double ori, double weight){ 00128 th_img1 = img1; th_img2 = img2; th_mapid = mapid; th_ptype = ptype; th_ori = ori; th_weight = weight; 00129 LINFO("Starting thread for cmap[%i] with %i %g %g\n",mapid, ptype, ori, weight); 00130 00131 start_undetached(); 00132 //start(); 00133 } 00134 00135 ~CmapThread(void) {} 00136 00137 private: 00138 Image<byte> th_img1; 00139 Image<byte> th_img2; 00140 int th_mapid; 00141 PyramidType th_ptype; 00142 double th_ori; 00143 double th_weight; 00144 00145 void* run_undetached(void *ptr){ 00146 //process the thread 00147 CMap_var CMap = getCmapRef(); //get the object to send to 00148 ImageOrb* imgOrb; 00149 switch (th_mapid){ 00150 case 5: 00151 imgOrb = CMap->computeCMAP2(*image2Orb(th_img1), *image2Orb(th_img2), 00152 th_ptype, th_ori, th_weight); 00153 break; 00154 case 6: 00155 imgOrb = CMap->computeCMAP2(*image2Orb(th_img1), *image2Orb(th_img2), 00156 th_ptype, th_ori, th_weight); 00157 break; 00158 case 7: 00159 imgOrb = CMap->computeFlickerCMAP(*image2Orb(th_img1), 00160 th_ptype, th_ori, th_weight); 00161 break; 00162 00163 default: 00164 imgOrb = CMap->computeCMAP(*image2Orb(th_img1), 00165 th_ptype, th_ori, th_weight); 00166 } 00167 00168 Image<byte> tmp; 00169 orb2Image(*imgOrb, tmp); 00170 cmap[th_mapid] = tmp; 00171 delete imgOrb; 00172 LINFO("Cmap %i done\n",th_mapid); 00173 00174 return NULL; 00175 } 00176 00177 }; 00178 00179 00180 Image< PixRGB<byte> > &getImage(){ 00181 00182 int w=256, h=256; 00183 static Image< PixRGB<byte> > *img =0; 00184 00185 if (img) delete img; 00186 00187 00188 LINFO("New Image\n"); 00189 img = new Image< PixRGB<byte> >(w, h, NO_INIT); 00190 00191 00192 //generate a random image 00193 00194 Image<byte> r(w,h,ZEROS), g(w,h,ZEROS), b(w,h,ZEROS); 00195 00196 //r.speckleNoise(1.0F, 10, 255, true); 00197 //g.speckleNoise(1.0F, 10, 255, true); 00198 //b.speckleNoise(1.0F, 10, 255, true); 00199 00200 *img = makeRGB(r,g,b); 00201 00202 int x_pos = 1+(int)((float)w*rand()/(RAND_MAX+1.0)); 00203 int y_pos = 1+(int)((float)h*rand()/(RAND_MAX+1.0)); 00204 printf("Position: %i %i\n", x_pos, y_pos); 00205 00206 //draw a red cross 00207 drawCross(*img,Point2D<int>(x_pos, y_pos), PixRGB<byte>(255,0,0), 30, 8); 00208 drawCross(*img,Point2D<int>(x_pos,y_pos), PixRGB<byte>(0,0,255), 20, 4); 00209 00210 00211 //read an image 00212 //*img = Raster::ReadRGB("test.ppm"); //read image 00213 00214 //window2.drawImage(rescale(*img, 256, 256)); 00215 return *img; 00216 } 00217 00218 int main(int argc, char **argv){ 00219 00220 00221 CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB4"); 00222 00223 getObjectReference(orb); 00224 00225 Timer time(1000000); 00226 time.reset(); 00227 00228 Image<float> sm(256>>2, 256>>2, ZEROS); 00229 00230 for (int ii=0; ii<30; ii++){ 00231 //start the clock 00232 00233 LINFO("Loop i=%i\n", ii); 00234 Image< PixRGB<byte> > img; 00235 img = getImage(); 00236 00237 Image<PixRGB<byte> > ima2 = 00238 decY(lowPass5y(decX(lowPass5x(img),1<<PRESCALE)),1<<PRESCALE); 00239 00240 Image<byte> lum; 00241 lum = luminance(img); 00242 00243 00244 // compute RG and BY 00245 Image<byte> rImg, gImg, bImg, yImg; 00246 getRGBY(img, rImg, gImg, bImg, yImg, (byte)25); 00247 00248 00249 static class CmapThread* thCmapWorker[NBCMAP2]; 00250 00251 thCmapWorker[0] = new CmapThread(lum, 0, Gaussian5, 0.0, IWEIGHT); //lum thread 00252 00253 thCmapWorker[1] = new CmapThread(lum, 1, Oriented5, 0.0, OWEIGHT); //ori thread 00254 thCmapWorker[2] = new CmapThread(lum, 2, Oriented5, 45.0, OWEIGHT); //ori thread 00255 thCmapWorker[3] = new CmapThread(lum, 3, Oriented5, 90.0, OWEIGHT); //ori thread 00256 thCmapWorker[4] = new CmapThread(lum, 4, Oriented5, 135.0, OWEIGHT); //ori thread 00257 00258 thCmapWorker[5] = new CmapThread(rImg, gImg, 5, Gaussian5, 0.0, CWEIGHT); //color thread 00259 thCmapWorker[6] = new CmapThread(bImg, yImg, 6, Gaussian5, 0.0, CWEIGHT); //color thread 00260 00261 thCmapWorker[7] = new CmapThread(lum, 7, Gaussian5, 0.0, FWEIGHT); //filker thread 00262 00263 00264 //wait for threads to finish 00265 for(int i=0; i< NBCMAP2; i++) { 00266 thCmapWorker[i]->join(NULL); 00267 } 00268 00269 Image<float> sminput; 00270 00271 for (int i=0; i< NBCMAP2; i++){ 00272 if (cmap[i].initialized()){ 00273 if (sminput.initialized()) 00274 sminput += cmap[i]; 00275 else 00276 sminput = cmap[i]; 00277 } 00278 } 00279 00280 //inhibit old input and add the new one from sminput 00281 if (sminput.initialized()) sm = sm * 0.7F + sminput * 0.3F; 00282 00283 // find most salient location and feed saccade controller: 00284 float maxval; Point2D<int> currwin; findMax(sm,currwin, maxval); 00285 00286 printf("Winner at %i %i level=%f\n", currwin.i, currwin.j, maxval); 00287 00288 Image<float> dispsm(sm); inplaceNormalize(dispsm, 0.0F, 255.0F); 00289 00290 Image<byte> showsm = dispsm; 00291 drawCircle(showsm, currwin, 5, (byte)255, 1); 00292 window.drawImage(rescale(showsm, 256, 256)); 00293 //exit(0); 00294 00295 } 00296 00297 LINFO("Time taken %f\n", time.getSecs()); 00298 00299 //shutdown all the cmap servers 00300 00301 for (int i=0; i< nCmapObj; i++){ 00302 CMap_ref[i]->shutdown(); 00303 } 00304 return 0; 00305 00306 } 00307 00308 void getObjectReference(CORBA::ORB_ptr orb) { 00309 CosNaming::NamingContext_var rootContext; 00310 00311 try { 00312 // Obtain a reference to the root context of the Name service: 00313 CORBA::Object_var obj; 00314 obj = orb->resolve_initial_references("NameService"); 00315 00316 // Narrow the reference returned. 00317 rootContext = CosNaming::NamingContext::_narrow(obj); 00318 if( CORBA::is_nil(rootContext) ) { 00319 std::cerr << "Failed to narrow the root naming context." << std::endl; 00320 return; 00321 } 00322 } 00323 catch(CORBA::ORB::InvalidName& ex) { 00324 // This should not happen! 00325 std::cerr << "Service required is invalid [does not exist]." << std::endl; 00326 return; 00327 } 00328 00329 //find out how many objects we have to work with 00330 00331 // Create a name object, containing the name test/context: 00332 CosNaming::Name_var name = omniURI::stringToName("test.saliency"); 00333 00334 CORBA::Object_var obj = rootContext->resolve(name); 00335 00336 CosNaming::NamingContext_var context; 00337 context = CosNaming::NamingContext::_narrow(obj); 00338 00339 if (CORBA::is_nil(context)) { 00340 LINFO("No objects found\n"); 00341 exit(1); 00342 } 00343 00344 //get all the objects in the context 00345 00346 CosNaming::BindingIterator_var bi; 00347 CosNaming::BindingList_var bl; 00348 CosNaming::Binding_var b; 00349 00350 context->list(0, bl, bi); 00351 00352 if (CORBA::is_nil(bi)){ 00353 LINFO("No objects found\n"); 00354 exit(1); 00355 } 00356 00357 nCmapObj=0; 00358 while (bi->next_one(b)){ 00359 00360 CosNaming::Name name_comp = b->binding_name; 00361 // CORBA::String_var sname = omniURI::nameToString(b->binding_name); 00362 00363 LINFO("Binding to %s ... ", (const char*)omniURI::nameToString(name_comp)); 00364 CORBA::Object_ptr ref = context->resolve(name_comp); 00365 CMap_ref[nCmapObj] = CMap::_narrow(ref); 00366 //check for errors 00367 if (!CORBA::is_nil(CMap_ref[nCmapObj])){ 00368 nCmapObj++; 00369 LINFO("Done\n"); 00370 } else { 00371 LINFO("Fail\n"); 00372 } 00373 00374 } 00375 bi->destroy(); 00376 00377 } 00378 00379