LPTFoveator.C

Go to the documentation of this file.
00001 /*!@file Foveator/LPTFoveator.C Foveator class that performs log polar transform */
00002 
00003 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Foveator/LPTFoveator.C $
00004 // $Id: LPTFoveator.C 9412 2008-03-10 23:10:15Z farhan $
00005 
00006 #include "Foveator/LPTFoveator.H"
00007 
00008 #include "Image/Pixels.H"
00009 
00010 #include <algorithm> // for std::max()
00011 
00012 // ######################################################################
00013 
00014 // constructor with initialization of original image
00015 
00016 LPTFoveator::LPTFoveator( const Image< PixRGB<byte> >& img,
00017                           int lptW, int lptH) : Foveator( img ),
00018                                                 lptWidth( lptW ),
00019                                                 lptHeight( lptH )
00020 {
00021   if( lptW <= 0 || lptH <= 0 )
00022     LERROR( "LPTFoveator map image must have positive dimensions." );
00023   setOrigin( width / 2, height / 2 );
00024 }
00025 
00026 // destructor
00027 
00028 LPTFoveator::~LPTFoveator()
00029 {
00030   lptMap.clear();
00031 }
00032 
00033 // ######################################################################
00034 
00035 // set origin and recalculate the LPT mapping
00036 
00037 bool LPTFoveator::setOrigin( Point2D<int> pt )
00038 {
00039   if( Foveator::setOrigin( pt ) )
00040     {
00041       // find log multiplier
00042       int maxX = std::max( origin.i, width - origin.i );
00043       int maxY = std::max( origin.j, height - origin.j );
00044       logMultiplier = ( lptWidth - 1 ) / log( maxX*maxX + maxY*maxY + 1.0 );
00045 
00046       // calculate LPT pixel mapping
00047       lptMap.clear();
00048       Point2D<int> mapPt;
00049       Point2D<int> originalPt;
00050       for( int x = 0; x < width; x++ )
00051         {
00052           for( int y = 0; y < height; y++ )
00053             {
00054               originalPt.i = x;
00055               originalPt.j = y;
00056               mapPt.i = (int)radius( x - origin.i, y - origin.j );
00057               mapPt.j = (int)angle( x - origin.i, y - origin.j );
00058               lptMap.insert( std::pair< Point2D<int>, Point2D<int> >
00059                              ( mapPt, originalPt ) );
00060             }
00061         }
00062 
00063       // send positive feedback
00064       return true;
00065     }
00066   else
00067     return false;
00068 }
00069 
00070 bool LPTFoveator::setOrigin( int x, int y )
00071 {
00072   Point2D<int> pt( x, y );
00073   return setOrigin( pt );
00074 }
00075 
00076 // ######################################################################
00077 
00078 Image< PixRGB<byte> > LPTFoveator::foveate( void )
00079 {
00080   Image< PixRGB<byte> > fovImg = invLPT( getLPT() );
00081   return fovImg;
00082 }
00083 
00084 // ######################################################################
00085 
00086 Image< PixRGB<byte> > LPTFoveator::getLPT( void )
00087 {
00088   Image< PixRGB<byte> > lptImg( lptWidth, lptHeight, NO_INIT );
00089   for( int x = 0; x < lptWidth; x++ )
00090     {
00091       for( int y = 0; y < lptHeight; y++ )
00092         {
00093           Point2D<int> pt( x, y );
00094           Point2DMapPtr pmp = lptMap.lower_bound( pt );
00095           int count = 0;
00096           int rAcc = 0;
00097           int gAcc = 0;
00098           int bAcc = 0;
00099           while( pmp != lptMap.upper_bound( pt ) )
00100             {
00101               // accumulation of RGB values
00102               rAcc += original.getVal( (*pmp).second ).red();
00103               gAcc += original.getVal( (*pmp).second ).green();
00104               bAcc += original.getVal( (*pmp).second ).blue();
00105               count++;
00106               pmp++;
00107             }
00108           if( count > 1 )
00109             {
00110               rAcc /= count;
00111               gAcc /= count;
00112               bAcc /= count;
00113             }
00114           PixRGB<byte> pix( rAcc, gAcc, bAcc );
00115           lptImg.setVal( pt, pix );
00116         }
00117     }
00118   return lptImg;
00119 }
00120 
00121 // ######################################################################
00122 
00123 Image< PixRGB<byte> > LPTFoveator::invLPT( const Image< PixRGB<byte> >& img )
00124 {
00125   Image< PixRGB<byte> > invImg( width, height, NO_INIT );
00126   for( Point2DMapPtr pmp = lptMap.begin(); pmp != lptMap.end(); pmp++ )
00127     {
00128       invImg.setVal( (*pmp).second, img.getVal( (*pmp).first ) );
00129     }
00130   return invImg;
00131 }
00132 
00133 // ######################################################################
00134 
00135 Image< PixRGB<byte> > LPTFoveator::foveate( const Image< PixRGB<byte> >& img,
00136                                             int lptW, int lptH, int x, int y,
00137                                             bool getMap )
00138 {
00139   // find log multiplier
00140   int maxX = std::max( x, img.getWidth() - x );
00141   int maxY = std::max( y, img.getHeight() - y );
00142   double logMult = ( lptW - 1 ) / log( maxX * maxX + maxY * maxY + 1.0 );
00143 
00144   // declare and allocate accumulators and counter
00145   int **R_acc;
00146   int **G_acc;
00147   int **B_acc;
00148   int **counter;
00149 
00150   typedef int* intptr;
00151   R_acc = new intptr[lptW];
00152   G_acc = new intptr[lptW];
00153   B_acc = new intptr[lptW];
00154   counter = new intptr[lptW];
00155   for( int i = 0; i < lptW; i++ )
00156     {
00157       R_acc[i] = new int[lptH];
00158       G_acc[i] = new int[lptH];
00159       B_acc[i] = new int[lptH];
00160       counter[i] = new int[lptH];
00161     }
00162 
00163   // initialize accumulators and counter to all zeros
00164   for( int i = 0; i < lptW; i++ )
00165     {
00166       for( int j = 0; j < lptH; j++ )
00167         {
00168           R_acc[i][j] = 0;
00169           G_acc[i][j] = 0;
00170           B_acc[i][j] = 0;
00171           counter[i][j] = 0;
00172         }
00173     }
00174 
00175   // accumulate and count LPT pixels
00176   for( int i = 0; i < img.getWidth(); i++ )
00177     {
00178       for( int j = 0; j < img.getHeight(); j++ )
00179         {
00180           // make coordinates relative to origin
00181           int xx = i - x;
00182           int yy = j - y;
00183 
00184           // determine r
00185           int r = int( logMult * log( xx * xx + yy * yy + 1.0 ) + 0.5 );
00186           // determine theta
00187           int theta;
00188           if( yy == 0 )
00189             {
00190               theta = (int)( ( xx >= 0 ) ?
00191                              0.0 : 0.5 * ( lptH - 1 ) );
00192             }
00193           else if( xx == 0 )
00194             {
00195               theta = (int)( ( yy > 0 ) ?
00196                              0.25 * ( lptH - 1 ) : 0.75 * ( lptH - 1 ) );
00197             }
00198           else
00199             {
00200               theta = (int)( ( M_PI + atan2( -1.0 * yy, -1.0 * xx ) ) /
00201                 ( 2 * M_PI ) * ( lptH - 1 ) + 0.5 );
00202             }
00203 
00204           // add pixel values
00205           R_acc[r][theta] += ( img.getVal( i, j ) ).red();
00206           G_acc[r][theta] += ( img.getVal( i, j ) ).green();
00207           B_acc[r][theta] += ( img.getVal( i, j ) ).blue();
00208           counter[r][theta]++;
00209         }
00210     }
00211 
00212   // write pixels to image
00213   Image< PixRGB<byte> > mapImage( lptW, lptH, NO_INIT );
00214   for( int r = 0; r < lptW; r++ )
00215   {
00216     for( int theta = 0; theta < lptH; theta++ )
00217     {
00218       if( counter[r][theta] > 1 )
00219         {
00220           // divide accumulators by counter matrix
00221           R_acc[r][theta] /= counter[r][theta];
00222           G_acc[r][theta] /= counter[r][theta];
00223           B_acc[r][theta] /= counter[r][theta];
00224         }
00225       PixRGB<byte> pix( R_acc[r][theta], G_acc[r][theta], B_acc[r][theta] );
00226       mapImage.setVal( r, theta, pix );
00227     }
00228   }
00229 
00230   // free memory
00231   delete [] R_acc;
00232   delete [] G_acc;
00233   delete [] B_acc;
00234   delete [] counter;
00235 
00236   if( getMap )
00237     return mapImage;
00238   else
00239     return ( invLPT( mapImage, img.getWidth(), img.getHeight(), x, y ) );
00240 }
00241 
00242 // ######################################################################
00243 
00244 Image< PixRGB<byte> > LPTFoveator::invLPT( const Image< PixRGB<byte> >& img,
00245                                            int w, int h, int x, int y )
00246 {
00247   // find log multiplier
00248   int maxX = std::max( x, w - x );
00249   int maxY = std::max( y, h - y );
00250   double logMult = ( img.getWidth() - 1 ) /
00251     log( maxX * maxX + maxY * maxY + 1.0 );
00252 
00253   Image< PixRGB<byte> > invImage( w, h, NO_INIT );
00254 
00255   // write to image
00256   for( int i = 0; i < w; i++ )
00257   {
00258     for( int j = 0; j < h; j++ )
00259     {
00260       // make coordinates relative to origin
00261       int xx = i - x;
00262       int yy = j - y;
00263 
00264       // determine r
00265       int r = int( logMult * log( xx * xx + yy * yy + 1.0 ) + 0.5 );
00266       // determine theta
00267       int theta;
00268       if( yy == 0 )
00269         {
00270           theta = (int)( ( xx >= 0 ) ?
00271                          0.0 : 0.5 * ( img.getHeight() - 1 ) );
00272         }
00273       else if( xx == 0 )
00274         {
00275           theta = (int)( ( yy > 0 ) ?
00276                          0.25 * ( img.getHeight() - 1 ) :
00277                          0.75 * ( img.getHeight() - 1 ) );
00278         }
00279       else
00280         {
00281           theta = (int)( ( M_PI + atan2( -1.0 * yy, -1.0 * xx ) ) /
00282                          ( 2 * M_PI ) * ( img.getHeight() - 1 ) + 0.5 );
00283         }
00284 
00285       invImage.setVal( i, j, img.getVal( r, theta ) );
00286     }
00287   }
00288   return invImage;
00289 }
00290 
00291 // ######################################################################
00292 /* So things look consistent in everyone's emacs... */
00293 /* Local Variables: */
00294 /* indent-tabs-mode: nil */
00295 /* End: */
Generated on Sun May 8 08:04:47 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3