CMap.C

Go to the documentation of this file.
00001 /*!@file Corba/Parallel/CMap.C a compute a conspicuity map from an image */
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/CMap.C $
00035 // $Id: CMap.C 14125 2010-10-12 06:29:08Z itti $
00036 //
00037 
00038 
00039 #include <stdlib.h>
00040 #include <time.h>
00041 #include <iostream>
00042 #include <unistd.h>
00043 #include <fcntl.h>
00044 #include <sys/types.h>
00045 #include <sys/stat.h>
00046 #include "Image/ColorOps.H"
00047 #include "Image/Image.H"
00048 #include "Image/ImageSet.H"
00049 #include "Image/Pixels.H"
00050 #include "Image/PyramidOps.H"
00051 #include "Image/ShapeOps.H"
00052 #include "Image/Transforms.H"
00053 #include "Image/fancynorm.H"
00054 #include "Util/Assert.H"
00055 #include "Util/Timer.H"
00056 #include "Util/Types.H"
00057 #include <cstdio> // for sprintf
00058 
00059 #include "Corba/Parallel/CMapSK.hh"
00060 #include "Corba/ImageOrbUtil.H"
00061 
00062 // ######################################################################
00063 // ##### Global options:
00064 // ######################################################################
00065 #define sml        2
00066 #define delta_min  3
00067 #define delta_max  4
00068 #define level_min  0
00069 #define level_max  2
00070 #define maxdepth   (level_max + delta_max + 1)
00071 #define normtyp    (VCXNORM_MAXNORM)
00072 
00073 // relative feature weights:
00074 #define IWEIGHT 1.0
00075 #define CWEIGHT 1.0
00076 #define OWEIGHT 1.0
00077 #define FWEIGHT 1.5
00078 
00079 #define NBCMAP2 7
00080 //! prescale level by which we downsize images before sending them off
00081 #define PRESCALE 2
00082 
00083 CORBA::ORB_var orb;
00084 CosNaming::Name objectName;
00085 
00086 static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr);
00087 void unbindObject ();
00088 
00089 //Define STAT_CMAP to show camp statisitc and timing
00090 #define STAT_CMAP
00091 
00092 
00093 //The cmap object implimentation
00094 class CMap_i : public POA_CMap ,
00095         public PortableServer::RefCountServantBase
00096 {
00097 public:
00098         inline CMap_i(){}
00099         virtual ~CMap_i(){}
00100         virtual ImageOrb* computeCMAP(const ImageOrb& img,
00101                 const short ptyp, const float ori, const float coeff);
00102         virtual ImageOrb* computeCMAP2(const ImageOrb& img1, const ImageOrb& img2,
00103                 const short ptyp, const float ori, const float coeff);
00104         virtual ImageOrb* computeFlickerCMAP(const ImageOrb& img,
00105                 const short ptyp, const float ori, const float coeff);
00106 
00107         virtual void shutdown();
00108 
00109 private:
00110         Image<float>* computeCMAP(const Image<float>& fimg,
00111                                           const PyramidType ptyp, const float ori, const float coeff);
00112 };
00113 
00114 void CMap_i::shutdown() {
00115         // Shutdown the ORB
00116         unbindObject();
00117         orb->shutdown(0);
00118 }
00119 
00120 ImageOrb* CMap_i::computeCMAP(const ImageOrb& img, const short ptyp, const float ori, const float coeff){
00121 
00122 
00123 #ifdef STAT_CMAP
00124                 static double avrtime = 0;
00125                 static int avgn = 0;
00126                 double time_taken;
00127                 Timer time(1000000);
00128                 time.reset();
00129 #endif
00130 
00131 
00132         //convert to an image
00133         Image<byte> image;
00134         orb2Image(img, image);
00135 
00136         //compute the cmap
00137         Image<float> fimg = image;
00138         Image<float> *cmap = computeCMAP(fimg, (PyramidType)ptyp, ori, coeff);
00139         Image<byte> cmap_byte = *cmap;
00140 
00141         delete cmap;
00142 
00143 #ifdef STAT_CMAP
00144                 time_taken = time.getSecs();
00145                 avrtime += time_taken;
00146                 ++avgn;
00147                 LINFO("CMap stats: agvn=%i avgtime=%0.4f time_taken=%f ptype=%i ori=%f coeff=%f",
00148                                 avgn, avrtime/(double)avgn, time_taken, (int)ptyp, ori, coeff);
00149 #endif
00150 
00151         return image2Orb(cmap_byte);
00152 }
00153 
00154 
00155 ImageOrb* CMap_i::computeCMAP2(const ImageOrb& img1, const ImageOrb& img2,
00156                         const short ptyp, const float ori, const float coeff){
00157 
00158 #ifdef STAT_CMAP
00159                 static double avrtime = 0;
00160                 static int avgn = 0;
00161                 double time_taken;
00162 
00163                 Timer time(1000000);
00164                 time.reset();
00165 #endif
00166         //convert to an  image
00167         Image<byte> image1;
00168         orb2Image(img1, image1);
00169 
00170         Image<byte> image2;
00171         orb2Image(img2, image2);
00172 
00173         //compute the cmap
00174         Image<float> fimg = image1-image2;
00175 
00176         Image<float> *cmap = computeCMAP(fimg, (PyramidType)ptyp, ori, coeff);
00177         Image<byte> cmap_byte = *cmap;
00178         delete cmap;
00179 
00180 #ifdef STAT_CMAP
00181                 time_taken = time.getSecs();
00182                 avrtime += time_taken;
00183                 ++avgn;
00184                 LINFO("CMap2 stats: agvn=%i avgtime=%0.4f time_taken=%f ptype=%i ori=%f coeff=%f",
00185                                 avgn, avrtime/(double)avgn, time_taken, (int)ptyp, ori, coeff);
00186 #endif
00187         return image2Orb(cmap_byte);
00188 }
00189 
00190 ImageOrb* CMap_i::computeFlickerCMAP(const ImageOrb& img, const short ptyp, const float ori, const float coeff){
00191 
00192 #ifdef STAT_CMAP
00193                 static double avrtime = 0;
00194                 static int avgn = 0;
00195                 double time_taken;
00196                 Timer time(1000000);
00197                 time.reset();
00198 #endif
00199         static Image<float> previmg;
00200 
00201         //convert to an  image
00202         Image<byte> image;
00203         orb2Image(img, image);
00204 
00205         //compute the cmap
00206         Image<float> fimg = image;
00207         if (previmg.initialized() == false) previmg = fimg;
00208 
00209         previmg -= fimg;
00210         Image<float> *cmap = computeCMAP(previmg, (PyramidType)ptyp, ori, coeff);
00211         previmg = fimg;
00212         Image<byte> cmap_byte = *cmap;
00213 
00214         delete cmap;
00215 
00216 #ifdef STAT_CMAP
00217                 time_taken = time.getSecs();
00218                 avrtime += time_taken;
00219                 ++avgn;
00220                 LINFO("FilckerCmap stats: agvn=%i avgtime=%0.4f time_taken=%f ptype=%i ori=%f coeff=%f",
00221                                 avgn, avrtime/(double)avgn, time_taken, (int)ptyp, ori, coeff);
00222 #endif
00223         return image2Orb(cmap_byte);
00224 }
00225 
00226 
00227 // ######################################################################
00228 Image<float> *CMap_i::computeCMAP(const Image<float>& fimg, const PyramidType ptyp, const float ori, const float coeff)
00229 {
00230   // compute pyramid:
00231   ImageSet<float> pyr = buildPyrGeneric(fimg, 0, maxdepth,
00232                                         ptyp, ori);
00233 
00234   // alloc conspicuity map and clear it:
00235   Image<float> *cmap = new Image<float>(pyr[sml].getDims(), ZEROS);
00236 
00237 
00238   // intensities is the max-normalized weighted sum of IntensCS:
00239   for (int delta = delta_min; delta <= delta_max; delta ++)
00240     for (int lev = level_min; lev <= level_max; lev ++)
00241       {
00242         Image<float> tmp = centerSurround(pyr, lev, lev + delta, true);
00243         tmp = downSize(tmp, cmap->getWidth(), cmap->getHeight());
00244         inplaceAddBGnoise(tmp, 255.0);
00245         tmp = maxNormalize(tmp, MAXNORMMIN, MAXNORMMAX, normtyp);
00246         *cmap += tmp;
00247       }
00248   if (normtyp == VCXNORM_MAXNORM)
00249     *cmap = maxNormalize(*cmap, MAXNORMMIN, MAXNORMMAX, normtyp);
00250   else
00251     *cmap = maxNormalize(*cmap, 0.0f, 0.0f, normtyp);
00252 
00253   // multiply by conspicuity coefficient:
00254   *cmap *= coeff;
00255 
00256   return cmap;
00257 }
00258 
00259 
00260 //start the class server
00261 int main(int argc, char **argv){
00262 
00263         LINFO("Running as a daemon");
00264         //Become a daemon
00265         // fork off the parent process
00266         pid_t pid = fork();
00267         if (pid < 0){
00268                 LFATAL("Can not fork");
00269         }
00270 
00271         if (pid > 0){
00272                 exit(0); //exit the parent process
00273         }
00274 
00275         // Chnage the file mask
00276         umask(0);
00277 
00278         //Create a new system id so that the kernel wont think we are an orphan.
00279 
00280         pid_t sid = setsid();
00281 
00282         if (sid < 0){
00283                 LFATAL("Can not become independent");
00284         }
00285 
00286         //Create the object and run in
00287         orb = CORBA::ORB_init(argc, argv);
00288 
00289         CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
00290         PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);
00291 
00292         CMap_i* cmap = new CMap_i();
00293 
00294         PortableServer::ObjectId_var cmapid = poa->activate_object(cmap);
00295 
00296         //get a ref string
00297         obj = cmap->_this();
00298         CORBA::String_var sior(orb->object_to_string(obj));
00299         std::cerr << "'" << (char*)sior << "'" << "\n";
00300 
00301         if( !bindObjectToName(orb, obj) )
00302       return 1;
00303         cmap->_remove_ref();
00304 
00305         PortableServer::POAManager_var pman = poa->the_POAManager();
00306         pman->activate();
00307 
00308 
00309 
00310         //run the object untill shutdown or killed
00311         orb->run();
00312 
00313         LINFO("Shutting down");
00314         return 0;
00315 }
00316 
00317 //////////////////////////////////////////////////////////////////////
00318 
00319 static CORBA::Boolean
00320 bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref)
00321 {
00322   CosNaming::NamingContext_var rootContext;
00323 
00324   try {
00325     // Obtain a reference to the root context of the Name service:
00326     CORBA::Object_var obj;
00327     obj = orb->resolve_initial_references("NameService");
00328 
00329     if( CORBA::is_nil(obj) ) {
00330       std::cerr << "Obj is null." << std::endl;
00331       return 0;
00332     }
00333 
00334     // Narrow the reference returned.
00335     rootContext = CosNaming::NamingContext::_narrow(obj);
00336     if( CORBA::is_nil(rootContext) ) {
00337       std::cerr << "Failed to narrow the root naming context." << std::endl;
00338       return 0;
00339     }
00340   }
00341   catch(CORBA::ORB::InvalidName& ex) {
00342     // This should not happen!
00343     std::cerr << "Service required is invalid [does not exist]." << std::endl;
00344     return 0;
00345   }
00346 
00347   try {
00348     // Bind a context called "test" to the root context:
00349 
00350     CosNaming::Name contextName;
00351     contextName.length(1);
00352     contextName[0].id   = (const char*) "test";       // string copied
00353     contextName[0].kind = (const char*) "saliency"; // string copied
00354     // Note on kind: The kind field is used to indicate the type
00355     // of the object. This is to avoid conventions such as that used
00356     // by files (name.type -- e.g. test.ps = postscript etc.)
00357     CosNaming::NamingContext_var testContext;
00358     try {
00359       // Bind the context to root.
00360       testContext = rootContext->bind_new_context(contextName);
00361     }
00362     catch(CosNaming::NamingContext::AlreadyBound& ex) {
00363       // If the context already exists, this exception will be raised.
00364       // In this case, just resolve the name and assign testContext
00365       // to the object returned:
00366       CORBA::Object_var obj;
00367       obj = rootContext->resolve(contextName);
00368       testContext = CosNaming::NamingContext::_narrow(obj);
00369       if( CORBA::is_nil(testContext) ) {
00370         std::cerr << "Failed to narrow naming context." << std::endl;
00371         return 0;
00372       }
00373     }
00374 
00375     // Bind objref with name Echo to the testContext:
00376     objectName.length(1);
00377 
00378 
00379          bool bound = false;
00380          char CmapID[100];
00381          for (int i=0; i<100 && !bound; i++) {
00382                 sprintf(CmapID, "CMap_%i", i);
00383                 std::cout << "Binding object " << CmapID << std::endl;
00384             objectName[0].id   = (const char *) CmapID;   // string copied
00385             objectName[0].kind = (const char*) "Object"; // string copied
00386 
00387                 bound = true;
00388                 try {
00389                         testContext->bind(objectName, objref);
00390                 }
00391                 catch(CosNaming::NamingContext::AlreadyBound& ex) {
00392                         //testContext->rebind(objectName, objref);
00393                         bound = false;
00394                 }
00395 
00396          }
00397          if (!bound){
00398                 LFATAL("Can not bind object");
00399                 return 0;
00400          } else {
00401          }
00402 
00403 
00404     // Amendment: When using OrbixNames, it is necessary to first try bind
00405     // and then rebind, as rebind on it's own will throw a NotFoundexception if
00406     // the Name has not already been bound. [This is incorrect behaviour -
00407     // it should just bind].
00408   }
00409   catch(CORBA::COMM_FAILURE& ex) {
00410     std::cerr << "Caught system exception COMM_FAILURE -- unable to contact the "
00411          << "naming service." << std::endl;
00412     return 0;
00413   }
00414   catch(CORBA::SystemException&) {
00415     std::cerr << "Caught a CORBA::SystemException while using the naming service."
00416     << std::endl;
00417     return 0;
00418   }
00419 
00420   return 1;
00421 }
00422 
00423 // unbind the object from the name server
00424 void unbindObject (){
00425   CosNaming::NamingContext_var rootContext;
00426 
00427   try {
00428     // Obtain a reference to the root context of the Name service:
00429     CORBA::Object_var obj;
00430     obj = orb->resolve_initial_references("NameService");
00431 
00432     if( CORBA::is_nil(obj) ) {
00433       std::cerr << "Obj is null." << std::endl;
00434                 return;
00435     }
00436 
00437     // Narrow the reference returned.
00438     rootContext = CosNaming::NamingContext::_narrow(obj);
00439     if( CORBA::is_nil(rootContext) ) {
00440       std::cerr << "Failed to narrow the root naming context." << std::endl;
00441                 return;
00442     }
00443   }
00444   catch(CORBA::ORB::InvalidName& ex) {
00445     // This should not happen!
00446     std::cerr << "Service required is invalid [does not exist]." << std::endl;
00447     return;
00448   }
00449 
00450   CosNaming::Name contextName;
00451   contextName.length(2);
00452   contextName[0].id   = (const char*) "test";       // string copied
00453   contextName[0].kind = (const char*) "saliency"; // string copied
00454   contextName[1] = objectName[0];
00455 
00456   rootContext->unbind(contextName);
00457 }
00458 
00459 
00460 
Generated on Sun May 8 08:04:43 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3