00001 /*!@file SpaceVariant/SpaceVariantTransform.H */ 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: David J. Berg <dberg@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/SpaceVariant/SpaceVariantTransforms.H $ 00035 00036 #ifndef IMAGE_SPACEVARIANTTRANSFORMS_H_DEFINED 00037 #define IMAGE_SPACEVARIANTTRANSFORMS_H_DEFINED 00038 00039 #include "SpaceVariant/ScaleSpaceOps.H" 00040 #include "Image/Image.H" 00041 #include "Util/Promotions.H" 00042 00043 //forward declare 00044 template <class T> class ImageSet; 00045 //###################################################################### 00046 // SpaceVariantTransform 00047 // 00048 // This is a general interface for a family of space variant image transforms. Space variant transforms remap a 00049 // cartesian image (x,y) to a new space variant representation consisting of (u, v, r), where u and v represents new 00050 // space dimensions and r isthe size of the receptive field (the amount of many-to-one mapping in cartesian pixels) of 00051 // pixel u, v. The receptive field describes the spatial influcuence a single pixel in (x,y) will have in (u,v,r). 00052 // 00053 // ###################################################################### 00054 class SpaceVariantTransform 00055 { 00056 public: 00057 typedef Image<std::pair<float, float> >::iterator iterator; 00058 typedef Image<std::pair<float, float> >::const_iterator const_iterator; 00059 00060 //! constructor 00061 SpaceVariantTransform(); 00062 00063 //! destructor 00064 ~SpaceVariantTransform(); 00065 00066 //!are we initialized? 00067 bool initialized() const; 00068 00069 //!transform a point from cartesian to space variant coordinates 00070 void to(const int x, const int y, int& u, int& v) const; 00071 00072 //!transform a point from cartesian to space variant coordinates 00073 void to(const int x, const int y, float& u, float& v) const; 00074 00075 //!transform a point from space variant to cartesian coordinates 00076 void from(const int u, const int v, int& x, int& y) const; 00077 00078 //!transform a point from space variant to cartesian coordinate 00079 void from(const int u, const int v, float& x, float& y) const; 00080 00081 //!get the cartesian image size 00082 const Dims& getCTDims() const; 00083 00084 //!get the space variant image size 00085 const Dims& getSVDims() const; 00086 00087 //! get the rf size at the specified ring. returns the standard deviation of 00088 //! the gaussian used to model the RF. 00089 const float& getRFSize(const uint u, const uint v) const; 00090 00091 //! get the rf size at the specified ring. returns the standard deviation of 00092 //! the gaussian used to model the RF. This version uses interpolation 00093 float getRFSize(const float& u, const float& v) const; 00094 00095 //! get the rf size at the specified ring. returns the standard deviation of 00096 //! the gaussian used to model the RF. 00097 const float& getRFSize(const uint pos) const; 00098 00099 //!get the max rf size 00100 float getMaxRFSize() const; 00101 00102 //!get a const iterator to the lookup table 00103 const_iterator begin() const; 00104 00105 //!get a const iterator to the lookup table 00106 const_iterator end() const; 00107 00108 //!get a const iterator to the reverse lookup table 00109 const_iterator rbegin() const; 00110 00111 //!get a const iterator to the reverse lookup table 00112 const_iterator rend() const; 00113 00114 //get a const iterator to the rf lookup table 00115 Image<float>::const_iterator rfbegin() const; 00116 00117 //get a const iterator to the rf lookup table 00118 Image<float>::const_iterator rfend() const; 00119 00120 protected: 00121 //!compute the distance from xpos, ypos to the nearest image 00122 //!boundary given the angle(radians) 00123 float computeDistance(const float& angle, const uint xpos, const uint ypos, 00124 const uint imgw, const uint imgh); 00125 00126 //store our lookup tables as floats in a case we want to interpolate 00127 Image<std::pair<float, float> > itsLookup, itsRevLookup; 00128 Image<float> itsStd; 00129 float itsMaxStd; 00130 bool isInitialized; 00131 }; 00132 00133 // ###################################################################### 00134 //Computations for a foveal transform - SpaceVariantModule for a model 00135 // component which implements default params etc... 00136 // 00137 //FovealTransform - model of the retinal ganglial cell or visual structures 00138 //like the superior colliculus, thalamus or early visual cortex. We model 00139 //the relationship between eccentricity from the fixation point and 00140 //density of receptor units using the basic variable resolution transform 00141 //described in Wiebe & Basu ('95). The default parameters are estimated from the 00142 //best fit to the data from ??? on ???. The receptive field (modeled as 00143 //a Gaussian parameterized by sigma) has a non-linear relationship between 00144 //eccentricity and size and the default paramters fit an exponential equation 00145 //to the data from Croner & Kaplan ('93) where the authors measured RF sizes for 00146 //magno- and parvocellular ganglion cells at a wide range of eccentricities. 00147 //the default params fit the parvo-ganglion cells data. 00148 //###################################################################### 00149 struct FovealTransform : public SpaceVariantTransform 00150 { 00151 //to indate the scaling condition 00152 enum SCALE_TYPE {CROP, FULL, NONE}; 00153 00154 //!constructor 00155 FovealTransform(); 00156 00157 //default distrucor, copy etc OK 00158 00159 //!convert a string to scale type 00160 static SCALE_TYPE toScaleType(const std::string& scale_type_string); 00161 00162 //!set transform parameters and compute lookup table. 00163 void setup(const uint image_width, const uint image_height, 00164 const uint rings, const uint wedges, 00165 const float& alpha, const float& beta, 00166 const float& gain, const float& exponent, const float& offset, 00167 const float& ppdx, const float& ppdy, 00168 const SCALE_TYPE& scale_type = FovealTransform::FULL, 00169 const float& s = 0.0F, const float& fovea_cuttoff = 2.0F); 00170 00171 //get the fovial size in pixels 00172 const uint getFoveaSize() const; 00173 00174 private: 00175 int u_FoveaSize; 00176 }; 00177 00178 // ###################################################################### 00179 // ###################################################################### 00180 // free functions for SpaceVariantTransform 00181 // ###################################################################### 00182 // ###################################################################### 00183 //!return a space variant image 00184 // ###################################################################### 00185 template <class T_or_RGB> 00186 Image<T_or_RGB> transformTo(const SpaceVariantTransform& sv, const Image<T_or_RGB>& input, const ImageSet<typename promote_trait<T_or_RGB, float>::TP>* const cache = NULL, const float& offset = 0.0F); 00187 00188 // ###################################################################### 00189 //!return a cartesian image from a space variant one 00190 // ###################################################################### 00191 template <class T_or_RGB> 00192 Image<T_or_RGB> transformFrom(const SpaceVariantTransform& sv,const Image<T_or_RGB>& input); 00193 00194 // ###################################################################### 00195 //!return a space variant image with center surround processing where 00196 // the surround size is determined by mutliplying the center sigma by 00197 // surround_mult (asumes a SpaceVariantTransform where getRf() returns 00198 // the size in units of sigma). From Croner & Kaplan ('95) a value 00199 // of ~6 gives the average retinal ganglion cell 00200 // ###################################################################### 00201 template <class T_or_RGB> 00202 Image<typename promote_trait<T_or_RGB, float>::TP> 00203 transformToDoG(const SpaceVariantTransform& sv, const Image<T_or_RGB>& input, const float& surround_mult, 00204 const bool centeron, const ImageSet<typename promote_trait<T_or_RGB, float>::TP>* const cache = NULL, const float& offset = 0.0F); 00205 00206 // ###################################################################### 00207 /*!return a space variant image with edge processing 00208 00209 Get value of a local edge by pooling nearby on only and off only 00210 responses, but allowing the centers to differ. The tree shrew 00211 apparently creates edge detecting cells in this fashion see 00212 Hirsh and Martiniz, Trends Neuro Sci, 2006 for a review. 00213 The result is squared. 00214 */ 00215 // ###################################################################### 00216 template <class T_or_RGB> 00217 Image<typename promote_trait<T_or_RGB, float>::TP> 00218 transformToEdge(const SpaceVariantTransform& sv, const Image<T_or_RGB>& input, const Image<LocalEdge>& edgemap, 00219 const ImageSet<typename promote_trait<T_or_RGB, float>::TP>* const cache = NULL, const float& offset = 0.0F); 00220 00221 // ###################################################################### 00222 /*!return a space variant image with edge processing, surround_mult is as in 00223 // transformToDoG 00224 00225 The wiring diagram is inspired by: 00226 Hirsh and Martiniz, Trends Neuro Sci, 2006 (for a reviw). 00227 We model the orientation of a pixel as an on-center DiffScaleSpacePixel 00228 adjacent to an off-center one, creating a local orientation estimation. 00229 When the parameters are chosen correctly this looks simmilar to a odd gabor or 00230 a third derivitive Gaussian An edge is then modeled as a length of local co-oriented local 00231 orientations at a specific density. The result is squared. 00232 */ 00233 00234 // ###################################################################### 00235 template <class T_or_RGB> 00236 Image<typename promote_trait<T_or_RGB, float>::TP> 00237 transformToEdge(const SpaceVariantTransform& sv, const Image<T_or_RGB>& input, const float& surround_mult, 00238 const Image<LocalEdge>& edgemap, const ImageSet<typename promote_trait<T_or_RGB, float>::TP>* const cache = NULL, const float& offset = 0.0F); 00239 00240 // ###################################################################### 00241 //!return a space variant pyramid with DoG processing 00242 // ###################################################################### 00243 template <class T_or_RGB> 00244 ImageSet<typename promote_trait<T_or_RGB, float>::TP> 00245 transformToDoGPyramid(const SpaceVariantTransform& sv, const Image<T_or_RGB>& input, const float& surround_mult, const bool centeron, const std::vector<float>& scales, const ImageSet<typename promote_trait<T_or_RGB, float>::TP>* const cache = NULL); 00246 00247 // ###################################################################### 00248 //!return a space variant pyramid with Edge processing 00249 // ###################################################################### 00250 template <class T_or_RGB> 00251 ImageSet<typename promote_trait<T_or_RGB, float>::TP> 00252 transformToEdgePyramid(const SpaceVariantTransform& sv, const Image<T_or_RGB>& input, const Image<LocalEdge>& edgemap, const float& orientation, const uint& length, const float& density, const std::vector<float>& scales, const ImageSet<typename promote_trait<T_or_RGB, float>::TP>* const cache = NULL); 00253 00254 // ###################################################################### 00255 //!return a space variant pyramid with Edge processing 00256 // ###################################################################### 00257 template <class T_or_RGB> 00258 ImageSet<typename promote_trait<T_or_RGB, float>::TP> 00259 transformToEdgePyramid(const SpaceVariantTransform& sv, const Image<T_or_RGB>& input, const float& surround_mult, const Image<LocalEdge>& edgemap, const float& orientation, const uint& length, const float& density, const std::vector<float>& scales, const ImageSet<typename promote_trait<T_or_RGB, float>::TP>* const cache = NULL); 00260 00261 // ###################################################################### 00262 // ###################################################################### 00263 // Needs updating to work with std instead of variance 00264 // free functions for FovealTransform: 00265 // These are different implementations of the transformTo and transformFrom 00266 // If the variance of the largest ring is small, this can be faster and 00267 // interpolation can be turned off. 00268 // ###################################################################### 00269 // ###################################################################### 00270 //!return a space variant image 00271 // ###################################################################### 00272 template <class T_or_RGB> 00273 Image<T_or_RGB> transformToFoveal(const FovealTransform& sv, const Image<T_or_RGB>& input, const bool interp); 00274 00275 // ###################################################################### 00276 //!return a space variant image with center surround processing 00277 // ###################################################################### 00278 template <class T_or_RGB> 00279 Image<typename promote_trait<T_or_RGB, float>::TP> 00280 transformToDoGFoveal(const FovealTransform& sv, const Image<T_or_RGB>& input, 00281 const float& smult, const bool centeron, const bool interp); 00282 00283 // ###################################################################### 00284 // ###################################################################### 00285 // Other Functions 00286 // ###################################################################### 00287 // ###################################################################### 00288 /*!On each hemifields top and bottom, extend the image by 00289 replicating a flipped version of the opposite hemifields pixels. 00290 This enables standard image processing algorithms to be applied 00291 with appropriate boarder conditions. The replicated pixels can then 00292 be removed after processing. 00293 00294 Note: This is NOT optimized. The preffered method is to filter 00295 such that boundaries extend to the opposite hemifield. See Image/LowPassLpt.H */ 00296 // ###################################################################### 00297 template <class T_or_RGB> 00298 Image<T_or_RGB> replicateHemifield(const Image<T_or_RGB>& inp, const uint pix = 48); 00299 00300 00301 // ###################################################################### 00302 // get separate the fovial and peripherial image 00303 // ###################################################################### 00304 template <class T_or_RGB> 00305 void getFoveaPeriphery(const FovealTransform& sv, const Image<T_or_RGB>& ret_image, 00306 Image<T_or_RGB>& fovia, Image<T_or_RGB>& periphery); 00307 00308 // ###################################################################### 00309 //returns a vector of local edges 00310 // ###################################################################### 00311 Image<LocalEdge> LocalEdgeMap(const SpaceVariantTransform& sv, const float& surround_mult, 00312 const float& orientation, const uint& length, const uint density); 00313 00314 // ###################################################################### 00315 /* So things look consistent in everyone's emacs... */ 00316 /* Local Variables: */ 00317 /* mode: c++ */ 00318 /* indent-tabs-mode: nil */ 00319 /* End: */ 00320 00321 #endif // IMAGE_SPACEVARIANTTRANSFORMS_H_DEFINED