00001 /*!@file Foveator/LPTFoveator.H Foveator class that performs log polar transform */ 00002 00003 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Foveator/LPTFoveator.H $ 00004 // $Id: LPTFoveator.H 9412 2008-03-10 23:10:15Z farhan $ 00005 00006 #ifndef LPTFOVEATOR_H_DEFINED 00007 #define LPTFOVEATOR_H_DEFINED 00008 00009 #include "Foveator/Foveator.H" 00010 #include <cmath> 00011 #include <map> 00012 #include <utility> 00013 00014 //! A class that does space-variant processing with log polar transform 00015 /*! A log-polar transform (LPT) maps pixels of the original image to a smaller 00016 "map" image that holds pixel data. The LPT transforms rectangular \f$(x,y)\f$ 00017 coordinates into \f$(r,\theta)\f$, where r is a function of the log of the 00018 radius from the point to the origin, and \f$\theta\f$ is the angle from the 00019 horizontal axis. 00020 00021 For points close to the origin, the result is that the LPT mapping is almost 00022 one-to-one, while in the periphery many pixels may correspond to a single 00023 ordered pair of \f$(r,\theta)\f$, resulting in some degree of data loss. To 00024 display the foveated image an inverse LPT must be performed with the invLPT() 00025 set of methods. 00026 00027 LPTFoveator is very fast compared with BlurFoveator and PyrFoveator, and 00028 is useful for compression. However, there is a significant amount of 00029 blockiness in the periphery in the foveated image, and it seems that noise can 00030 have a serious effect on image quality. 00031 */ 00032 00033 class LPTFoveator : public Foveator 00034 { 00035 private: 00036 int lptWidth; 00037 int lptHeight; 00038 double logMultiplier; 00039 00040 //! a function object for the key compare in multimap 00041 struct ltPoint2D 00042 { 00043 bool operator()( const Point2D<int> pt1, const Point2D<int> pt2 ) const 00044 { 00045 if( pt1.j < pt2.j ) 00046 return true; 00047 else if( pt1.j > pt2.j ) 00048 return false; 00049 else 00050 { 00051 return( pt1.i < pt2.i ); 00052 } 00053 } 00054 }; 00055 00056 // to make life simpler for the coder: 00057 typedef std::multimap< Point2D<int>, Point2D<int>, ltPoint2D > Point2DMap; 00058 typedef Point2DMap::const_iterator Point2DMapPtr; 00059 00060 Point2DMap lptMap; //!< our log-polar mapping 00061 00062 //! Radius calculation function based on distance between point and origin 00063 inline double radius( int x, int y ); 00064 /*! Angle calculation function based on angle from origin (positive x-axis) 00065 to point */ 00066 inline double angle( int x, int y ); 00067 00068 public: 00069 //! Construct a LPTFoveator for img 00070 /*! This constructor will create a LPTFoveator that handles img and all 00071 other images of the same dimensions. 00072 @param img image to be foveated 00073 @param lptW width of log-polar map image, controls radial detail 00074 @param lptH height of log-polar map image, controls angular detail 00075 */ 00076 LPTFoveator( const Image< PixRGB<byte> >& img, int lptW, int lptH ); 00077 00078 //! Destructor 00079 ~LPTFoveator(); 00080 00081 //! Set origin point (center of foveation) 00082 /*! Set origin point to Point2D<int> argument, returns true if successful 00083 @param pt center of foveation 00084 */ 00085 virtual bool setOrigin( Point2D<int> pt ); 00086 //! Set origin point (center of foveation) 00087 /*! Set origin point to two int arguments, returns true if successful 00088 @param x horizontal coordinate of origin 00089 @param y vertical coordinate of origin 00090 */ 00091 virtual bool setOrigin( int x, int y ); 00092 00093 //! Perform log-polar foveation and return resulting image 00094 Image< PixRGB<byte> > foveate( void ); 00095 //! Perform log-polar transform and return map image 00096 Image< PixRGB<byte> > getLPT( void ); 00097 //! Perform inverse log-polar transform on a map image to get foveated image 00098 /*! This function can do an inverse log-polar transform on an image returned 00099 by LPTFoveator::getLPT(). It will be important that this function must be 00100 called from the same LPTFoveator object that created the map image, or 00101 from one with the same configuration parameters. Also, the origin must not 00102 have been changed since the map image was generated. 00103 @param img map image (source from which foveated image will be created) 00104 */ 00105 Image< PixRGB<byte> > invLPT( const Image< PixRGB<byte> >& img ); 00106 00107 //! Perform one log-polar foveation without a LPTFoveator 00108 /*! This function is for foveating ONE image with a call such as 00109 LPTFoveator::foveate(). It is not optimized for foveating multiple 00110 images. 00111 @param img image to be foveated 00112 @param lptW width of log-polar map image, controls radial detail 00113 @param lptH height of log-polar map image, controls angular detail 00114 @param x horizontal coordinate of origin 00115 @param y vertical coordinate of origin 00116 @param getMap set this to true if you want to have this function return 00117 map image rather than foveated image 00118 */ 00119 static Image< PixRGB<byte> > foveate( const Image< PixRGB<byte> >& img, 00120 int lptW, int lptH, int x, int y, 00121 bool getMap = false ); 00122 //! Get foveated image from log-polar map image 00123 /*! This function can be used to perform an inverse log-polar transform 00124 without a LPTFoveator. It is not optimized for performing this operation 00125 on multiple images, but it would be faster to use this function on an map 00126 image than to call LPTFoveator::foveate() again with getMap = true. 00127 @param img image to be foveated 00128 @param w width of original image (before LPT) 00129 @param h height of original image (before LPT) 00130 @param x horizontal coordinate of origin 00131 @param y vertical coordinate of origin 00132 */ 00133 static Image< PixRGB<byte> > invLPT( const Image< PixRGB<byte> >& img, 00134 int w, int h, int x, int y ); 00135 }; 00136 00137 // ###################################################################### 00138 // ########## Inlined methods: 00139 // ###################################################################### 00140 00141 inline double LPTFoveator::radius( int x, int y ) 00142 { 00143 return( logMultiplier * log( x*x + y*y + 1.0 ) + 0.5 ); 00144 } 00145 00146 inline double LPTFoveator::angle( int x, int y ) 00147 { 00148 if( y == 0 ) 00149 { 00150 return( ( x >= 0 ) ? 00151 0.0 : 0.5 * ( lptHeight - 1 ) ); 00152 } 00153 if( x == 0 ) 00154 { 00155 return( ( y > 0 ) ? 00156 0.25 * ( lptHeight - 1 ) : 0.75 * ( lptHeight - 1 ) ); 00157 } 00158 return( ( M_PI + atan2( -1.0 * y, -1.0 * x ) ) / 00159 ( 2 * M_PI ) * ( lptHeight - 1 ) + 0.5 ); 00160 } 00161 00162 #endif 00163 00164 // ###################################################################### 00165 /* So things look consistent in everyone's emacs... */ 00166 /* Local Variables: */ 00167 /* indent-tabs-mode: nil */ 00168 /* End: */