00001 /*!@file AppNeuro/test-intVisualCortex.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: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppNeuro/test-intVisualCortex.C $ 00035 // $Id: test-intVisualCortex.C 10987 2009-03-05 19:47:46Z itti $ 00036 // 00037 00038 #ifndef APPNEURO_TEST_INTVISUALCORTEX_C_DEFINED 00039 #define APPNEURO_TEST_INTVISUALCORTEX_C_DEFINED 00040 00041 #include "Channels/ChannelOpts.H" 00042 #include "Channels/IntegerInput.H" 00043 #include "Channels/IntegerMathEngine.H" 00044 #include "Component/ModelManager.H" 00045 #include "Component/ModelOptionDef.H" 00046 #include "Component/ModelParam.H" 00047 #include "Image/Image.H" 00048 #include "Image/ColorOps.H" 00049 #include "Image/DrawOps.H" 00050 #include "Image/Layout.H" 00051 #include "Image/IntegerMathOps.H" 00052 #include "Image/MathOps.H" 00053 #include "Image/PyrBuilder.H" 00054 #include "Image/PyramidCache.H" 00055 #include "Image/PyramidOps.H" 00056 #include "Image/ShapeOps.H" 00057 #include "Media/FrameSeries.H" 00058 #include "Neuro/NeuroOpts.H" 00059 #include "Channels/IntegerRawVisualCortex.H" 00060 #include "Channels/RawVisualCortex.H" 00061 #include "Raster/GenericFrame.H" 00062 #include "Raster/Raster.H" 00063 #include "Transport/FrameInfo.H" 00064 #include "Util/AllocAux.H" 00065 #include "Util/Pause.H" 00066 #include "Util/csignals.H" 00067 #include "rutz/time.h" 00068 00069 static const ModelOptionDef OPT_SaveInputCopy = 00070 { MODOPT_FLAG, "SaveInputCopy", &MOC_DISPLAY, OPTEXP_SAVE, 00071 "Save a copy of the input frame", 00072 "save-input-copy", '\0', "", "false" }; 00073 00074 static const ModelOptionDef OPT_CompareToVC = 00075 { MODOPT_FLAG, "CompareToVC", &MOC_DISPLAY, OPTEXP_SAVE, 00076 "Compare int and float visual cortex outputs", 00077 "compare-to-vc", '\0', "", "true" }; 00078 00079 static const ModelOptionDef OPT_ALIASsaveall = 00080 { MODOPT_ALIAS, "ALIASsaveall", &MOC_DISPLAY, OPTEXP_SAVE, 00081 "Default save option for test-intVisualCortex", 00082 "saveall", '\0', "", 00083 "--save-channel-outputs --save-vcx-output --save-input-copy" }; 00084 00085 // ###################################################################### 00086 int submain(int argc, const char** argv) 00087 { 00088 volatile int signum = 0; 00089 catchsignals(&signum); 00090 00091 ModelManager manager("test-intChannel"); 00092 00093 OModelParam<bool> saveInput(&OPT_SaveInputCopy, &manager); 00094 OModelParam<bool> compareToVC(&OPT_CompareToVC, &manager); 00095 OModelParam<IntegerDecodeType> decodeType(&OPT_IntInputDecode, &manager); 00096 00097 // Instantiate our various ModelComponents: 00098 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(manager)); 00099 manager.addSubComponent(ifs); 00100 00101 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager)); 00102 manager.addSubComponent(ofs); 00103 00104 nub::ref<IntegerMathEngine> ieng(new IntegerMathEngine(manager)); 00105 manager.addSubComponent(ieng); 00106 00107 nub::ref<IntegerRawVisualCortex> ivc(new IntegerRawVisualCortex(manager, ieng)); 00108 manager.addSubComponent(ivc); 00109 00110 nub::ref<RawVisualCortex> vc(new RawVisualCortex(manager)); 00111 manager.addSubComponent(vc); 00112 00113 REQUEST_OPTIONALIAS_CHANNEL(manager); 00114 manager.requestOptionAlias(&OPT_ALIASsaveall); 00115 00116 manager.setOptionValString(&OPT_MaxNormType, "Maxnorm"); 00117 manager.setOptionValString(&OPT_DirectionChannelLowThresh, "0"); 00118 manager.setOptionValString(&OPT_IntChannelScaleBits, "16"); 00119 manager.setOptionValString(&OPT_IntMathLowPass5, "lp5optim"); 00120 manager.setOptionValString(&OPT_IntMathLowPass9, "lp9optim"); 00121 manager.setOptionValString(&OPT_RawVisualCortexOutputFactor, "1.0"); // look at raw values 00122 00123 // Parse command-line: 00124 if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1); 00125 00126 manager.start(); 00127 00128 LINFO("using %u bits for integer arithmetic", ieng->getNbits()); 00129 LINFO("using '%s' decoding algorithm", convertToString(decodeType.getVal()).c_str()); 00130 00131 int c = 0; PauseWaiter p; SimTime t; PyramidCache<int> cache; size_t npixels = 0; 00132 00133 rutz::time r1 = rutz::time::wall_clock_now(); 00134 rutz::time u1 = rutz::time::user_rusage(); 00135 rutz::time s1 = rutz::time::sys_rusage(); 00136 00137 while (true) 00138 { 00139 if (signum != 0) { LINFO("quitting because %s was caught", signame(signum)); return -1; } 00140 00141 t += SimTime::HERTZ(30); 00142 00143 if (p.checkPause()) continue; 00144 00145 const FrameState is = ifs->updateNext(); 00146 if (is == FRAME_COMPLETE) break; 00147 00148 GenericFrame input = ifs->readFrame(); 00149 if (!input.initialized()) break; 00150 00151 npixels = size_t(input.getDims().sz()); 00152 Image< PixRGB<byte> > inputimg = input.asRgb(); 00153 const IntegerInput ii = IntegerInput::decode(input, decodeType.getVal(), ieng->getNbits()); 00154 ivc->inputInt(ii, t, &cache); 00155 if (compareToVC.getVal()) vc->input(InputFrame::fromRgb(&inputimg, t)); 00156 00157 Image<int> ivcout = ivc->getOutputInt(); 00158 Image<float> vcout; if (compareToVC.getVal()) vcout = vc->getOutput(); 00159 00160 const FrameState os = ofs->updateNext(); 00161 if (saveInput.getVal()) ofs->writeFrame(input, "input", FrameInfo("copy of input frame", SRC_POS)); 00162 ivc->saveResults(ofs); 00163 if (compareToVC.getVal()) 00164 { 00165 // do the int map: 00166 int mini, maxi, a, b; getMinMax(ivcout, mini, maxi); 00167 const std::string irng = sformat("[%d .. %d]", mini, maxi); 00168 intgInplaceNormalize(ivcout, 0, 255, &a, &b); Image<byte> bivcout = ivcout; 00169 00170 Image<PixRGB<byte> > map1 = rescaleOpt(makeRGB(bivcout,bivcout,bivcout), input.getDims(), false); 00171 drawRect(map1, Rectangle(Point2D<int>(0, 0), map1.getDims()), PixRGB<byte>(128, 128, 255)); 00172 writeText(map1, Point2D<int>(1,1), " Integer Salmap ", PixRGB<byte>(255,255,64), 00173 PixRGB<byte>(0), SimpleFont::FIXED(10), true); 00174 writeText(map1, Point2D<int>(3, map1.getHeight() - 3), irng.c_str(), PixRGB<byte>(255,255,64), 00175 PixRGB<byte>(0), SimpleFont::FIXED(6), true, ANCHOR_BOTTOM_LEFT); 00176 00177 // do the float map: 00178 float fmini, fmaxi; getMinMax(vcout, fmini, fmaxi); 00179 inplaceNormalize(vcout, 0.0F, 255.0F); Image<byte> bvcout = vcout; 00180 const std::string rng = sformat("[%f .. %f]", fmini, fmaxi); 00181 00182 Image<PixRGB<byte> > map2 = rescaleOpt(makeRGB(bvcout,bvcout,bvcout), input.getDims(), false); 00183 drawRect(map2, Rectangle(Point2D<int>(0, 0), map2.getDims()), PixRGB<byte>(128, 128, 255)); 00184 writeText(map2, Point2D<int>(1,1), " Float Salmap ", PixRGB<byte>(255,255,64), 00185 PixRGB<byte>(0), SimpleFont::FIXED(10), true); 00186 writeText(map2, Point2D<int>(3, map2.getHeight() - 3), rng.c_str(), PixRGB<byte>(255,255,64), 00187 PixRGB<byte>(0), SimpleFont::FIXED(6), true, ANCHOR_BOTTOM_LEFT); 00188 00189 // do the difference map (note some promoting to int will occur and prevent overflows): 00190 Image<byte> diff = ((bvcout - bivcout)) / 2 + 127; 00191 Image<PixRGB<byte> > map3 = rescaleOpt(makeRGB(diff,diff,diff), input.getDims(), false); 00192 drawRect(map3, Rectangle(Point2D<int>(0, 0), map3.getDims()), PixRGB<byte>(128, 128, 255)); 00193 writeText(map3, Point2D<int>(1,1), " Float - Int ", PixRGB<byte>(255,255,64), 00194 PixRGB<byte>(0), SimpleFont::FIXED(10), true); 00195 std::string msg = sformat("[float = %g * int]", fmaxi / maxi); 00196 writeText(map3, Point2D<int>(3, map2.getHeight() - 3), msg.c_str(), PixRGB<byte>(255,255,64), 00197 PixRGB<byte>(0), SimpleFont::FIXED(6), true, ANCHOR_BOTTOM_LEFT); 00198 00199 Layout< PixRGB<byte> > disp = vcat(hcat(input.asRgb(), map3), hcat(map1, map2)); 00200 ofs->writeRGB(disp.render(), "combo", FrameInfo("combo display output", SRC_POS)); 00201 } 00202 00203 if (os == FRAME_FINAL) break; 00204 LINFO("frame %d", c); ++c; 00205 00206 if (ifs->shouldWait() || ofs->shouldWait()) Raster::waitForKey(); 00207 } 00208 00209 rutz::time r2 = rutz::time::wall_clock_now(); 00210 rutz::time u2 = rutz::time::user_rusage(); 00211 rutz::time s2 = rutz::time::sys_rusage(); 00212 00213 const rutz::time irreal = (r2 - r1); 00214 const rutz::time iruser = (u2 - u1); 00215 const rutz::time irsys = (s2 - s1); 00216 invt_allocation_show_stats(1, "final", npixels); 00217 LINFO("integer code: %.2es real; %.2es user + sys", irreal.sec(), (iruser + irsys).sec()); 00218 00219 manager.stop(); 00220 return 0; 00221 } 00222 00223 int main(const int argc, const char **argv) 00224 { 00225 try 00226 { 00227 return submain(argc, argv); 00228 } 00229 catch (...) 00230 { 00231 REPORT_CURRENT_EXCEPTION; 00232 } 00233 00234 return 1; 00235 } 00236 00237 // ###################################################################### 00238 /* So things look consistent in everyone's emacs... */ 00239 /* Local Variables: */ 00240 /* mode: c++ */ 00241 /* indent-tabs-mode: nil */ 00242 /* End: */ 00243 00244 #endif // APPNEURO_TEST_INTVISUALCORTEX_C_DEFINED