Jet.C

Go to the documentation of this file.
00001 /*!@file Channels/Jet.C a simple jet */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // 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: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Channels/Jet.C $
00035 // $Id: Jet.C 7367 2006-11-01 00:47:02Z rjpeters $
00036 //
00037 
00038 #include "Channels/Jet.H"
00039 
00040 #include "Util/Assert.H"
00041 #include "Image/Image.H"
00042 #include "rutz/compat_cmath.h"
00043 
00044 #include <iostream>
00045 
00046 // ######################################################################
00047 JetSpec::JetSpec()
00048 { spec = NULL; freeMem(); }
00049 
00050 // ######################################################################
00051 JetSpec::JetSpec(const JetSpec& js)
00052 { spec = NULL; freeMem(); *this = js; }
00053 
00054 // ######################################################################
00055 JetSpec& JetSpec::operator=(const JetSpec& js)
00056 {
00057   freeMem(); JF *jfp = js.spec;
00058   while(jfp) {
00059     if (addFeature(jfp->feature) == false)
00060       LFATAL("Cannot add feature");
00061     JFT *jftp = jfp->jft;
00062     while(jftp) {
00063       if (addFeatureType(jfp->feature, jftp->ftype) == false)
00064         LFATAL("Cannot add feature type");
00065       for (int i = 0; i < jftp->nbidx; i++)
00066         if (addIndexRange(jfp->feature, jftp->ftype,
00067                           jftp->idxmin[i], jftp->idxmax[i]) == false)
00068           LFATAL("Cannot add index range");
00069       jftp = jftp->next;
00070     }
00071     jfp = jfp->next;
00072   }
00073   return *this;
00074 }
00075 
00076 // ######################################################################
00077 void JetSpec::freeMem()
00078 {
00079   JF *jfp = spec;
00080   while(jfp) {
00081     JFT *jftp = jfp->jft;
00082     while(jftp) {
00083       if (jftp->nbidx) { delete [] jftp->idxmin; delete [] jftp->idxmax; }
00084       JFT *del = jftp; jftp = jftp->next; delete del;
00085     }
00086     JF *del = jfp; jfp = jfp->next; delete del;
00087   }
00088   spec = NULL; jetSize = 0;
00089   for (int f = 0; f < NBVISUALFEATURES; f ++)
00090     for (int t = 0; t < NBVISUALFEATURETYPES; t ++)
00091       dataIdx[f][t] = NULL; // undefined
00092 }
00093 
00094 // ######################################################################
00095 JetSpec::~JetSpec()
00096 { freeMem(); }
00097 
00098 // ######################################################################
00099 bool JetSpec::addFeature(const VisualFeature f)
00100 {
00101   JF *jfp = spec;
00102   if (spec == NULL) { spec = new JF; jfp = spec; } // first feature ever added
00103   else  // add to end of chained list
00104     while(true) {
00105       if (jfp->feature == f)
00106         { LERROR("Feature %s already exists!", featureName(f)); return false; }
00107       if (jfp->next) jfp = jfp->next;
00108       else { jfp->next = new JF; jfp = jfp->next; break; }
00109     }
00110   jfp->feature = f; jfp->jft = NULL; jfp->next = NULL;
00111   //LDEBUG("Added feature %s", featureName(f));
00112   return true;
00113 }
00114 
00115 // ######################################################################
00116 bool JetSpec::addFeatureType(const VisualFeature f, const VisualFeatureType t)
00117 {
00118   // if we don't have this feature yet, add it:
00119   if (hasFeature(f) == false) addFeature(f);
00120 
00121   // if we already have this feature/type, error:
00122   if (hasFeatureType(f, t)) {
00123     LERROR("Already have %s/%s", featureName(f), featureTypeName(t));
00124     return false;
00125   }
00126 
00127   // find the feature:
00128   JF *jfp = spec;
00129   while(jfp) {
00130     if (jfp->feature == f) { // ok, this is our feature; add type
00131       JFT *jftp = jfp->jft;
00132       if (jfp->jft == NULL)
00133         { jfp->jft = new JFT; jftp = jfp->jft; } // first type ever added
00134       else  // add to end of chained list
00135         while(true) {
00136           if (jftp->ftype == t)
00137             { LERROR("Feature type %s for feature %s already exists!",
00138                      featureTypeName(t), featureName(f)); return false; }
00139           if (jftp->next) jftp = jftp->next;
00140           else { jftp->next = new JFT; jftp = jftp->next; break; }
00141         }
00142       jftp->ftype = t; jftp->nbidx = 0; jftp->idxmin = NULL;
00143       jftp->idxmax = NULL; jftp->next = NULL;
00144       updateDataIdx();  // will update indexBase, siz, and data pointers
00145       //LDEBUG("Added feature type %s/%s", featureName(f), featureTypeName(t));
00146       return true;
00147     }
00148     jfp = jfp->next;
00149   }
00150   LERROR("Feature %s not found?", featureName(f));
00151   return false;
00152 }
00153 
00154 // ######################################################################
00155 bool JetSpec::addIndexRange(const VisualFeature f, const VisualFeatureType t,
00156                             const int indexmin, const int indexmax)
00157 {
00158   // if we don't have this feature yet, add it:
00159   if (hasFeature(f) == false) addFeature(f);
00160 
00161   // if we don't have this feature type yet, add it:
00162   if (hasFeatureType(f, t) == false) addFeatureType(f, t);
00163 
00164   // let's add the range:
00165   JFT *jftp = dataIdx[f][t];
00166   int n = jftp->nbidx;
00167   int *nmin = new int[n + 1], *nmax = new int[n + 1];
00168   if (n) {
00169     memcpy(nmin, jftp->idxmin, n * sizeof(int));
00170     memcpy(nmax, jftp->idxmax, n * sizeof(int));
00171     delete [] jftp->idxmin; delete [] jftp->idxmax;
00172   }
00173   nmin[n] = indexmin; nmax[n] = indexmax;
00174   jftp->nbidx ++; jftp->idxmin = nmin; jftp->idxmax = nmax;
00175   updateDataIdx();  // will update indexBase, siz and data pointers
00176   //LDEBUG("Added %s/%s range %d = [%d..%d]", featureName(f),
00177   //       featureTypeName(t), jftp->nbidx-1, indexmin, indexmax);
00178   return true;
00179 }
00180 
00181 // ######################################################################
00182 void JetSpec::print() const
00183 {
00184   JF *jfp = spec; std::cout<<"=== JetSpec [size = "<<jetSize<<']'<<std::endl;
00185   while(jfp) {
00186     std::cout<<featureName(jfp->feature)<<':'<<std::endl;
00187     JFT *jftp = jfp->jft;
00188     while(jftp) {
00189       std::cout<<"  "<<featureTypeName(jftp->ftype)<<": [base = "<<
00190         jftp->indexBase<<", size = "<<jftp->siz<<"]: ";
00191       for (int i = 0; i < jftp->nbidx; i ++)
00192         std::cout<<'['<<jftp->idxmin[i]<<".."<<jftp->idxmax[i]<<"] ";
00193       std::cout<<std::endl;
00194       jftp = jftp->next;
00195     }
00196     jfp = jfp->next;
00197   }
00198 }
00199 
00200 // ######################################################################
00201 void JetSpec::updateDataIdx()
00202 {
00203   JF *jfp = spec; jetSize = 0;
00204   while(jfp) {
00205     JFT *jftp = jfp->jft;
00206     while(jftp) {
00207       // update indexBase for this feature/type:
00208       jftp->indexBase = jetSize;
00209 
00210       // store data pointer in our accelerated-access array
00211       dataIdx[jfp->feature][jftp->ftype] = jftp;
00212 
00213       // compute size for this feature type
00214       int siz = 0;
00215       if (jftp->nbidx) {
00216         siz = 1;
00217         for (int i = 0; i < jftp->nbidx; i ++)
00218           siz *= jftp->idxmax[i] - jftp->idxmin[i] + 1;
00219       }
00220       jftp->siz = siz;
00221       jetSize += siz;
00222 
00223       // skip to next feature type for this feature
00224       jftp = jftp->next;
00225     }
00226     // skip to nect feature
00227     jfp = jfp->next;
00228   }
00229 }
00230 
00231 // ######################################################################
00232 // ######################################################################
00233 template <class T>
00234 Jet<T>::Jet(const rutz::shared_ptr<JetSpec> js) : Image<T>()
00235 { spec = js; this->resize(spec->getJetSize(), 1); }
00236 
00237 // ######################################################################
00238 template <class T>
00239 Jet<T>::Jet() : Image<T>(), spec(NULL)
00240 { }
00241 
00242 // ######################################################################
00243 template <class T>
00244 void Jet<T>::init(const rutz::shared_ptr<JetSpec> js)
00245 { ASSERT(spec.get()); spec = js; this->resize(spec->getJetSize(), 1); }
00246 
00247 // ######################################################################
00248 template <class T>
00249 Jet<T>::~Jet()
00250 { this->freeMem(); }
00251 
00252 // ######################################################################
00253 double raodistance(const Jet<float>& j1, const Jet<float>& j2,
00254                    const int idxmin, const int idxmax)
00255 {
00256   // this is a sum of jet distances computed separately for each scale
00257   double sumsq[idxmax - idxmin + 1];
00258   // initialize it
00259   for (int i = 0; i < idxmax - idxmin + 1; i++)
00260     sumsq[i] = 0.0;
00261 
00262   for (int f = 0; f < NBVISUALFEATURES; f ++)
00263     {
00264       VisualFeature ff = VisualFeature(f);
00265       if (j1.hasFeatureType(ff, RAW))
00266         {
00267           int nr = j1.getNbIndexRanges(ff, RAW);
00268           switch(nr)
00269             {
00270             case 1:
00271               {
00272                 int imin = 0, imax = 0;
00273                 j1.getIndexRange(ff, RAW, 0, imin, imax);
00274                 ASSERT(idxmin >= imin && idxmax <= imax);
00275                 for (int i = idxmin; i <= idxmax; i ++)
00276                   {
00277                     float val1 = j1.getVal(ff, RAW, i);
00278                     float val2 = j2.getVal(ff, RAW, i);
00279                     double val;
00280                     if (isnan(val1) || isnan(val2))
00281                       val = 0.0;
00282                     else
00283                       val = double(val1 - val2);
00284                     sumsq[i - idxmin] += val * val;
00285                   }
00286                 //LINFO("%s: [%d .. %d]",featureName(ff),imin, imax);
00287               }
00288               break;
00289             case 2:
00290               {
00291                 int rmin = 0, rmax = 0;
00292                 j1.getIndexRange(ff, RAW, 0, rmin, rmax);
00293                 for (int r = rmin; r <= rmax; r ++)
00294                   {
00295                     int imin = 0, imax = 0;
00296                     j1.getIndexRange(ff, RAW, 1, imin, imax);
00297                     ASSERT(idxmin >= imin && idxmax <= imax);
00298                     for (int i = idxmin; i <= idxmax; i ++)
00299                       {
00300                         float val1 = j1.getVal(ff, RAW, r, i);
00301                         float val2 = j2.getVal(ff, RAW, r, i);
00302                         double val;
00303                         if (isnan(val1) || isnan(val2))
00304                           val = 0.0;
00305                         else
00306                           val = double(val1 - val2);
00307                         sumsq[i - idxmin] += val * val;
00308                       }
00309                     //LINFO("%s:(%d) [%d .. %d]",featureName(ff),r,imin,imax);
00310                   }
00311               }
00312               break;
00313             default:
00314               LFATAL("Deep hierarchical Jets not supported");
00315             }
00316         }
00317     }
00318   double d = 0.0;
00319   for (int i = 0; i <= idxmax - idxmin; i ++) d += sumsq[i];
00320   return d;
00321 }
00322 
00323 
00324 // ######################################################################
00325 #ifdef INVT_INST_BYTE
00326 template class Jet<byte>;
00327 #endif
00328 #ifdef INVT_INST_INT16
00329 template class Jet<int16>;
00330 #endif
00331 #ifdef INVT_INST_INT32
00332 template class Jet<int32>;
00333 #endif
00334 #ifdef INVT_INST_FLOAT
00335 template class Jet<float>;
00336 #endif
00337 
00338 
00339 // ######################################################################
00340 /* So things look consistent in everyone's emacs... */
00341 /* Local Variables: */
00342 /* indent-tabs-mode: nil */
00343 /* End: */
Generated on Sun May 8 08:40:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3