StereoChannel.C

Go to the documentation of this file.
00001 /*!@file Channels/StereoChannel.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:
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Channels/StereoChannel.C $
00035 // $Id: StereoChannel.C 9412 2008-03-10 23:10:15Z farhan $
00036 //
00037 
00038 #ifndef STEREOCHANNEL_C_DEFINED
00039 #define STEREOCHANNEL_C_DEFINED
00040 
00041 #include "Channels/StereoChannel.H"
00042 
00043 #include "Channels/ChannelOpts.H"
00044 #include "Channels/DisparityChannel.H"
00045 #include "Component/OptionManager.H"
00046 #include "Image/CutPaste.H"
00047 #include "Image/FilterOps.H"
00048 #include "Image/Kernels.H"
00049 #include "Image/Pixels.H"
00050 #include "Image/PyramidOps.H"
00051 
00052 // ######################################################################
00053 // StereoChannel member definitions:
00054 // ######################################################################
00055 
00056 // instantiations for our static members:
00057 const uint  StereoChannel::nPhase;
00058 const uint  StereoChannel::nTheta;
00059 const float StereoChannel::dPhase;
00060 const float StereoChannel::dTheta;
00061 const float StereoChannel::stddev;
00062 const float StereoChannel::period;
00063 
00064 
00065 // ######################################################################
00066 StereoChannel::StereoChannel(OptionManager& mgr) :
00067   ComplexChannel(mgr, "Stereo", "stereo", STEREO),
00068   itsPyrType("StereoChannelPyramidType", this, Gaussian3),
00069   itsNumTheta(&OPT_NumTheta, this),
00070   itsNumPhase("NumPhase", this, nPhase/2 + 1)
00071 {
00072   fImgL = NULL; fImgR = NULL;
00073 
00074   // let's create our subchannels (may be reconfigured later if our
00075   // number of orientations changes):
00076   buildSubChans();
00077 }
00078 
00079 // ######################################################################
00080 StereoChannel::~StereoChannel()
00081 {  }
00082 
00083 // ######################################################################
00084 void StereoChannel::start1()
00085 {
00086 
00087   // get the depth of the feature maps
00088   itsDepth = dispChan(0,0).getLevelSpec().maxDepth();
00089 
00090   // create the phased gabor pyramids
00091   createPhasedGaborPyramids();
00092 }
00093 
00094 // ######################################################################
00095 DisparityChannel& StereoChannel::dispChan(const uint idO,
00096                                           const uint idP) const
00097 {
00098   uint idx= idO * itsNumPhase.getVal() + idP;
00099   return *(dynCast<DisparityChannel>(this->subChan(idx)));
00100 }
00101 
00102 // ######################################################################
00103 void StereoChannel::buildSubChans()
00104 {
00105   // kill any subchans we may have had...
00106   this->removeAllSubChans();
00107 
00108   // let's instantiate our subchannels now that we know how many we
00109   // want. They will inherit the current values (typically
00110   // post-command-line parsing) of all their options as they are
00111   // constructed:
00112   LINFO("Using %d orientations spanning [0..180]deg and %d phase spanning [0..360]deg",
00113     itsNumTheta.getVal(), itsNumPhase.getVal());
00114 
00115   double theta;
00116   double phase;
00117 
00118   for (uint i = 0; i < itsNumTheta.getVal(); i ++)
00119     for (uint j = 0; j < itsNumPhase.getVal(); j ++)
00120     {
00121       theta = 180.0 * double(i) / double(itsNumTheta.getVal());
00122       // the phase range is -PI/2 to PI/2 but -PI/2 to 0 is normalized.
00123       // the number of thetas is always odd
00124       // first half is 0 to PI/2
00125       if(j <= itsNumPhase.getVal()/2)
00126         phase = 90.0 * double(j)   / double(itsNumPhase.getVal()/2);
00127       // the second half is -PI/2 to 0
00128       else
00129         phase = 90.0 * double(j-1) / double(itsNumPhase.getVal()/2) +
00130                 180.0;
00131 
00132       addSubChan(makeSharedComp
00133                  (new DisparityChannel(getManager(),
00134                                        i*itsNumPhase.getVal()
00135                                        +j,theta,phase )));
00136 
00137       dispChan(i,j).setNumTheta(nTheta);
00138       dispChan(i,j).setNumPhase(nPhase);
00139 
00140     }
00141 
00142   // Here, we just use our subchannels' default tag names
00143 
00144   // if we have been requested to export some options, let's ask it
00145   // again on our newly built channels:
00146   ModelComponent::exportOptions(MC_RECURSE);
00147 }
00148 
00149 // ######################################################################
00150 void StereoChannel::createPhasedGaborPyramids()
00151 {
00152   // create the phased gabor pyramids
00153   if(fImgL != NULL || fImgR != NULL)
00154   {
00155     for(uint i = 0; i < itsDepth; i++)
00156     {
00157       for(uint j = 0; j < nTheta; j++)
00158       {
00159         delete(fImgL[i][j]);
00160         delete(fImgR[i][j]);
00161       }
00162     }
00163 
00164     for(uint i = 0; i < itsDepth; i++)
00165     {
00166       delete(fImgL[i]);
00167       delete(fImgR[i]);
00168     }
00169 
00170     delete(fImgL);
00171     delete(fImgR);
00172   }
00173 
00174   fImgL = new Image<float>**[itsDepth];
00175   fImgR = new Image<float>**[itsDepth];
00176 
00177   for(uint i = 0; i < itsDepth; i++)
00178   {
00179     fImgL[i] = new Image<float>*[nTheta];
00180     fImgR[i] = new Image<float>*[nTheta];
00181   }
00182 
00183   for(uint i = 0; i < itsDepth; i++)
00184   {
00185     for(uint j = 0; j < nTheta; j++)
00186     {
00187       fImgL[i][j] = new Image<float>[nPhase];
00188       fImgR[i][j] = new Image<float>[nPhase];
00189     }
00190   }
00191 }
00192 
00193 // ######################################################################
00194 void StereoChannel::paramChanged(ModelParamBase* const param,
00195                                  const bool valueChanged,
00196                                  ParamClient::ChangeStatus* status)
00197 {
00198   ComplexChannel::paramChanged(param, valueChanged, status);
00199 
00200   // if the param is our  number of channel and it has
00201   // become different from our number of orientations * number of phase ,
00202   // let's reconfigure:
00203   if (param == &itsNumTheta &&
00204       //      param == &itsNumPhase &&
00205       numChans() != itsNumPhase.getVal() * itsNumTheta.getVal())
00206     buildSubChans();
00207 }
00208 
00209 // ######################################################################
00210 void StereoChannel::doInput(const InputFrame& inframe)
00211 {
00212   ASSERT(inframe.grayFloat().initialized());
00213 
00214   imgL = inframe.grayFloat();
00215   // IMPORTANT
00216   // at this point the secondary view image should already
00217   // be set by Stereo Vision.
00218 
00219   // create an image pyramid for both images
00220   pyrL = buildPyrGaussian(imgL, 0, itsDepth, 5);
00221   pyrR = buildPyrGaussian(imgR, 0, itsDepth, 5);
00222 
00223   // apply the gabor filter at various angle and phase on both eyes
00224   applyGabor();
00225 
00226   // for normalization
00227   ImageSet<float> tDispMap(itsDepth);
00228   ImageSet<float> tempDM;
00229 
00230   for(uint d = 0; d < itsDepth; d++)
00231   {
00232     tDispMap[d].resize(pyrL[d].getWidth(),pyrL[d].getHeight(),true);
00233     //ispMap[d] += 1.0F;
00234   }
00235 
00236   // pass the response array to each subchannel
00237   // so they can calculate each disparity correspondence
00238   for (uint i = 0; i < itsNumTheta.getVal(); i ++)
00239     for (uint j = 0; j < itsNumPhase.getVal(); j ++)
00240     {
00241       dispChan(i,j).setRawFilteredImages(fImgL,fImgR);
00242       dispChan(i,j).doInput(inframe);
00243 
00244       //dispChan(i,j).getDispMap(&tempDM);
00245 
00246       // add the results for normalizing the output
00247       //for (uint d = 0; d< itsDepth; d++)
00248       //  tDispMap[d] += tempDM[d];
00249 
00250     }
00251 
00252   // normalize the values to [0,  1] - confidence level
00253   // and store the pyramid for the interaction
00254   /*  for (uint i = 0; i < itsNumTheta.getVal(); i ++)
00255     for (uint j = 0; j < itsNumPhase.getVal(); j ++)
00256     {
00257       dispChan(i,j).normalizeDispMap(tDispMap,
00258         itsNumTheta.getVal()*itsNumPhase.getVal());
00259       dispChan(i,j).storePyramid(t);
00260     }
00261   */
00262 
00263 
00264 }
00265 
00266 // ######################################################################
00267 void StereoChannel::setSecondImage(const Image<float>* bwimg)
00268 {
00269   imgR = *bwimg;
00270 }
00271 
00272 // ######################################################################
00273 void StereoChannel::getRawFilteredImages(Image<float> ****fImgLE,
00274                                          Image<float> ****fImgRI)
00275 {
00276   *fImgLE = fImgL;
00277   *fImgRI = fImgR;
00278 }
00279 
00280 // ######################################################################
00281 void StereoChannel::applyGabor()
00282 {
00283   Image<float> gaborF;Image<float> gF;
00284   Point2D<int> a(3,3); Dims b(5,5);
00285   for(uint d = 0; d < itsDepth; d++)
00286   {
00287     for(uint t = 0; t < nTheta; t++)
00288     {
00289       for(uint p = 0; p < nPhase; p++)
00290       {
00291         gaborF = gaborFilter<float>(stddev,period,p*dPhase,t*dTheta);
00292         ASSERT(gaborF.getWidth() == 11 && gaborF.getHeight() == 11);
00293         gaborF = crop(gaborF,a,b,false);
00294 
00295         fImgL[d][t][p] = convolve(pyrL[d],gaborF,CONV_BOUNDARY_ZERO);
00296         //fImgL[d][t][p].rectify();
00297         fImgR[d][t][p] = convolve(pyrR[d],gaborF,CONV_BOUNDARY_ZERO);
00298         //fImgR[d][t][p].rectify();
00299       }
00300     }
00301   }
00302 }
00303 
00304 // ######################################################################
00305 /* So things look consistent in everyone's emacs... */
00306 /* Local Variables: */
00307 /* indent-tabs-mode: nil */
00308 /* End: */
00309 
00310 #endif // STEREOCHANNEL_C_DEFINED
Generated on Sun May 8 08:04:41 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3