00001 /*!@file Image/ConvolutionMap.H */ 00002 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: T Nathan Mundhenk <mundhenk@usc.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/ConvolutionMap.H $ 00036 // $Id: ConvolutionMap.H 8631 2007-07-25 23:26:37Z rjpeters $ 00037 // 00038 00039 #ifndef CONVOLUTIONMAP_H_DEFINED 00040 #define CONVOLUTIONMAP_H_DEFINED 00041 00042 #include "Image/Image.H" 00043 #include <vector> 00044 #include <stdlib.h> 00045 00046 //! Container class for convolution maps 00047 template <class T> class convolutionMap 00048 { 00049 public: 00050 //! default constructor 00051 inline convolutionMap(); 00052 //! default constructor, with initial values 00053 inline convolutionMap(T smallNumber, 00054 unsigned int initVecSize, 00055 Image<T> &origImage, 00056 Image<T> &kernelImage); 00057 //! default destructor 00058 inline ~convolutionMap(); 00059 //! check to see that we set up everything... 00060 inline void CMcheckInit1(); 00061 //! check to see that we set up everything... 00062 inline void CMcheckInit2(); 00063 //! copy an image into an attached image array 00064 inline void CMcopyImage(Image<T> &input); 00065 //! This is the pointer map to each pixel in the image for convolution 00066 Image<std::vector<T*> > CMimageMap; 00067 //! This is the pointer map to each pixel in the kernel for convolution 00068 Image<std::vector<T> > CMkernelMap; 00069 //! This stores the number of operations at each pixel 00070 Image<unsigned int> CMindexMap; 00071 //! This stores the normalization const at each pixel 00072 Image<T> CMkWeightNorm; 00073 //! This is the "attached" static image to use 00074 Image<T> CMstaticImage; 00075 //! This is the original or template image to create a static image from 00076 Image<T> CMorigImage; 00077 //! This is the handle to the static information in the attached image 00078 T* CMimageArrayHandle; 00079 //! This is an outside holder for the array size 00080 unsigned int CMimageArraySize; 00081 //! This is the "attached" static kernel image to use 00082 Image<T> CMkernel; 00083 //! This is the small number below which we weed out operations 00084 T CMsmallNumber; 00085 //! initial size for vectors, 0 means kernel size 00086 unsigned int CMinitVecSize; 00087 //! set true if we input values during construction 00088 bool CMinit1; 00089 //! set true if we called a known init method to make maps 00090 bool CMinit2; 00091 //! set this to true if the vector maps are precise in size 00092 bool CMpreciseVectors; 00093 }; 00094 00095 // ###################################################################### 00096 // ###################################################################### 00097 // FREE FUNCTIONS 00098 // ###################################################################### 00099 // ###################################################################### 00100 00101 //! Computes a set of convolution maps for doing multiple convolutions 00102 /*! When doing more than one convolution, for instance on an animated 00103 sequence, this builds a map set so that we precompute 00104 (A) border regions 00105 (B) very small kernel values 00106 These are removed and a vector of indexes is produced. These can then 00107 be used by iterating over the maps which contain the index. 00108 @param cMap This is a container for the maps and images used 00109 */ 00110 template <class T> 00111 void computeConvolutionMaps(convolutionMap<T> &cMap); 00112 00113 //! carries out a simple mapped convolution, call computeConvolutionMaps first 00114 /*! This will take in the convolution maps created and the current image 00115 and compute convolution in a line. That is, for each pixel we can 00116 in a straight line iterate over all the image and kernel values using 00117 a map. This saves us from having to check for border regions and compute 00118 pixel locations. Additionally, we can pre-remove small values from 00119 convolution. 00120 @param cMap This is a contaner for maps and images 00121 Example use: 00122 00123 convolutionMap<FLOAT> cMap; 00124 Image<float> inputImg; 00125 00126 ... 00127 00128 if(frame == 1) 00129 { 00130 readMatrix rm("lowPassKernel.mat"); 00131 rm.echoMatrix(); 00132 cMap.CMsmallNumber = 1.1F; 00133 cMap.CMinitVecSize = 1; 00134 cMap.CMkernel = rm.returnMatrixAsImage(); 00135 cMap.CMorigImage = inputImg; 00136 computeConvolutionMaps(cMap); 00137 } 00138 cMap.CMcopyImage(inputImg); 00139 Image<FLOAT> i2 = convolveWithMaps(cMap); 00140 */ 00141 template <class T> 00142 Image<T> convolveWithMaps(convolutionMap<T> &cMap); 00143 00144 // ###################################################################### 00145 // ###################################################################### 00146 // INLINE MEMBER FUNCTIONS 00147 // ###################################################################### 00148 // ###################################################################### 00149 00150 00151 // ###################################################################### 00152 template <class T> inline 00153 convolutionMap<T>::convolutionMap() 00154 { 00155 CMsmallNumber = 0; 00156 CMinitVecSize = 3; 00157 CMpreciseVectors = false; 00158 CMinit1 = false; 00159 00160 } 00161 00162 // ###################################################################### 00163 template <class T> inline 00164 convolutionMap<T>::convolutionMap(T smallNumber, 00165 unsigned int initVecSize, 00166 Image<T> &origImage, 00167 Image<T> &kernelImage) 00168 { 00169 CMsmallNumber = smallNumber; 00170 CMinitVecSize = initVecSize; 00171 CMorigImage = origImage; 00172 CMkernel = kernelImage; 00173 if(initVecSize == 1) 00174 CMpreciseVectors = true; 00175 else 00176 CMpreciseVectors = false; 00177 CMinit1 = true; 00178 } 00179 00180 // ###################################################################### 00181 template <class T> inline 00182 convolutionMap<T>::~convolutionMap() 00183 {} 00184 00185 // ###################################################################### 00186 template <class T> inline 00187 void convolutionMap<T>::CMcheckInit1() 00188 { 00189 if(CMinit1 == false) 00190 { 00191 if(CMorigImage.initialized() == false) 00192 LFATAL("CMorigImage must be init the size of the image to be convolved"); 00193 if(CMkernel.initialized() == false) 00194 LFATAL("You must supply the kernel as image CMkernel"); 00195 CMinit1 = true; 00196 } 00197 } 00198 00199 // ###################################################################### 00200 template <class T> inline 00201 void convolutionMap<T>::CMcheckInit2() 00202 { 00203 if(CMinit2 == false) 00204 { 00205 if(CMimageMap.initialized() == false) 00206 LFATAL("Image map CMimageMap not initalized in container"); 00207 if(CMkernelMap.initialized() == false) 00208 LFATAL("Kernel map CMkernelMap not initalized in container"); 00209 if(CMindexMap.initialized() == false) 00210 LFATAL("Index map image CMindexMap not initalized in container"); 00211 if(CMkWeightNorm.initialized() == false) 00212 LFATAL("Normalization image CMkWeightNorm not initalized in container"); 00213 if(CMstaticImage.initialized() == false) 00214 LFATAL("Static Image CMstaticImage not initalized in container"); 00215 CMinit2 = true; 00216 } 00217 } 00218 00219 // ###################################################################### 00220 template <class T> inline 00221 void convolutionMap<T>::CMcopyImage(Image<T> &input) 00222 { 00223 if(input.getWidth() != CMstaticImage.getWidth()) 00224 LFATAL("Input image and static image different width"); 00225 if(input.getHeight() != CMstaticImage.getHeight()) 00226 LFATAL("Input image and static image different height"); 00227 typename Image<T>::iterator istatic = CMstaticImage.beginw(); 00228 typename Image<T>::iterator iinput = input.beginw(); 00229 while(istatic != CMstaticImage.endw()) 00230 *istatic++ = *iinput++; 00231 } 00232 00233 #endif 00234