00001 /*!@file Corba/Objects/CMap.H */ 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/Objects/CMap.H $ 00035 // $Id: CMap.H 9412 2008-03-10 23:10:15Z farhan $ 00036 // 00037 00038 #ifndef CMAP_H 00039 #define CMAP_H 00040 00041 #include "Corba/Objects/CMapSK.hh" 00042 #include "Corba/ImageOrbUtil.H" 00043 #include "Corba/CorbaUtil.H" 00044 #include "Image/PyramidTypes.H" 00045 00046 static omni_mutex CMapWorkerThreadMutex; 00047 00048 //the worker cmap threads 00049 class CMapWorkerThread : public omni_thread { 00050 00051 public: 00052 CMapWorkerThread(CMap_ptr cmap, Image<float> &dst, Image<byte> &img, PyramidType ptype, 00053 double ori, double weight, int &frame, bool isUndetached) : th_dst(dst), th_bias(NULL), 00054 th_ptype(ptype), th_ori(ori), th_weight(weight), th_frame(frame) { 00055 00056 CMapObj = cmap; 00057 th_img1 = img; //copy the image incase it changes 00058 00059 LDEBUG("Starting thread for with %i %g %g\n", ptype, ori, weight); 00060 00061 runBias = false; 00062 if (isUndetached) 00063 start_undetached(); 00064 else 00065 start(); 00066 } 00067 00068 CMapWorkerThread(CMap_ptr cmap, Image<float> &dst, Image<byte> &img, PyramidType ptype, 00069 double ori, double weight, int &frame, std::vector<float> &bias, bool isUndetached) : 00070 th_dst(dst), th_ptype(ptype), th_ori(ori), th_weight(weight), th_frame(frame) { 00071 00072 CMapObj = cmap; 00073 th_img1 = img; //copy the image incase it changes 00074 00075 th_bias = new CMap::BiasSeq; 00076 th_bias->length(bias.size()); 00077 for(uint i=0; i<bias.size(); i++) 00078 (*th_bias)[i] = bias[i]; 00079 00080 00081 LDEBUG("Starting thread for with %i %g %g\n", ptype, ori, weight); 00082 00083 runBias = true; 00084 if (isUndetached) 00085 start_undetached(); 00086 else 00087 start(); 00088 } 00089 00090 ~CMapWorkerThread(){} 00091 00092 private: 00093 Image<byte> th_img1; 00094 Image<byte> th_img2; 00095 Image<float> &th_dst; 00096 CMap::BiasSeq *th_bias; 00097 00098 PyramidType th_ptype; 00099 double th_ori; 00100 double th_weight; 00101 int &th_frame; 00102 CMap_ptr CMapObj; 00103 bool runBias; 00104 00105 void* run_undetached(void *ptr){ 00106 LDEBUG("Start undetached"); 00107 processCMap(); 00108 00109 return NULL; 00110 } 00111 00112 void run(void *ptr){ 00113 LDEBUG("Start detached"); 00114 processCMap(); 00115 } 00116 00117 void processCMap (){ 00118 //process the thread 00119 00120 ImageOrb *imgOrb; 00121 00122 if (runBias){ 00123 LDEBUG("Biasing cmap"); 00124 00125 00126 imgOrb = CMapObj->computeBiasCMAP(*image2Orb(th_img1), 00127 th_ptype, th_ori, th_weight, *th_bias); 00128 } else { 00129 LDEBUG("Unbias CMap"); 00130 imgOrb = CMapObj->computeCMAP(*image2Orb(th_img1), 00131 th_ptype, th_ori, th_weight); 00132 } 00133 00134 00135 Image<byte> tmp; 00136 orb2Image(*imgOrb, tmp); 00137 delete imgOrb; 00138 00139 //here we assign the results to the image givien. Need to insure we dont 00140 //conflict with another thred writing to the same image space 00141 CMapWorkerThreadMutex.lock(); 00142 th_dst = tmp; //convert to float 00143 CMapWorkerThreadMutex.unlock(); 00144 th_frame++; //update how many frames have we proceesd 00145 } 00146 00147 00148 }; 00149 00150 // The main thread manegemnt class the spawns the worker threads 00151 class CMapThreads { 00152 public: 00153 CMapThreads(CORBA::ORB_ptr orb) 00154 { 00155 nCmapObj = 0; 00156 initObject(orb); 00157 } 00158 00159 //start a new thread and return the thread address 00160 //if isUndetrached is true then Join needs to be called 00161 CMapWorkerThread* newth(Image<float> &dst, Image<byte> &img, PyramidType ptype, 00162 double ori, double weight, int &frame, bool isUndetached = false) 00163 { 00164 CMap_ptr CMap = getCmapRef(); //get the object to send to 00165 return new CMapWorkerThread(CMap, dst, img, ptype, ori, weight,frame, isUndetached); 00166 } 00167 00168 CMapWorkerThread* newth(Image<float> &dst, Image<byte> &img, PyramidType ptype, 00169 double ori, double weight, int &frame, std::vector<float> &bias, 00170 bool isUndetached = false) 00171 { 00172 CMap_ptr CMap = getCmapRef(); //get the object to send to 00173 return new CMapWorkerThread(CMap, dst, img, ptype, ori, weight,frame, bias, isUndetached); 00174 } 00175 00176 std::vector<float> &getBias(Image<float> &dst, Image<byte> &img, PyramidType ptype, 00177 double ori, double weight, int &frame, Point2D<int> &loc) 00178 { 00179 Point2DOrb locOrb; 00180 locOrb.i = loc.i; locOrb.j = loc.j; 00181 00182 CMap_ptr CMap = getCmapRef(); //get the object to send to 00183 CMap::BiasSeq *bias = CMap->getBiasCMAP(*image2Orb(img), 00184 ptype, ori, weight, locOrb); 00185 std::vector<float> *retBias = new std::vector<float>(bias->length()); 00186 00187 for (uint i=0; i<bias->length(); i++){ 00188 (*retBias)[i] = (*bias)[i]; 00189 } 00190 00191 return *retBias; 00192 00193 } 00194 00195 private: 00196 00197 //!Number of cmap objects that we have running 00198 int nCmapObj; 00199 CORBA::Object_ptr CMap_ref[100]; //100 is the limit for now TODO: watch for overflow 00200 00201 00202 //!The current cmap object to send the request to 00203 CMap_var getCmapRef(){ 00204 static int current_obj = 0; 00205 00206 //just do a round robin 00207 current_obj = (current_obj+1)%nCmapObj; 00208 00209 LDEBUG("Using cmap object number %i\n", current_obj); 00210 00211 return CMap::_narrow(CMap_ref[current_obj]); 00212 } 00213 00214 void initObject(CORBA::ORB_ptr orb) { 00215 LDEBUG("Initalizing CMap object"); 00216 if (!getMultiObjectRef(orb, "test.saliency", CMap_ref, nCmapObj)){ 00217 LFATAL("Can not find any object to bind with"); 00218 } 00219 00220 } 00221 }; 00222 00223 #endif 00224