00001 /*!@file SceneUnderstanding/Objects.C */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 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: Lior Elazary <elazary@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/plugins/SceneUnderstanding/Objects.C $ 00035 // $Id: Objects.C 13765 2010-08-06 18:56:17Z lior $ 00036 // 00037 00038 #ifndef Objects_C_DEFINED 00039 #define Objects_C_DEFINED 00040 00041 #include "Image/DrawOps.H" 00042 #include "Image/MathOps.H" 00043 //#include "Image/OpenCVUtil.H" 00044 #include "Image/Kernels.H" 00045 #include "Image/FilterOps.H" 00046 #include "Image/Transforms.H" 00047 #include "Image/fancynorm.H" 00048 #include "Image/Convolutions.H" 00049 #include "Image/MatrixOps.H" 00050 #include "Simulation/SimEventQueue.H" 00051 #include "plugins/SceneUnderstanding/Objects.H" 00052 #include "GUI/DebugWin.H" 00053 #include <math.h> 00054 #include <fcntl.h> 00055 #include <limits> 00056 #include <string> 00057 00058 const ModelOptionCateg MOC_Objects = { 00059 MOC_SORTPRI_3, "Objects-Related Options" }; 00060 00061 // Used by: SimulationViewerEyeMvt 00062 const ModelOptionDef OPT_ObjectsShowDebug = 00063 { MODOPT_ARG(bool), "ObjectsShowDebug", &MOC_Objects, OPTEXP_CORE, 00064 "Show debug img", 00065 "Objects-debug", '\0', "<true|false>", "false" }; 00066 00067 00068 // ###################################################################### 00069 Objects::Objects(OptionManager& mgr, const std::string& descrName, 00070 const std::string& tagName) : 00071 SimModule(mgr, descrName, tagName), 00072 SIMCALLBACK_INIT(SimEventGeons3DOutput), 00073 SIMCALLBACK_INIT(SimEventSaveOutput), 00074 SIMCALLBACK_INIT(SimEventUserInput), 00075 itsShowDebug(&OPT_ObjectsShowDebug, this), 00076 itsProb(0) 00077 { 00078 00079 initRandomNumbers(); 00080 00081 Table* table = new Table(); 00082 table->pos = Point3D<double>(-3.60,-7.30,-5.00); 00083 table->rotation = Point3D<double>(0.31,-0.15,0.31); 00084 table->tableWidth = 6.01; 00085 table->tableLength = 4.50; 00086 table->legHeight = 4.00; 00087 table->legWidth = 0.50; 00088 00089 //itsObjectsState.push_back(ObjectState(TABLE, Point3D<float>(0,0,0), Point3D<float>(0,0,0))); 00090 itsObjectsState.push_back(table); 00091 00092 //Table* table2 = new Table(); 00093 //table2->pos = Point3D<double>(-2.60,-7.30,-5.00); 00094 //table2->rotation = Point3D<double>(0.31,-0.15,0.31); 00095 //table2->tableWidth = 6.01; 00096 //table2->tableLength = 4.50; 00097 //table2->legHeight = 4.00; 00098 //table2->legWidth = 0.50; 00099 //itsObjectsState.push_back(table2); 00100 00101 00102 } 00103 00104 // ###################################################################### 00105 Objects::~Objects() 00106 { 00107 } 00108 00109 // ###################################################################### 00110 void Objects::onSimEventGeons3DOutput(SimEventQueue& q, 00111 rutz::shared_ptr<SimEventGeons3DOutput>& e) 00112 { 00113 itsGeons = e->getGeons(); 00114 itsProb = e->getProb(); 00115 evolve(q); 00116 00117 //q.post(rutz::make_shared(new SimEventObjectsOutput(this, itsEdgesState, itsCornersState))); 00118 00119 } 00120 00121 // ###################################################################### 00122 void Objects::onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e) 00123 { 00124 if (itsShowDebug.getVal()) 00125 { 00126 // get the OFS to save to, assuming sinfo is of type 00127 // SimModuleSaveInfo (will throw a fatal exception otherwise): 00128 nub::ref<FrameOstream> ofs = 00129 dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs; 00130 Layout<PixRGB<byte> > disp = getDebugImage(q); 00131 ofs->writeRgbLayout(disp, "Objects", FrameInfo("Objects", SRC_POS)); 00132 } 00133 } 00134 00135 // ###################################################################### 00136 void Objects::onSimEventUserInput(SimEventQueue& q, rutz::shared_ptr<SimEventUserInput>& e) 00137 { 00138 00139 LINFO("Got event %s %ix%i key=%i", 00140 e->getWinName(), 00141 e->getMouseClick().i, 00142 e->getMouseClick().j, 00143 e->getKey()); 00144 00145 if (e->getMouseClick().isValid()) 00146 { 00147 } 00148 00149 ObjectState* object = itsObjectsState[0]; 00150 Table* table = (Table*)object; 00151 switch(e->getKey()) 00152 { 00153 case 98: //up 00154 object->pos.x -= 0.1; 00155 break; 00156 case 104: //down 00157 object->pos.x += 0.1; 00158 break; 00159 case 100: //left 00160 object->pos.y -= 0.1; 00161 break; 00162 case 102: //right 00163 object->pos.y += 0.1; 00164 break; 00165 case 21: //= 00166 object->pos.z += 0.1; 00167 break; 00168 case 20: //- 00169 object->pos.z -= 0.1; 00170 break; 00171 case 38: //a 00172 object->rotation.x += 1*(M_PI/180); 00173 break; 00174 case 52: //z 00175 object->rotation.x -= 1*(M_PI/180); 00176 break; 00177 case 39: //s 00178 object->rotation.y += 1*(M_PI/180); 00179 break; 00180 case 53: //x 00181 object->rotation.y -= 1*(M_PI/180); 00182 break; 00183 case 40: //d 00184 object->rotation.z += 1*(M_PI/180); 00185 break; 00186 case 54: //c 00187 object->rotation.z -= 1*(M_PI/180); 00188 break; 00189 00190 case 10: //1 00191 table->legHeight -= 0.1; 00192 break; 00193 case 24: //q 00194 table->legHeight += 0.1; 00195 break; 00196 case 11: //2 00197 table->tableWidth += 0.01; 00198 break; 00199 case 25: //w 00200 table->tableWidth -= 0.01; 00201 break; 00202 case 12: //3 00203 table->tableLength += 0.01; 00204 break; 00205 case 26: //e 00206 table->tableLength -= 0.01; 00207 break; 00208 } 00209 00210 LINFO("Pos(%0.2f,%0.2f,%0.2f), rotation((%0.2f,%0.2f,%0.2f), size(%0.2f,%0.2f,%0.2f)", 00211 object->pos.x, object->pos.y, object->pos.z, 00212 object->rotation.x, object->rotation.y, object->rotation.z, 00213 table->tableWidth, table->tableLength,table->legHeight); 00214 00215 00216 evolve(q); 00217 00218 } 00219 00220 void Objects::calcObjectLikelihood(ObjectState& object) 00221 { 00222 00223 } 00224 00225 00226 std::vector<Geons3D::GeonState> Objects::getPrior(ObjectState* object) 00227 { 00228 00229 std::vector<Geons3D::GeonState> geons; 00230 00231 switch(object->type) 00232 { 00233 case TABLE: 00234 Table* table = (Table*)object; 00235 00236 float legXOffset = table->tableWidth/2 - table->legWidth/2; 00237 float legYOffset = table->tableLength/2 - table->legWidth/2; 00238 00239 geons.push_back( 00240 Geons3D::GeonState(Geons3D::BOX, 00241 Point3D<double>(0, 0, 0+table->legHeight/2), 00242 //Point3D<double>(table->pos.x, table->pos.y, table->pos.z+table->legHeight/2), 00243 Point3D<double>(0,0,0), 00244 //table->rotation, 00245 Point3D<double>(1, 1, 1), 00246 Point3D<double>(table->tableWidth,table->tableLength,0.40) )); 00247 geons.push_back( 00248 Geons3D::GeonState(Geons3D::BOX, 00249 Point3D<double>(0-legXOffset, 0-legYOffset,0), 00250 //Point3D<double>(table->pos.x-legXOffset, table->pos.y-legYOffset,table->pos.z), 00251 Point3D<double>(0,0,0), 00252 Point3D<double>(1, 1, 1), 00253 Point3D<double>(table->legWidth,table->legWidth,table->legHeight) )); 00254 geons.push_back( 00255 Geons3D::GeonState(Geons3D::BOX, 00256 Point3D<double>(0+legXOffset, 0-legYOffset,0), 00257 //Point3D<double>(table->pos.x+legXOffset, table->pos.y-legYOffset,table->pos.z), 00258 Point3D<double>(0,0,0), 00259 Point3D<double>(1, 1, 1), 00260 Point3D<double>(table->legWidth,table->legWidth,table->legHeight) )); 00261 geons.push_back( 00262 Geons3D::GeonState(Geons3D::BOX, 00263 Point3D<double>(0-legXOffset, 0+legYOffset,0), 00264 //Point3D<double>(table->pos.x-legXOffset, table->pos.y+legYOffset,table->pos.z), 00265 Point3D<double>(0,0,0), 00266 Point3D<double>(1, 1, 1), 00267 Point3D<double>(table->legWidth,table->legWidth,table->legHeight) )); 00268 geons.push_back( 00269 Geons3D::GeonState(Geons3D::BOX, 00270 Point3D<double>(0+legXOffset, 0+legYOffset,0), 00271 //Point3D<double>(table->pos.x+legXOffset, table->pos.y+legYOffset,table->pos.z), 00272 Point3D<double>(0,0,0), 00273 Point3D<double>(1, 1, 1), 00274 Point3D<double>(table->legWidth,table->legWidth,table->legHeight) )); 00275 break; 00276 } 00277 00278 return geons; 00279 00280 } 00281 00282 Objects::ObjectState* Objects::proposeState(ObjectState* object) 00283 { 00284 // ###################################################################### 00285 00286 object->lastSample = (object->lastSample +1)%2; 00287 00288 //TODO: Check for object type 00289 //Table* table = (Table*)object; 00290 00291 Table* table = new Table(); 00292 table->pos = Point3D<double>(-3.60,-7.30,-5.00); 00293 table->rotation = Point3D<double>(0.31,-0.15,0.31); 00294 table->tableWidth = 6.01; 00295 table->tableLength = 4.50; 00296 table->legHeight = 4.00; 00297 table->legWidth = 0.50; 00298 00299 switch(object->lastSample) 00300 { 00301 case 0: 00302 { 00303 Point3D<double> randLoc( 00304 randomDoubleFromNormal(0.10), 00305 randomDoubleFromNormal(0.10), 00306 randomDoubleFromNormal(0.10)); 00307 table->pos += randLoc; 00308 } 00309 break; 00310 case 1: 00311 { 00312 Point3D<double> randRot( 00313 randomDoubleFromNormal(0.5)*M_PI/180, 00314 randomDoubleFromNormal(0.5)*M_PI/180, 00315 randomDoubleFromNormal(0.5)*M_PI/180); 00316 table->rotation += randRot; 00317 } 00318 break; 00319 case 2: 00320 //newSketch.params.x += randomDoubleFromNormal(0.25); 00321 //if (newSketch.params.x <= 0.1) 00322 // newSketch.params.x = 0.1; 00323 break; 00324 case 3: 00325 //newSketch.params.y += randomDoubleFromNormal(0.25); 00326 //if (newSketch.params.y <= 0.1) 00327 // newSketch.params.y = 0.1; 00328 break; 00329 } 00330 00331 return table; 00332 00333 } 00334 00335 00336 // ###################################################################### 00337 void Objects::evolve(SimEventQueue& q) 00338 { 00339 //double totalProb = 0; 00340 00341 for(uint i=0; i<itsObjectsState.size(); i++) 00342 { 00343 ObjectState* newObject = proposeState(itsObjectsState[i]); 00344 00345 //ObjectState newObject = itsObjectsState[i]; 00346 //calcObjectLikelihood(itsObjectsState[i]); 00347 00348 00349 00350 //send prior; 00351 std::vector<Geons3D::GeonState> geons = getPrior(newObject); 00352 q.post(rutz::make_shared(new SimEventGeons3DPrior(this, geons, 00353 newObject->pos, newObject->rotation))); 00354 00355 delete newObject; 00356 } 00357 } 00358 00359 00360 00361 Layout<PixRGB<byte> > Objects::getDebugImage(SimEventQueue& q) 00362 { 00363 //evolve(q); 00364 Layout<PixRGB<byte> > outDisp; 00365 00366 //Image<float> input(512,512, ZEROS); 00367 //for(uint i=0; i<itsV1Edges.size(); i++) 00368 // input.setVal(itsV1Edges[i].pos, itsV1Edges[i].prob); 00369 //inplaceNormalize(input, 0.0F, 255.0F); 00370 00371 //for(uint i=0; i<itsLinesState.size(); i++) 00372 //{ 00373 // LineState line = itsLinesState[i]; 00374 // //drawLine(perc, line.pos, line.ori, line.length, PixRGB<byte>((float)line.nProb,0,0), 1); 00375 // // if (line.prob > -500) 00376 // { 00377 // drawLine(perc, line.pos, line.ori, line.length, PixRGB<byte>(255,0,0), 1); 00378 // // LINFO("%i %ix%i %f %f %f", 00379 // // i, line.pos.i, line.pos.j, line.ori, line.length, line.prob); 00380 // } 00381 //} 00382 00383 00384 //outDisp = hcat(toRGB(Image<byte>(input)), perc); 00385 00386 return outDisp; 00387 00388 } 00389 00390 00391 // ###################################################################### 00392 /* So things look consistent in everyone's emacs... */ 00393 /* Local Variables: */ 00394 /* indent-tabs-mode: nil */ 00395 /* End: */ 00396 00397 #endif 00398