00001 /*!@file Neuro/TargetChecker.C check+count targets hit during a neural simulation */ 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: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/TargetChecker.C $ 00035 // $Id: TargetChecker.C 13065 2010-03-28 00:01:00Z itti $ 00036 // 00037 00038 #ifndef NEURO_TARGETCHECKER_C_DEFINED 00039 #define NEURO_TARGETCHECKER_C_DEFINED 00040 00041 #include "Neuro/TargetChecker.H" 00042 00043 #include "Channels/InputFrame.H" 00044 #include "Component/GlobalOpts.H" 00045 #include "Component/OptionManager.H" 00046 #include "Image/DrawOps.H" 00047 #include "Image/MathOps.H" 00048 #include "Image/Transforms.H" 00049 #include "Neuro/NeuroOpts.H" 00050 #include "Raster/Raster.H" 00051 #include "Util/TextLog.H" 00052 #include "Util/sformat.H" 00053 #include "Simulation/SimEvents.H" 00054 #include "Neuro/NeuroSimEvents.H" 00055 #include "Simulation/SimEventQueue.H" 00056 00057 // ###################################################################### 00058 TargetChecker::TargetChecker(OptionManager& mgr, const std::string& descrName, 00059 const std::string& tagName) 00060 : 00061 SimModule(mgr, descrName, tagName), 00062 SIMCALLBACK_INIT(SimEventWTAwinner), 00063 SIMCALLBACK_INIT(SimEventRetinaImage), 00064 SIMCALLBACK_INIT(SimEventTargetMask), 00065 itsFOAradius(&OPT_FOAradius, this), 00066 itsLogFile(&OPT_TextLogFile, this), 00067 itsTargetMaskFname(&OPT_TargetMaskFname, this), 00068 itsVisualField(), 00069 itsRawTargetMask(), 00070 itsTargetMask(), 00071 itsNumTargetsRemaining(0) 00072 { } 00073 00074 // ###################################################################### 00075 TargetChecker::~TargetChecker() 00076 { } 00077 00078 // ###################################################################### 00079 void TargetChecker::reset1() 00080 { 00081 itsVisualField.freeMem(); 00082 SimModule::reset1(); 00083 } 00084 00085 // ###################################################################### 00086 void TargetChecker:: 00087 onSimEventWTAwinner(SimEventQueue& q, rutz::shared_ptr<SimEventWTAwinner>& e) 00088 { 00089 // is there a new attention shift? If so, we want to check whether 00090 // one or more of our targets were hit: 00091 const WTAwinner winner = e->winner(); 00092 00093 // draw in the visual field, and count the new targets hit if we 00094 // have a target mask: 00095 if (itsTargetMask.initialized()) 00096 { 00097 // draw a disk anc count how many targets we hit: 00098 const int numhit = 00099 drawDiskCheckTarget(itsVisualField, itsTargetMask, winner.p, 00100 itsFOAradius.getVal(), byte(255), byte(255), byte(250)); 00101 00102 // did we hit any targets, as defined by our itsTargetMask? 00103 if (numhit > 0) 00104 { 00105 LINFO("###### %d new target(s) hit at t=%fms ######", numhit, winner.t.msecs()); 00106 itsNumTargetsRemaining -= numhit; 00107 00108 textLog(itsLogFile.getVal(), "HitTargets", sformat("%d", numhit), winner.t); 00109 00110 q.post(rutz::shared_ptr<SimEventTargetsHit> (new SimEventTargetsHit(this, numhit))); 00111 } 00112 00113 // are we done with all targets? 00114 if (itsTargetMask.initialized() && itsNumTargetsRemaining <= 0) 00115 { 00116 LINFO("##### All targets found -- EXIT #####"); 00117 textLog(itsLogFile.getVal(), "AllTargetsFound", "", winner.t); 00118 00119 q.post(rutz::shared_ptr<SimEventBreak>(new SimEventBreak(this))); 00120 } 00121 } 00122 00123 // if no target mask, just draw in the visual field: 00124 else if (itsVisualField.initialized()) 00125 drawDisk(itsVisualField, winner.p, itsFOAradius.getVal(), byte(255)); 00126 } 00127 00128 // ###################################################################### 00129 void TargetChecker:: 00130 onSimEventRetinaImage(SimEventQueue& q, rutz::shared_ptr<SimEventRetinaImage>& e) 00131 { 00132 // ok, here is a new input frame! Let's initialize our guts accordingly: 00133 const InputFrame inframe = e->frame(); 00134 00135 if (itsRawTargetMask.initialized()) 00136 { 00137 itsTargetMask = itsRawTargetMask; 00138 inplaceNormalize(itsTargetMask, byte(0), byte(255)); 00139 itsNumTargetsRemaining = countParticles(itsTargetMask, byte(255)); 00140 LINFO("Counting targets... %d detected", itsNumTargetsRemaining); 00141 00142 textLog(itsLogFile.getVal(), "TargetsRemaining", 00143 sformat("%d", itsNumTargetsRemaining), q.now()); 00144 } 00145 else 00146 itsTargetMask.freeMem(); 00147 00148 // initialize visual field if necessary: 00149 if (itsVisualField.isSameSize(inframe.colorByte()) == false) 00150 itsVisualField = Image<byte>(inframe.colorByte().getDims(), ZEROS); 00151 } 00152 00153 // ###################################################################### 00154 void TargetChecker:: 00155 onSimEventTargetMask(SimEventQueue& q, rutz::shared_ptr<SimEventTargetMask>& e) 00156 { 00157 LINFO("Loading new target mask at time %.2fms...", q.now().msecs()); 00158 itsRawTargetMask = e->mask(); 00159 } 00160 00161 // ###################################################################### 00162 void TargetChecker::start1() 00163 { 00164 if (!itsTargetMaskFname.getVal().empty()) 00165 { 00166 itsRawTargetMask = Raster::ReadGray(itsTargetMaskFname.getVal()); 00167 LINFO("Using targetmask from image file %s", itsTargetMaskFname.getVal().c_str()); 00168 } 00169 00170 SimModule::start1(); 00171 } 00172 00173 // ###################################################################### 00174 /* So things look consistent in everyone's emacs... */ 00175 /* Local Variables: */ 00176 /* indent-tabs-mode: nil */ 00177 /* End: */ 00178 00179 #endif // NEURO_TARGETCHECKER_C_DEFINED