test-intChannel.C

Go to the documentation of this file.
00001 /*!@file AppNeuro/test-intChannel.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-intChannel.C $
00035 // $Id: test-intChannel.C 11208 2009-05-20 02:03:21Z itti $
00036 //
00037 
00038 #ifndef APPNEURO_TEST_INTCHANNEL_C_DEFINED
00039 #define APPNEURO_TEST_INTCHANNEL_C_DEFINED
00040 
00041 #include "Channels/BlueYellowChannel.H"
00042 #include "Channels/ChannelOpts.H"
00043 #include "Channels/ColorChannel.H"
00044 #include "Channels/DirectionChannel.H"
00045 #include "Channels/FlickerChannel.H"
00046 #include "Channels/GaborChannel.H"
00047 #include "Channels/IntegerInput.H"
00048 #include "Channels/IntegerMathEngine.H"
00049 #include "Channels/IntegerOrientationChannel.H"
00050 #include "Channels/IntegerSimpleChannel.H"
00051 #include "Channels/IntensityChannel.H"
00052 #include "Channels/MotionChannel.H"
00053 #include "Channels/OrientationChannel.H"
00054 #include "Channels/RedGreenChannel.H"
00055 #include "Channels/SingleChannel.H"
00056 #include "Component/ModelManager.H"
00057 #include "Component/ModelOptionDef.H"
00058 #include "Image/ColorOps.H"
00059 #include "Image/Image.H"
00060 #include "Image/ImageSet.H"
00061 #include "Image/IntegerMathOps.H"
00062 #include "Image/MathOps.H"
00063 #include "Image/Pixels.H"
00064 #include "Image/PyrBuilder.H"
00065 #include "Image/PyramidCache.H"
00066 #include "Image/PyramidOps.H"
00067 #include "Image/ShapeOps.H"
00068 #include "Media/FrameSeries.H"
00069 #include "Neuro/NeuroOpts.H"
00070 #include "Channels/RawVisualCortex.H"
00071 #include "Channels/IntegerRawVisualCortex.H"
00072 #include "Raster/GenericFrame.H"
00073 #include "Raster/Raster.H"
00074 #include "Transport/FrameInfo.H"
00075 #include "Util/Pause.H"
00076 #include "Util/csignals.H"
00077 #include "rutz/time.h"
00078 
00079 #include <map>
00080 
00081 static const ModelOptionDef OPT_ALIASsaveall =
00082   { MODOPT_ALIAS, "ALIASsaveall", &MOC_DISPLAY, OPTEXP_SAVE,
00083     "Default save option for test-intChannel",
00084     "saveall", '\0', "",
00085     "--save-channel-outputs --save-vcx-output" };
00086 
00087 namespace
00088 {
00089   struct ChannelCorrcoefData
00090   {
00091     ChannelCorrcoefData() : sum(0.0), n(0) {}
00092 
00093     void add(double d) { sum += d; ++n; }
00094 
00095     double sum;
00096     int n;
00097   };
00098 
00099   std::map<IntegerChannel*, ChannelCorrcoefData> ccdata;
00100 
00101   void compareChannels(int c,
00102                        IntegerChannel& ic,
00103                        ChannelBase& fc)
00104   {
00105     IntegerComplexChannel* icc =
00106       dynamic_cast<IntegerComplexChannel*>(&ic);
00107 
00108     if (icc != 0)
00109       {
00110         ComplexChannel* fcc =
00111           dynamic_cast<ComplexChannel*>(&fc);
00112 
00113         ASSERT(icc->numChans() == fcc->numChans());
00114 
00115         for (uint i = 0; i < icc->numChans(); ++i)
00116           compareChannels(c, *(icc->subChan(i)), *(fcc->subChan(i)));
00117       }
00118 
00119     float fmi, fma; getMinMax(fc.getOutput(), fmi, fma);
00120     int imi, ima; getMinMax(ic.getOutputInt(), imi, ima);
00121 
00122     const double cc = corrcoef(fc.getOutput(),
00123                                Image<float>(ic.getOutputInt()));
00124     LINFO("%06d corrcoef(%-20s,%-20s) = %.4f, "
00125           "frange = %.2e .. %.2e, irange = %.2e .. %.2e, imax/fmax = %.2e",
00126           c, fc.tagName().c_str(), ic.tagName().c_str(), cc,
00127           fmi, fma, float(imi), float(ima), float(ima) / fma);
00128 
00129     ccdata[&ic].add(cc);
00130   }
00131 }
00132 
00133 // ######################################################################
00134 int submain(int argc, const char** argv)
00135 {
00136   volatile int signum = 0;
00137   catchsignals(&signum);
00138 
00139   IntgTrigTable<256, 8> trig;
00140 
00141   ModelManager manager("test-intChannel");
00142 
00143   OModelParam<IntegerDecodeType> decodeType
00144     (&OPT_IntInputDecode, &manager);
00145 
00146   // Instantiate our various ModelComponents:
00147   nub::ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00148   manager.addSubComponent(ifs);
00149 
00150   nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00151   manager.addSubComponent(ofs);
00152 
00153   nub::ref<RawVisualCortex> fvc(new RawVisualCortex(manager));
00154   manager.addSubComponent(fvc);
00155 
00156   nub::ref<IntegerMathEngine> ieng(new IntegerMathEngine(manager));
00157   manager.addSubComponent(ieng);
00158 
00159   nub::ref<IntegerRawVisualCortex> ivc(new IntegerRawVisualCortex(manager, ieng));
00160   manager.addSubComponent(ivc);
00161 
00162   REQUEST_OPTIONALIAS_CHANNEL(manager);
00163   manager.requestOptionAlias(&OPT_ALIASsaveall);
00164 
00165   manager.setOptionValString(&OPT_MaxNormType, "Maxnorm");
00166   manager.setOptionValString(&OPT_DirectionChannelLowThresh, "0");
00167   manager.setOptionValString(&OPT_IntChannelScaleBits, "16");
00168   manager.setOptionValString(&OPT_IntMathLowPass5, "lp5optim");
00169   manager.setOptionValString(&OPT_IntMathLowPass9, "lp9optim");
00170 
00171   // Parse command-line:
00172   if (manager.parseCommandLine(argc, argv, "?prof-only?", 0, 1) == false)
00173     return(1);
00174 
00175   const bool profOnly =
00176     manager.numExtraArgs() > 0 ? manager.getExtraArgAs<bool>(0) : false;
00177 
00178   manager.start();
00179 
00180   LINFO("using %u bits for integer arithmetic", ieng->getNbits());
00181 
00182   LINFO("using '%s' decoding algorithm",
00183         convertToString(decodeType.getVal()).c_str());
00184 
00185   int c = 0;
00186 
00187   PauseWaiter p;
00188 
00189   SimTime t;
00190 
00191   rutz::time iruser, irsys, fruser, frsys;
00192 
00193   PyramidCache<int> cache;
00194 
00195   while (true)
00196     {
00197       if (signum != 0)
00198         {
00199           LINFO("quitting because %s was caught", signame(signum));
00200           break;
00201         }
00202 
00203       t += SimTime::HERTZ(30);
00204 
00205       if (p.checkPause())
00206         continue;
00207 
00208       const FrameState is = ifs->updateNext();
00209       if (is == FRAME_COMPLETE)
00210         break;
00211 
00212       GenericFrame input = ifs->readFrame();
00213       if (!input.initialized())
00214         break;
00215 
00216       const FrameState os = ofs->updateNext();
00217 
00218       rutz::time u1 = rutz::time::user_rusage();
00219       rutz::time s1 = rutz::time::sys_rusage();
00220 
00221       const Image<PixRGB<byte> > rgb = input.asRgb();
00222 
00223       InputFrame finput = InputFrame::fromRgb(&rgb, t);
00224 
00225       fvc->input(finput);
00226 
00227       (void) fvc->getOutput();
00228 
00229       rutz::time u2 = rutz::time::user_rusage();
00230       rutz::time s2 = rutz::time::sys_rusage();
00231 
00232       const IntegerInput ii =
00233         IntegerInput::decode(input, decodeType.getVal(),
00234                              ieng->getNbits());
00235 
00236       ivc->inputInt(ii, t, &cache);
00237 
00238       (void) ivc->getOutputInt();
00239 
00240       rutz::time u3 = rutz::time::user_rusage();
00241       rutz::time s3 = rutz::time::sys_rusage();
00242 
00243       fruser += (u2 - u1);
00244       frsys += (s2 - s1);
00245       iruser += (u3 - u2);
00246       irsys += (s3 - s2);
00247 
00248       if (!profOnly)
00249         {
00250           Image<float> frg, fby;
00251           const float lumthresh = 25.5f;
00252           getRGBY(finput.colorFloat(), frg, fby, lumthresh);
00253 
00254           ofs->writeFrame(input, "input",
00255                           FrameInfo("copy of input frame", SRC_POS));
00256 
00257           ofs->writeFloat(finput.grayFloat(), FLOAT_NORM_0_255, "fBW",
00258                           FrameInfo("floating-point luminance", SRC_POS));
00259 
00260           ofs->writeFloat(frg, FLOAT_NORM_0_255, "fRG",
00261                           FrameInfo("floating-point Red-Green", SRC_POS));
00262 
00263           ofs->writeFloat(fby, FLOAT_NORM_0_255, "fBY",
00264                           FrameInfo("floating-point Blue-Yellow", SRC_POS));
00265 
00266           ofs->writeFloat(ii.grayInt(), FLOAT_NORM_0_255, "iBW",
00267                           FrameInfo("fixed-point luminance", SRC_POS));
00268 
00269           ofs->writeFloat(ii.rgInt(), FLOAT_NORM_0_255, "iRG",
00270                           FrameInfo("fixed-point Red-Green", SRC_POS));
00271 
00272           ofs->writeFloat(ii.byInt(), FLOAT_NORM_0_255, "iBY",
00273                           FrameInfo("fixed-point Blue-Yellow", SRC_POS));
00274 
00275           fvc->saveResults(ofs);
00276           ivc->saveResults(ofs);
00277 
00278           {
00279             const double cc = corrcoef(finput.grayFloat(), Image<float>(ii.grayInt()));
00280             LINFO("%06d corrcoef(fbw,ibw) = %.4f", c, cc);
00281           }
00282 
00283           {
00284             const double cc = corrcoef(frg, Image<float>(ii.rgInt()));
00285             LINFO("%06d corrcoef(frg,irg) = %.4f", c, cc);
00286           }
00287 
00288           {
00289             const double cc = corrcoef(fby, Image<float>(ii.byInt()));
00290             LINFO("%06d corrcoef(fby,iby) = %.4f", c, cc);
00291           }
00292 
00293           if (fvc->hasSubChan("orientation")
00294               && ivc->hasSubChan("int-orientation"))
00295             {
00296               const ImageSet<float> fpyr =
00297                 dyn_cast<OrientationChannel>(fvc->subChan("orientation"))->gabor(2).pyramid(0);
00298               const ImageSet<int> ipyr =
00299                 dyn_cast<IntegerOrientationChannel>(ivc->subChan("int-orientation"))->gabor(2).intgPyramid();
00300 
00301               for (uint i = 0; i < fpyr.size(); ++i)
00302                 if (fpyr[i].initialized())
00303                   ofs->writeFloat(fpyr[i], FLOAT_NORM_0_255,
00304                                   sformat("fpyr[%u]", i),
00305                                   FrameInfo(sformat("floating-point pyramid "
00306                                                     "level %u of %u", i,
00307                                                     fpyr.size()), SRC_POS));
00308 
00309               for (uint i = 0; i < ipyr.size(); ++i)
00310                 if (ipyr[i].initialized())
00311                   ofs->writeFloat(Image<float>(ipyr[i]), FLOAT_NORM_0_255,
00312                                   sformat("ipyr[%u]", i),
00313                                   FrameInfo(sformat("integer pyramid "
00314                                                     "level %u of %u", i,
00315                                                     fpyr.size()), SRC_POS));
00316 
00317               for (uint i = 0; i < fpyr.size(); ++i)
00318                 if (fpyr[i].initialized())
00319                   {
00320                     const double cc = corrcoef(fpyr[i], Image<float>(ipyr[i]));
00321                     LINFO("%06d pyr[%u] corrcoef = %.4f", c, i, cc);
00322                   }
00323             }
00324 
00325           compareChannels(c, *ivc, *fvc);
00326         }
00327 
00328       if (os == FRAME_FINAL)
00329         break;
00330 
00331       LDEBUG("frame %d", c);
00332       ++c;
00333 
00334       if (ifs->shouldWait() || ofs->shouldWait())
00335         Raster::waitForKey();
00336     }
00337 
00338   manager.stop();
00339 
00340   for (std::map<IntegerChannel*, ChannelCorrcoefData>::const_iterator
00341          itr = ccdata.begin(), stop = ccdata.end();
00342        itr != stop; ++itr)
00343     {
00344       LINFO("AVG corrcoef(%-20s) = %.4f",
00345             (*itr).first->tagName().c_str(),
00346             (*itr).second.sum / (*itr).second.n);
00347     }
00348 
00349   LINFO("floating-point code: %.3es user + %.3es sys (%.3fms per frame)",
00350         fruser.sec(), frsys.sec(),
00351         c <= 0 ? 0.0 : (fruser.msec() + frsys.msec()) / c);
00352   LINFO("integer code:        %.3es user + %.3es sys (%.3fms per frame)",
00353         iruser.sec(), irsys.sec(),
00354         c <= 0 ? 0.0 : (iruser.msec() + irsys.msec()) / c);
00355 
00356   if (iruser.sec() + irsys.sec() > 0.0)
00357     LINFO("floating-point/integer runtime ratio: %.2f",
00358           (fruser.sec() + frsys.sec()) / (iruser.sec() + irsys.sec()));
00359 
00360   return 0;
00361 }
00362 
00363 int main(const int argc, const char **argv)
00364 {
00365   try
00366     {
00367       return submain(argc, argv);
00368     }
00369   catch (...)
00370     {
00371       REPORT_CURRENT_EXCEPTION;
00372     }
00373 
00374   return 1;
00375 }
00376 
00377 // ######################################################################
00378 /* So things look consistent in everyone's emacs... */
00379 /* Local Variables: */
00380 /* mode: c++ */
00381 /* indent-tabs-mode: nil */
00382 /* End: */
00383 
00384 #endif // APPNEURO_TEST_INTCHANNEL_C_DEFINED
Generated on Sun May 8 08:04:11 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3