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: */