00001 /*! @file SceneUnderstanding/play-escape.C Play the escape game using POMDP */ 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/play-escape.C $ 00035 // $Id: play-escape.C 13765 2010-08-06 18:56:17Z lior $ 00036 // 00037 00038 //#include "Image/OpenCVUtil.H" // must be first to avoid conflicting defs of int64, uint64 00039 00040 #include "Component/ModelManager.H" 00041 #include "Image/Image.H" 00042 #include "Image/Transforms.H" 00043 #include "Image/DrawOps.H" 00044 #include "Image/ShapeOps.H" 00045 #include "Image/ColorOps.H" 00046 #include "Image/Rectangle.H" 00047 #include "Image/MathOps.H" 00048 #include "Image/Layout.H" 00049 #include "Media/FrameSeries.H" 00050 #include "Transport/FrameInfo.H" 00051 #include "Raster/GenericFrame.H" 00052 #include "Raster/Raster.H" 00053 #include "GUI/AutomateXWin.H" 00054 #include "GUI/ImageDisplayStream.H" 00055 #include "GUI/XWinManaged.H" 00056 #include "GUI/DebugWin.H" 00057 #include "Neuro/getSaliency.H" 00058 #include "plugins/SceneUnderstanding/POMDP.H" 00059 #include "plugins/SceneUnderstanding/Ganglion.H" 00060 00061 #define KEY_UP 98 00062 #define KEY_DOWN 104 00063 #define KEY_LEFT 100 00064 #define KEY_RIGHT 102 00065 00066 int getKey(nub::ref<OutputFrameSeries> &ofs) 00067 { 00068 const nub::soft_ref<ImageDisplayStream> ids = 00069 ofs->findFrameDestType<ImageDisplayStream>(); 00070 00071 const rutz::shared_ptr<XWinManaged> uiwin = 00072 ids.is_valid() 00073 ? ids->getWindow("Output") 00074 : rutz::shared_ptr<XWinManaged>(); 00075 return uiwin->getLastKeyPress(); 00076 } 00077 00078 00079 //Get the input image 00080 Image<PixRGB<byte> > getImage(AutomateXWin &xwin) 00081 { 00082 int idnum = getIdum(); 00083 00084 Image<PixRGB<byte> > img = xwin.getImage(); 00085 00086 // inplaceColorSpeckleNoise(img, int(img.getSize()*0.50F)); //25% speckle noise 00087 00088 //Add Noise 00089 Image<PixRGB<byte> >::iterator ptr = img.beginw(), stop = img.endw(); 00090 while(ptr != stop) 00091 { 00092 *ptr += (int)(25*gasdev(idnum)); 00093 ++ptr; 00094 } 00095 00096 return img; 00097 00098 } 00099 00100 void doAction(AutomateXWin &xwin,const int action) 00101 { 00102 00103 LINFO("Perform action"); 00104 //with 80% probability the action will succeed, otherwise it will go to a 00105 //perperdiculer location 00106 00107 float prob = randomDouble(); 00108 00109 int newAction = action; 00110 if (prob > 0.80) 00111 { 00112 switch(action) 00113 { 00114 case POMDP::NORTH: 00115 case POMDP::SOUTH: 00116 (prob > 0.90) ? newAction = POMDP::EAST : newAction = POMDP::WEST; 00117 break; 00118 case POMDP::EAST: 00119 case POMDP::WEST: 00120 (prob > 0.90) ? newAction = POMDP::NORTH : newAction = POMDP::SOUTH; 00121 break; 00122 } 00123 LINFO("Action %i newaction %i", action, newAction); 00124 } 00125 00126 switch(newAction) 00127 { 00128 xwin.setFocus(); 00129 case POMDP::NORTH: xwin.sendKey(KEY_UP); break; 00130 case POMDP::SOUTH: xwin.sendKey(KEY_DOWN); break; 00131 case POMDP::WEST: xwin.sendKey(KEY_LEFT); break; 00132 case POMDP::EAST: xwin.sendKey(KEY_RIGHT); break; 00133 } 00134 00135 } 00136 00137 00138 int main(const int argc, const char **argv) 00139 { 00140 MYLOGVERB = LOG_INFO; 00141 ModelManager *mgr = new ModelManager("Test ObjRec"); 00142 00143 nub::ref<GetSaliency> getSaliency(new GetSaliency(*mgr)); 00144 mgr->addSubComponent(getSaliency); 00145 00146 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(*mgr)); 00147 mgr->addSubComponent(ofs); 00148 00149 POMDP pomdp; 00150 Ganglion ganglionCells; 00151 00152 mgr->exportOptions(MC_RECURSE); 00153 00154 if (mgr->parseCommandLine( 00155 (const int)argc, (const char**)argv, "", 0, 0) == false) 00156 return 1; 00157 00158 mgr->start(); 00159 00160 AutomateXWin xwin("escape 200606190"); 00161 00162 bool runPOMDP = false; 00163 Layout<PixRGB<byte> > outDisp; 00164 00165 Image< PixRGB<byte> > inputImg = getImage(xwin); 00166 pomdp.init(); 00167 ganglionCells.init(inputImg.getDims()); 00168 00169 00170 00171 00172 float surprise = 0; 00173 while(1) 00174 { 00175 00176 inputImg = getImage(xwin); 00177 00178 ganglionCells.setInput(inputImg); 00179 00180 if (runPOMDP) 00181 { 00182 00183 //get The current Perception 00184 LINFO("Get perception"); 00185 Image<float> agentPercep = pomdp.getPerception(0); 00186 SHOWIMG(agentPercep); 00187 //SHOWIMG(scaleBlock(agentPercep, agentPercep.getDims()*5)); 00188 00189 int action = -1; //pomdp.getPropAction(); 00190 00191 if (action == -1) 00192 { 00193 //choose a random action 00194 action = randomUpToNotIncluding(4)+1; 00195 } else { 00196 LINFO("Make prediction"); 00197 //Make predication 00198 //Image<float> predict = pomdp.makePrediction(action); 00199 //SHOWIMG(scaleBlock(predict, predict.getDims()*5)); 00200 } 00201 action = 0; 00202 LINFO("Action is %i\n", action); 00203 00204 00205 LINFO("Bayes filter to update perception"); 00206 //float surprise = pomdp.bayesFilter(action, inputImg); 00207 float surprise = pomdp.particleFilter(action, inputImg); 00208 LINFO("Surprise %f", surprise); 00209 00210 LINFO("Get perception"); 00211 agentPercep = pomdp.getPerception(0); 00212 SHOWIMG(agentPercep); 00213 00214 00215 //LINFO("Update perception"); 00216 ////Get Data and update Perception 00217 //inputImg = xwin.getImage(); 00218 //surprise = pomdp.updatePerception(inputImg); 00219 //LINFO("Surprise %f\n", surprise); 00220 00221 //if (surprise > 0) 00222 //{ 00223 // LINFO("What happend?, Learning"); 00224 // //pomdp.updateStateTransitions(action); 00225 // sleep(5); 00226 //} else { 00227 // //if we are exploring and there are no suprises then 00228 // //we know about the current world, try to find a solution 00229 // if (pomdp.isExploring()) 00230 // { 00231 // runPOMDP = false; 00232 // } 00233 //} 00234 00235 00236 00237 // SHOWIMG(scaleBlock(agentPercep, agentPercep.getDims()*5)); 00238 00239 00240 LINFO("Show found objects"); 00241 //Show the found objects 00242 Point2D<int> agentState = pomdp.getAgentState(); 00243 Point2D<int> goalState = pomdp.getGoalState(); 00244 00245 if (agentState.isValid()) 00246 drawCircle(inputImg, agentState, 20, PixRGB<byte>(255,0,0)); 00247 00248 if (goalState.isValid()) 00249 drawCircle(inputImg, goalState, 20, PixRGB<byte>(0,255,0)); 00250 00251 LINFO("%ix%i %ix%i\n", agentState.i, agentState.j, 00252 goalState.i, goalState.j); 00253 00254 //Show supprise 00255 00256 00257 } 00258 00259 char msg[255]; 00260 sprintf(msg, "Surprise %0.2f", surprise); 00261 writeText(inputImg, Point2D<int>(0,0), msg, PixRGB<byte>(255), PixRGB<byte>(127) ); 00262 //outDisp = inputImg; 00263 00264 Image<float> gangIn = ganglionCells.getInput(); 00265 Image<float> gangOut = ganglionCells.getOutput(); 00266 Image<float> gangPerc = ganglionCells.getGanglionCells(); 00267 00268 //Display result 00269 inplaceNormalize(gangIn, 0.0F, 255.0F); 00270 inplaceNormalize(gangPerc, 0.0F, 255.0F); 00271 inplaceNormalize(gangOut, 0.0F, 255.0F); 00272 00273 outDisp = hcat(toRGB(Image<byte>(gangIn)), toRGB(Image<byte>(gangPerc))); 00274 outDisp = hcat(outDisp, toRGB(Image<byte>(gangOut))); 00275 00276 ofs->writeRgbLayout(outDisp, "Output", FrameInfo("output", SRC_POS)); 00277 00278 00279 int key = getKey(ofs); 00280 00281 if (key != -1) 00282 { 00283 xwin.setFocus(); 00284 // xwin.sendKey(key); 00285 00286 switch (key) 00287 { 00288 case 27: //r to restart game 00289 if (runPOMDP) 00290 runPOMDP = false; 00291 else 00292 { 00293 runPOMDP = true; //run the controller 00294 LINFO("POMDP running"); 00295 00296 sleep(1); 00297 for(int i=0; i<10; i++) //wait for reset 00298 { 00299 outDisp = inputImg; 00300 ofs->writeRgbLayout(outDisp, "Output", FrameInfo("output", SRC_POS)); 00301 } 00302 inputImg = xwin.getImage(); 00303 00304 //LINFO("Get Initial Observation"); 00305 //if (pomdp.makeObservation(inputImg)) 00306 //{ 00307 //// //New input, plan the actions 00308 //// Point2D<int> agentState = pomdp.getAgentState(); 00309 00310 //// //new Observation, calculate optimal solution 00311 //// pomdp.valueIteration(); 00312 //// pomdp.doPolicy(agentState); 00313 //} 00314 } 00315 break; 00316 00317 case KEY_UP: doAction(xwin, POMDP::NORTH); break; 00318 case KEY_DOWN: doAction(xwin, POMDP::SOUTH); break; 00319 case KEY_RIGHT: doAction(xwin, POMDP::EAST); break; 00320 case KEY_LEFT: doAction(xwin, POMDP::WEST); break; 00321 00322 } 00323 LINFO("Key = %i\n", key); 00324 } 00325 00326 00327 } 00328 mgr->stop(); 00329 00330 return 0; 00331 00332 } 00333