00001 /*!@file Foveator/PyrFoveator.C Foveator class that builds dyadic pyramid */ 00002 00003 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Foveator/PyrFoveator.C $ 00004 // $Id: PyrFoveator.C 7293 2006-10-20 18:49:55Z rjpeters $ 00005 00006 #include "Foveator/PyrFoveator.H" 00007 00008 #include "Image/ImageSet.H" 00009 #include "Image/Pixels.H" 00010 #include "Image/ShapeOps.H" 00011 00012 // ###################################################################### 00013 00014 // constructor with initialization of original image 00015 PyrFoveator::PyrFoveator( const Image< PixRGB<byte> >& img, 00016 int filterSize ) : Foveator( img ), 00017 builder( filterSize ), 00018 baseRect( 1, 1 ) 00019 { 00020 } 00021 00022 // copy constructor 00023 PyrFoveator::PyrFoveator( const PyrFoveator& pf ) : Foveator( pf.original ), 00024 builder( pf.builder ) 00025 { 00026 baseRect = pf.baseRect; 00027 } 00028 00029 // assignment operator 00030 PyrFoveator& PyrFoveator::operator=( const PyrFoveator& pf ) 00031 { 00032 PyrFoveator *newpf = new PyrFoveator( pf ); 00033 return *newpf; 00034 } 00035 00036 // destructor 00037 PyrFoveator::~PyrFoveator() 00038 { 00039 } 00040 00041 // ###################################################################### 00042 00043 // set base rectangle size 00044 // at center of foveation, all rects will be multiples of this one 00045 void PyrFoveator::setBaseRect( Dims& d ) 00046 { 00047 baseRect = d; 00048 } 00049 00050 void PyrFoveator::setBaseRect( int x, int y ) 00051 { 00052 Dims rect(x,y); 00053 baseRect = rect; 00054 } 00055 00056 // ###################################################################### 00057 00058 Image< PixRGB<byte> > PyrFoveator::foveate( void ) 00059 { 00060 // determine necessary pyramid depth 00061 int expW = baseRect.w(); 00062 int expH = baseRect.h(); 00063 int depth = 0; 00064 while( ( origin.i + expW < width ) || ( origin.i - expW > 0 ) || 00065 ( origin.j + expW < height ) || ( origin.j - expW > 0 ) ) 00066 { 00067 depth++; 00068 expW *= 2; 00069 expH *= 2; 00070 } 00071 00072 // build pyramid 00073 ImageSet< PixRGB<byte> > pyramid( depth ); 00074 pyramid = builder.build( original, 0, depth ); 00075 for( int d = 0; d < depth; d++ ) 00076 pyramid[d] = rescale( pyramid[d], width, height ); 00077 00078 // pile the images on one another like a pyramid 00079 Image< PixRGB<byte> > fovImg( pyramid[depth-1] ); 00080 for( int d = depth - 2; d >= 0; d-- ) 00081 { 00082 int xOffset = baseRect.w(); 00083 int yOffset = baseRect.h(); 00084 for( int p = 0; p < d; p++ ) 00085 { 00086 xOffset *= 2; 00087 yOffset *= 2; 00088 } 00089 for( int x = origin.i - xOffset; x < origin.i + xOffset; x++ ) 00090 { 00091 for( int y = origin.j - yOffset; y < origin.j + yOffset; y++ ) 00092 { 00093 if( fovImg.coordsOk( x, y ) ) 00094 { 00095 fovImg.setVal( x, y, pyramid[d].getVal( x, y ) ); 00096 } 00097 } 00098 } 00099 } 00100 00101 // return the image 00102 return fovImg; 00103 } 00104 00105 // ###################################################################### 00106 00107 Image< PixRGB<byte> > PyrFoveator::foveate( const Image< PixRGB<byte> >& img, 00108 int filterSize, int baseRectWidth, 00109 int baseRectHeight, int x, int y ) 00110 { 00111 // determine necessary pyramid depth 00112 int expW = baseRectWidth; 00113 int expH = baseRectHeight; 00114 int depth = 0; 00115 while( ( x + expW < img.getWidth() ) || ( x - expW > 0 ) || 00116 ( y + expW < img.getHeight() ) || ( y - expW > 0 ) ) 00117 { 00118 depth++; 00119 expW *= 2; 00120 expH *= 2; 00121 } 00122 00123 // build pyramid 00124 GaussianPyrBuilder< PixRGB<byte> > builder( filterSize ); 00125 ImageSet< PixRGB<byte> > pyramid( depth ); 00126 pyramid = builder.build( img, 0, depth ); 00127 for( int d = 0; d < depth; d++ ) 00128 pyramid[d] = rescale( pyramid[d], img.getWidth(), img.getHeight() ); 00129 00130 // pile the images on one another like a pyramid 00131 Image< PixRGB<byte> > fovImg( pyramid[depth-1] ); 00132 for( int d = depth - 2; d >= 0; d-- ) 00133 { 00134 int xOffset = baseRectWidth; 00135 int yOffset = baseRectHeight; 00136 for( int p = 0; p < d; p++ ) 00137 { 00138 xOffset *= 2; 00139 yOffset *= 2; 00140 } 00141 for( int xx = x - xOffset; xx < x + xOffset; xx++ ) 00142 { 00143 for( int yy = y - yOffset; yy < y + yOffset; yy++ ) 00144 { 00145 if( fovImg.coordsOk( xx, yy ) ) 00146 { 00147 fovImg.setVal( xx, yy, pyramid[d].getVal( xx, yy ) ); 00148 } 00149 } 00150 } 00151 } 00152 00153 // return the image 00154 return fovImg; 00155 } 00156 00157 // ###################################################################### 00158 /* So things look consistent in everyone's emacs... */ 00159 /* Local Variables: */ 00160 /* indent-tabs-mode: nil */ 00161 /* End: */