00001 /*!@file Image/PyramidOps.H Free functions operating on pyramid data structures */ 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/Image/PyramidOps.H $ 00035 // $Id: PyramidOps.H 14473 2011-02-03 20:36:39Z dberg $ 00036 // 00037 00038 #ifndef IMAGE_PYRAMIDOPS_H_DEFINED 00039 #define IMAGE_PYRAMIDOPS_H_DEFINED 00040 00041 #include "Image/Convolutions.H" 00042 #include "Image/PyramidTypes.H" 00043 #include "Util/Promotions.H" 00044 #include "Util/Types.H" 00045 00046 template <class T> class Point2D; 00047 template <class T> class Image; 00048 template <class T> class ImageSet; 00049 00050 // ############################################################ 00051 // ##### Dyadic pyramid pixel operations: 00052 // ############################################################ 00053 00054 //! Get value of a pixel from a dyadic pyramid at a given level and coordinates 00055 /*! @param pix The pixel value returned 00056 @param p Coordinates given at scale 0 (base pyramid level); 00057 bilinear interpolation will be used to compute pixel value at 00058 given level. 00059 @param lev The pyramid level to get the pixel value from. */ 00060 template <class T_or_RGB> 00061 T_or_RGB getPyrPixel(const ImageSet<T_or_RGB>& pyr, 00062 const Point2D<int>& p, const uint lev); 00063 00064 //! Get value of a pixel from a dyadic pyramid at a given level and coordinates, no interpolation 00065 /*! @param pix The pixel value returned 00066 @param p Coordinates given at scale 0 (base pyramid level); 00067 This version does not use interpolation. 00068 @param lev The pyramid level to get the pixel value from. */ 00069 template <class T_or_RGB> 00070 T_or_RGB getPyrPixelNI(const ImageSet<T_or_RGB>& pyr, 00071 const Point2D<int>& p, const uint lev); 00072 00073 //! Get value of a pixel from a dyadic pyramid with trilinear interpolation 00074 template <class T_or_RGB> 00075 T_or_RGB getPyrPixel(const ImageSet<T_or_RGB>& pyr, 00076 const float x, const float y, const float z); 00077 00078 // ############################################################ 00079 // ##### Pyramid builder functions: 00080 // ############################################################ 00081 00082 //! Uses a Gaussian filter of size \a filterSize. 00083 template <class T_or_RGB> 00084 ImageSet<T_or_RGB> buildPyrGaussian(const Image<T_or_RGB>& image, 00085 int firstlevel, int depth, 00086 int filterSize); 00087 00088 //! Uses a Gaussian filter of size 5 designed for radially transformed images 00089 template <class T_or_RGB> 00090 ImageSet<T_or_RGB> buildRadialPyrGaussian(const Image<T_or_RGB>& image, 00091 int firstlevel, int depth); 00092 00093 //! Uses an arbitrary filter given as argument 00094 template <class T_or_RGB> 00095 ImageSet<T_or_RGB> buildPyrConvolve(const Image<T_or_RGB>& image, 00096 int firstlevel, int depth, 00097 const Image<float>& filter, 00098 ConvolutionBoundaryStrategy boundary); 00099 00100 //! Uses a Laplacian filter of size \a filterSize. 00101 template <class T_or_RGB> 00102 ImageSet<T_or_RGB> buildPyrLaplacian(const Image<T_or_RGB>& image, 00103 int firstlevel, int depth, 00104 int filterSize); 00105 00106 //! Uses an oriented Laplacian filter with a given size/orientation/intensity. 00107 /*! This is a fast approximation to gabor convolution. 00108 00109 @param usetab Whether to use trig tables to speed up the 00110 computations at the cost of some loss of precision. 00111 */ 00112 template <class T_or_RGB> 00113 ImageSet<T_or_RGB> buildPyrOrientedFromLaplacian(const ImageSet<T_or_RGB>& laplacian, 00114 int filterSize, 00115 float theta, float intens = 10.0f, 00116 const bool usetab = false); 00117 00118 //! Uses an oriented Laplacian filter with a given size/orientation/intensity. 00119 /*! This is a fast approximation to gabor convolution. 00120 00121 @param usetab Whether to use trig tables to speed up the 00122 computations at the cost of some loss of precision. 00123 */ 00124 template <class T_or_RGB> 00125 ImageSet<T_or_RGB> buildPyrOriented(const Image<T_or_RGB>& image, 00126 int firstlevel, int depth, 00127 int filterSize, 00128 float theta, float intens = 10.0f, 00129 const bool usetab = false); 00130 00131 //! Just fills the deepest level with the local image average at that scale. 00132 template <class T_or_RGB> 00133 ImageSet<T_or_RGB> buildPyrLocalAvg(const Image<T_or_RGB>& image, int depth); 00134 00135 //! Each level contains local 2x2 averages of the previous level 00136 template <class T_or_RGB> 00137 ImageSet<T_or_RGB> buildPyrLocalAvg2x2(const Image<T_or_RGB>& image, int depth); 00138 00139 //! Just fills the deepest level with the local image maximum at that scale. 00140 template <class T_or_RGB> 00141 ImageSet<T_or_RGB> buildPyrLocalMax(const Image<T_or_RGB>& image, int depth); 00142 00143 //! Build a pyramid of type given by the PyramidType. 00144 template <class T_or_RGB> 00145 ImageSet<T_or_RGB> buildPyrGeneric(const Image<T_or_RGB>& image, 00146 int firstlevel, int depth, 00147 const PyramidType typ, 00148 const float gabor_theta = 0.0f, 00149 const float gabor_intens = 10.0f); 00150 00151 enum GaborFlags 00152 { 00153 DO_ENERGY_NORM = 1, 00154 DO_LAPLACIAN = 2, 00155 DO_CLAMPED_DIFF = 4, 00156 NO_ABS = 8 00157 }; 00158 00159 //! Build a Gabor Pyramid with a given angle, filter period and elongation 00160 /*!@param size determines the filter size (in pixels) - in the default case 00161 (-1), the size is computed from the filter_period and elongation*/ 00162 ImageSet<float> buildPyrGabor(const ImageSet<float>& gaussianPyr, 00163 float angle, float filter_period, 00164 float elongation = 1.0, 00165 int size = -1, int flags = 0); 00166 00167 //! Build a Gabor Pyramid with a given angle, filter period and elongation 00168 /*!@param size determines the filter size (in pixels) - in the default case 00169 (-1), the size is computed from the filter_preiod and elongation*/ 00170 ImageSet<float> buildPyrGabor(const Image<float>& img, 00171 int firstlevel, int depth, float angle, 00172 float filter_period, float elongation = 1.0, 00173 int size = -1, int flags = 0); 00174 00175 // ############################################################ 00176 // ##### Processing Functions: 00177 // ############################################################ 00178 00179 //! Compute center-surround between images at lev1 and lev2 00180 template <class T> 00181 Image<T> centerSurround(const ImageSet<T>& pyr, 00182 const int lev1, const int lev2, 00183 const bool absol = false, 00184 const ImageSet<float>* clipPyr = 0); 00185 00186 //! Compute center-surround between images, splitting positive and negative 00187 template <class T> 00188 void centerSurround(const ImageSet<T>& pyr, 00189 const int lev1, const int lev2, 00190 Image<T>& pos, Image<T>& neg, 00191 const ImageSet<float>* clipPyr = 0); 00192 00193 //! Compute single-opponent center-surround between images at lev1 and lev2 00194 /*! This is essentially cpyr[lev1] - spyr[lev2] */ 00195 template <class T> 00196 Image<T> centerSurroundSingleOpponent(const ImageSet<T>& cpyr, 00197 const ImageSet<T>& spyr, 00198 const int lev1, const int lev2, 00199 const bool absol = false, 00200 const ImageSet<float>* clipPyr = 0); 00201 00202 //! Compute single-opp center-surr between imgs, splitting pos and neg 00203 template <class T> 00204 void centerSurroundSingleOpponent(const ImageSet<T>& cpyr, 00205 const ImageSet<T>& spyr, 00206 const int lev1, const int lev2, 00207 Image<T>& pos, Image<T>& neg, 00208 const ImageSet<float>* clipPyr = 0); 00209 00210 //! Compute center-surround between difference images at lev1 and lev2 00211 /*! Difference images are obtained at each level by taking the difference 00212 between the image from *this minus the image from other_pyr */ 00213 template <class T> 00214 Image<T> centerSurroundDiff(const ImageSet<T>& pyr1, 00215 const ImageSet<T>& pyr2, 00216 const int lev1, const int lev2, 00217 const bool absol = false, 00218 const ImageSet<float>* clipPyr = 0); 00219 00220 //! Compute center-surround differnces, splitting pos & neg values 00221 template <class T> 00222 void centerSurroundDiff(const ImageSet<T>& pyr1, 00223 const ImageSet<T>& pyr2, 00224 const int lev1, const int lev2, 00225 Image<T>& pos, Image<T>& neg, 00226 const ImageSet<float>* clipPyr = 0); 00227 00228 //! Compute single-opp center-surround btw difference images at lev1 and lev2 00229 /*! Difference images are obtained at each level by taking the difference 00230 between the image from *this minus the image from other_pyr */ 00231 template <class T> 00232 Image<T> centerSurroundDiffSingleOpponent(const ImageSet<T>& cpyr1, 00233 const ImageSet<T>& cpyr2, 00234 const ImageSet<T>& spyr1, 00235 const ImageSet<T>& spyr2, 00236 const int lev1, const int lev2, 00237 const bool absol = false, 00238 const ImageSet<float>* clipPyr = 0); 00239 00240 //! Compute single-opp center-surround differnces, splitting pos & neg values 00241 template <class T> 00242 void centerSurroundDiffSingleOpponent(const ImageSet<T>& cpyr1, 00243 const ImageSet<T>& cpyr2, 00244 const ImageSet<T>& spyr1, 00245 const ImageSet<T>& spyr2, 00246 const int lev1, const int lev2, 00247 Image<T>& pos, Image<T>& neg, 00248 const ImageSet<float>* clipPyr = 0); 00249 00250 //! generate a weighted blur 00251 /*! The higher the modulator value (0..255), the more blurring at that 00252 location */ 00253 template <class T_or_RGB> 00254 Image<T_or_RGB> weightedBlur(const Image<byte>& modulator, 00255 const ImageSet<T_or_RGB>& pyr); 00256 00257 //! Generate a foveation blur 00258 /*! Mask should be 255 inside the object and 0 outside; the pyramid 00259 should be a Gaussian pyramid and will be used to create the 00260 eccentricity-dependent blur. The deeper the pyramid, the more severe 00261 the blur */ 00262 template <class T_or_RGB> 00263 Image<T_or_RGB> foveate(const Image<byte>& mask, 00264 const ImageSet<T_or_RGB>& pyr); 00265 00266 // ###################################################################### 00267 /* So things look consistent in everyone's emacs... */ 00268 /* Local Variables: */ 00269 /* indent-tabs-mode: nil */ 00270 /* End: */ 00271 00272 #endif // !IMAGE_PYRAMIDOPS_H_DEFINED