The Machine Perception Toolbox

[Introduction]- [News]- [Download]- [Screenshots]- [Manual (pdf)]- [Forums]- [API Reference]- [Repository ]

 

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

mac/build/mpisearch.framework/Headers/mpiimage.h

Go to the documentation of this file.
00001 /*  
00002 *  mpiimage.h
00003 *   - header for Machine Perception lab Integral Image container object
00004 *
00005 *  Created by Ian Fasel on Feb 02, 2003.
00006 *  Fixes: 
00007 * 
00008 *  Copyright (c) 2003 Machine Perception Laboratory 
00009 *  University of California San Diego.
00010 * 
00011 * Please read the disclaimer and notes about redistribution 
00012 * at the end of this file.
00013 *
00014 * Three main goals:
00015 *    1) Simplify interface for iterating across all windows at all scales
00016 *    2) Provide easy ROI operator
00017 *    3) allow use of cached indexes for faster lookups
00018 *
00019 * Usage:
00020 * MPIImagePyramid ip(image_list, scale_factor, ROI, stride, window_size);
00021 * for(MPIImagePyramid::iterator scale = ip.begin(); scale != ip.end(); ++scale){
00022 *   for(MPIImagePyramid::MPIScaledImage::iterator iter = (*scale).begin(); iter != (*scale).end(); ++iter){
00023 *     iter.getFeature(feature1, layer1);
00024 *     iter.getFeature(feature1, layer2);
00025 *   }
00026 * }
00027 */
00028 
00029 #ifndef _MPIIMAGE_H_
00030 #define _MPIIMAGE_H_
00031 
00032 #include <fstream>
00033 #include <vector>
00034 
00035 #include "rimage.h"
00036 #include "square.h"
00037 #include "roi.h"
00038 #include "faceboxlist.h"
00039 
00040 using namespace std;
00041 
00042 template<class T> class MPIImagePyramid; // forward declaration for convenience
00043 
00044 template<class T>
00045 class MPIScaledImage{
00046   //private:
00047   
00048  public:
00049   const MPIImagePyramid<T>& m_ref;
00050   float shift;
00051   const int m_scale_ind;
00052   const int m_scale_factor;
00053   const float m_true_scale_factor;
00054   int   subwin_size_x; // Note: this is pure evil if m_true_scale_factor * (m_ref.m_window_x) is not an integer;
00055   int   subwin_size_y; // same as above
00056   int m_min_x, m_max_x, m_min_y, m_max_y;
00057   MPIScaledImage(const MPIImagePyramid<T>& ref, const int &scale_ind)
00058     : m_ref(ref), m_scale_ind(scale_ind), m_scale_factor(static_cast<int>(m_ref.scale_factors[scale_ind]+0.5)),
00059       m_true_scale_factor(ref.scale_factors[scale_ind]) {
00060     shift = max(1.0f,m_scale_factor*(m_ref.m_stride + 0.00001f));  // Fudge to make sure floor works correctly
00061     //cout << "Shift: " << shift << endl;
00062     subwin_size_x = static_cast<int>(m_true_scale_factor * (m_ref.m_window_x)+0.0001f);
00063     subwin_size_y = static_cast<int>(m_true_scale_factor * (m_ref.m_window_y)+0.0001f);
00064     m_min_x = ref.m_roi.vmin_x[scale_ind];
00065     m_max_x = ref.m_roi.vmax_x[scale_ind];
00066     m_min_y = ref.m_roi.vmin_y[scale_ind];
00067     m_max_y = ref.m_roi.vmax_y[scale_ind];
00068     //cout << "MPIScaledImage: m_scale_factor: "<< m_scale_factor << " m_min_x: " <<  m_min_x << ", m_max_x: " << m_max_x;
00069     //cout << ", m_min_y: " <<  m_min_y << ", m_max_y: " << m_max_y << endl;
00070   }
00071   class const_iterator{
00072   private:
00073     typedef const_iterator self;
00074     const MPIScaledImage< T > & m_ref;
00075     const vector< RImage< T > * >& ref_image; //  gcc 2.95 requires this... bug in gcc?
00076     const T* pixel0, *pixel1; // a reference to the first pixel of the first two images.  Probably evil.
00077     int m_max_x, m_max_y, m_max_valid_x_ind, m_max_valid_y_ind;
00078     float m_pos_x, m_pos_y;
00079     int m_working_x, m_working_y;
00080     //int old_x, old_y;
00081     int m_ind, m_line_ind;
00082     int m_min_x;
00083     float m_min_x_f;
00084     float m_shift;
00085     public:
00086       const_iterator(MPIScaledImage<T>& ref, const int &pos_x, const int &pos_y) : m_ref(ref),
00087         ref_image(m_ref.m_ref.m_image), m_shift(ref.shift) {
00088              //cout << "m_shift: " << m_shift << endl;
00089             m_working_x = pos_x; //+ m_ref.m_scale_factor - 1;
00090             m_working_y = pos_y; // + m_ref.m_scale_factor - 1;
00091             m_pos_x = static_cast<float>(m_working_x);
00092             m_pos_y = static_cast<float>(m_working_y);
00093             m_line_ind = m_working_y*ref_image[0]->width;
00094             m_ind = m_line_ind + m_working_x;
00095             m_max_x = m_ref.m_max_x - (m_ref.subwin_size_x); 
00096             m_max_y = m_ref.m_max_y - (m_ref.subwin_size_y);
00097             //cout << "iterator.m_max_x = " << m_max_x << endl;
00098             //cout << "iterator.m_max_y = " << m_max_y << endl;
00099             m_max_valid_x_ind = ref_image[0]->width - m_ref.subwin_size_x;
00100             m_max_valid_y_ind = ref_image[0]->height - m_ref.subwin_size_y;
00101             m_min_x = m_ref.m_min_x; // + m_ref.m_scale_factor - 1;
00102             m_min_x_f = static_cast<float>(m_min_x);
00103 
00104         pixel0 = ref_image[0]->array + m_ind;
00105         pixel1 = ref_image[1]->array + m_ind;
00106         //cout << "m_working_x = " << m_working_x << "   m_working_y = " << m_working_y << endl; 
00108         //old_x = m_working_x;
00109         //old_y = m_working_y;  
00111                 }
00112                 
00113       // Increment Logic
00114                 inline void do_increment(){
00115                   //cout << "m_pos_x: " << m_pos_x ;
00116                   //cout << ", m_pos_x + m_shift: " << m_pos_x + m_shift;
00117                   m_pos_x += m_shift;
00118                   //cout << ", static_cast<int>(m_pos_x): " << static_cast<int>(m_pos_x) << endl;
00119                   m_working_x = static_cast<int>(m_pos_x);
00120                   if(m_working_x < m_max_x){
00121                     //cout <<  "m_max_x= " << m_max_x << ",   m_working_x < m_max_x= " << (m_working_x < m_max_x) << "     "; 
00122                     m_ind = m_line_ind + m_working_x;
00123                     //cout << "m_pos_x: " << m_pos_x << ", m_working_x: " << m_working_x << endl;
00124                   } else {
00125                     
00127                     //cout << "Could have gone as far as ";
00128                     //int tmpx = m_working_x, tmpy = m_working_y;
00129                     //m_working_x = old_x; m_working_y = old_y;
00130                     //getScalePixel(0,24,24);
00131                     //m_working_x = tmpx; m_working_y = tmpy;
00133                     
00134                     m_pos_x = m_min_x_f; 
00135                     m_working_x = m_min_x; 
00136                     m_pos_y += m_shift;
00137                     m_working_y = static_cast<int>(m_pos_y);
00138                     m_line_ind = m_working_y*ref_image[0]->width;
00139                     m_ind = m_line_ind + m_working_x;
00140                     //cout << "iterator.m_working_x = " << m_working_x << 
00141                     //",  iterator.m_working_y = " << m_working_y << "   m_pos_y = " << m_pos_y << endl;
00142                   }
00143                   pixel0 = ref_image[0]->array + m_ind;
00144                   pixel1 = ref_image[1]->array + m_ind;
00146                   //old_x = m_working_x;
00147                   //old_y = m_working_y;
00149                 }
00150                 //: Preincrement
00151                 inline self& operator++ () { 
00152                   do_increment(); 
00153                   //cout << "(" << m_working_x << ","<< m_working_y << ") ";
00154                   return *this; }
00155                 //: Postincrement
00156                 inline self operator++ (int) { self tmp = *this; do_increment(); return tmp; }
00157                 inline self& operator=(const self &it){
00158                   m_max_x = it.m_max_x; m_max_y=it.m_max_y; m_max_valid_x_ind=it.m_max_valid_x_ind;
00159                   m_max_valid_y_ind=it.m_max_valid_y_ind; m_pos_x=it.m_pos_x; m_pos_y=it.m_pos_y;
00160                   m_working_x=it.m_working_x; m_working_y=it.m_working_y; m_ind=it.m_ind; m_line_ind=it.m_line_ind;
00161                   return *this;
00162                 }
00163                 //: Predecrement
00164                 //inline self& operator-- () { --m_pos; return *this; }
00165                 //: Postdecrement
00166                 //inline self operator-- (int) { self tmp = *this; --m_pos; return tmp; }
00167                 
00168                 inline T operator*() const{ return ref_image[0]->getPixel( m_ind ); }
00169                 inline bool operator!=(const self& x) const { return m_ind != x.m_ind; }
00170                 inline bool operator<=(const self& x) const { return m_pos_y <= x.m_pos_y; }
00171                 inline RImage<T>& operator[](int i) const { return *ref_image[i]; }
00172                 inline void getIndex(int &ind) const { ind = m_ind; }
00173                 inline void getCoords(int &x, int &y) const { x = m_working_x, y = m_working_y; }
00174                 inline int getSize() const {return m_ref.subwin_size_x;}
00175                 
00176                 //-------------------------------------------
00177                 // Get Pixel functions
00178                 //
00179       inline T getPixel(const int &i, const int &ind){
00181         //int x,y;
00182         //x = m_ind / ref_image[i]->height;
00183         //y = m_ind % ref_image[i]->height;
00184         //cout << "Going for pixel (" << x << "," << y << ")... ";
00185         //int val = ref_image[i]->getPixel(m_ind+ind);
00186         //cout << "got it."<< endl;
00188 
00189         return ref_image[i]->getPixel(m_ind+ind); }
00190 
00192        //return val; }
00194 
00195         // A get pixel function for getting at image[0] pixels really fast.
00196         inline T getPixel0(const int &ind) const { return pixel0[ind]; }
00197         // A get pixel function for getting at image[1] pixels really fast.
00198         inline T getPixel1(const int &ind) const { return pixel1[ind]; }
00199 
00200       // special getPixel for cases where it is necessary to protect against going off the edge of the image
00201       inline T getPixel(const int &i, const int &ind, const int &x, const int &y) const
00202         {
00203           if((m_working_x < 0) || (m_working_y < 0) || (m_working_x > m_max_valid_x_ind) || (m_working_y > m_max_valid_y_ind))
00204             return ref_image[i]->getPixel(m_working_x + x, m_working_y + y);
00205           else
00206             return ref_image[i]->getPixel(m_ind+ind);
00207         }
00208       inline T getScalePixel(const int &i, const int &x, const int &y) const {
00209         //cout << "accessing pixel (" << m_working_x + x * m_ref.m_scale_factor <<","
00210         //     << m_working_y + y * m_ref.m_scale_factor <<")... ";
00211         //T val = ref_image[i]->getPixel(m_working_x + x * m_ref.m_scale_factor, m_working_y + y * m_ref.m_scale_factor);
00212         //cout << "got it. Value is " << val << endl;
00213         return ref_image[i]->getPixel(m_working_x + x * m_ref.m_scale_factor, m_working_y + y * m_ref.m_scale_factor); }
00214     //  return val;}
00215 
00216       // get pixels that correspond to shifting the window (i.e., take stride into account)
00217       inline T getShiftPixel(const int &i, const int &x, const int &y){
00218         return ref_image[i]->getPixel(static_cast<int>(m_pos_x + x * m_shift),
00219                                       static_cast<int>(m_pos_y + y * m_shift)); }
00220       //--------------------------------------------
00221 
00222 
00223       //-------------------------------------------
00224       // Set Pixel functions
00225       //
00226       inline void setPixel(const int &i, const int &ii, const T &val){
00227                         ref_image[i]->setPixel(m_ind+ii, val); }
00228       inline void setShiftPixel(const int &i, const int &x, const int &y, const T &val){
00229                         ref_image[i]->setPixel(static_cast<int>(m_pos_x + x * m_shift),
00230                                       static_cast<int>(m_pos_y + y * m_shift), val); }
00231       inline void setScalePixel(const int &i, const int &x, const int &y, const T &val){
00232                         ref_image[i]->setPixel(m_working_x + x * m_ref.m_scale_factor,
00233                                       m_working_y + y * m_ref.m_scale_factor, val); }
00234       // set pixels that correspond to shifting the window (i.e., take stride into account)
00235       //--------------------------------------------
00236       inline Square getSquare() const { return Square(m_ref.subwin_size_x, m_working_x, m_working_y, m_ref.m_scale_ind); }
00237     };
00238     friend class const_iterator;
00239 
00240     inline const_iterator begin(){ return const_iterator(*this, m_min_x, m_min_y); }
00241     inline const_iterator end(){
00242       // This is inefficient, but trying to figure it out correctly is very error-prone. Help!
00243       int working_y = m_min_y;
00244       float pos_y = static_cast<float>(working_y);
00245       while((working_y + subwin_size_y) < m_max_y){
00246         pos_y += shift;
00247         working_y = static_cast<int>(pos_y);
00248       }
00249       return const_iterator(*this, m_min_x, working_y);// - (m_scale_factor - 1));
00250     }
00251 };
00252 
00253 
00254 
00255 template<class T>
00256 class MPIImagePyramid{
00257   friend class MPIScaledImage<T>;
00258 //#if defined (__GNUC__) && (__GNUC__ > 2)
00259 // This used to work, no longer
00260 //  typedef typename MPIScaledImage<T>::const_iterator MPIScaledImage_iter;
00261 //    friend class MPIScaledImage_iter;
00262 //#else
00263   // Issues annoying warning on gcc 3.2, but I think its a bug in gcc
00264   friend class MPIScaledImage<T>::const_iterator; 
00265 
00266   // Public Functions and data
00267  public:
00268   MPIImagePyramid(RImage<T> &image, float scale_factor, int window_x, int window_y, float stride)
00269     : m_scale_factor(scale_factor),
00270     m_window_x(window_x), m_window_y(window_y), m_stride(stride){
00271     m_image.push_back(&image);
00272     SetScaleFactors();
00273     InitROI(); }
00274          
00275   MPIImagePyramid(vector< RImage<T>* > &image, float scale_factor, int window_x, int window_y, float stride)
00276     : m_image(image),  m_scale_factor(scale_factor),
00277     m_window_x(window_x), m_window_y(window_y), m_stride(stride){
00278     SetScaleFactors();
00279     InitROI(); }
00280 
00281   ~MPIImagePyramid(){ }
00282          
00283   class const_iterator{
00284   private:
00285     typedef const_iterator self;
00286     const MPIImagePyramid<T>& m_ref; 
00287     int m_pos;
00288   public:
00289     const_iterator(const MPIImagePyramid &ref, const int &pos) : m_ref(ref), m_pos(pos) {
00290       //;//cout << "scale iterator: m_pos="<<m_pos<<endl;
00291     }
00292     // Preincrement
00293     inline self& operator++ () { ++m_pos; return *this; }
00294     // Postincrement
00295     inline self operator++ (int) { self tmp = *this; ++m_pos; return tmp; }
00296     // Preincrement
00297     inline self& operator-- () { --m_pos; return *this; }
00298     // Postincrement
00299     inline self operator-- (int) { self tmp = *this; --m_pos; return tmp; }
00300     // Dereference
00301     MPIScaledImage<T> operator*() const{ return MPIScaledImage<T>(m_ref, m_pos);}
00302     // Notequals
00303     inline bool operator!=(const self& x) const { return m_pos != x.m_pos; }
00304     inline int getScale(float &sf){sf = m_ref.scale_factors[m_pos]; return m_pos; }
00305     inline float getScale(){return m_ref.scale_factors[m_pos];}
00306   };
00307 
00308   friend class const_iterator;
00309   inline const_iterator begin(){ // cout << "m_roi.m_min_scale: " << m_roi.m_min_scale << endl;
00310     return const_iterator(*this, m_roi.m_min_scale); }
00311   inline const_iterator end(){ // cout << "m_roi.m_max_scale: " << m_roi.m_max_scale << endl;
00312     return const_iterator(*this, m_roi.m_max_scale); }
00313          
00314  public:
00315   vector< float > scale_factors;
00316   float m_stride;
00317   inline float getMaxScale(){return scale_factors[scale_factors.size() - 1];}
00318   inline int getMaxScale(float &sf){sf = scale_factors[scale_factors.size() - 1]; return scale_factors.size() - 1;}
00319  private:
00320   // Private data
00321   vector< RImage<T>* > m_image;
00322   ROI m_roi;
00323   float m_scale_factor;
00324   int m_window_x, m_window_y;
00325   float temp;
00326 
00327   // Private Functions
00328   inline int imax(const int &x, const int &y) const { return(x > y ? x : y);}
00329   inline int imin(const int &x, const int &y) const { return(x < y ? x : y);}
00330   inline int scale(const int &x, const int &y) const { return(x * y);}
00331   void SetScaleFactorsFloat(){
00332       // Find maximum scales
00333       float max_y_scale_factor = static_cast<int>(m_image[0]->height / (m_window_y+1));
00334       float max_x_scale_factor = static_cast<int>(m_image[0]->width / (m_window_x+1));
00335       if (max_x_scale_factor && max_y_scale_factor){
00336           float scale_factor = 1.0f;
00337           while((scale_factor < max_y_scale_factor) && (scale_factor < max_x_scale_factor)){
00338               //cout << "creating scale_factor: " << scale_factor << endl; 
00339               scale_factors.push_back(scale_factor);
00340               // cout << "scale_factor*m_scale_factor*(float)m_window_x: "<< scale_factor*m_scale_factor*(float)m_window_x << endl;
00341               // cout << "(float)(static_cast<int>(scale_factor*m_scale_factor*(float)m_window_x + .99999f)): " << 
00342               //    (float)(static_cast<int>(scale_factor*m_scale_factor*(float)m_window_x + .99999f)) << endl;
00343               temp = (float)(static_cast<int>(scale_factor*m_scale_factor*(float)m_window_x + .99999f))/(float)m_window_x;
00344               scale_factor = temp;
00345           }
00346           // make the last scale such that the window gets as close as possible to the full image
00347           scale_factor = min(max_x_scale_factor,max_y_scale_factor);
00348           scale_factors.push_back(scale_factor);
00349       }
00350   }
00351   void SetScaleFactors(){
00352     // Find maximum scales
00353     int max_y_scale_factor = static_cast<int>(m_image[0]->height / (m_window_y+1));
00354     int max_x_scale_factor = static_cast<int>(m_image[0]->width / (m_window_x+1));
00355     if (max_x_scale_factor && max_y_scale_factor){
00356       int scale_factor = 1;
00357       while((scale_factor < max_y_scale_factor) && (scale_factor < max_x_scale_factor)){
00358         scale_factors.push_back(scale_factor);
00359         temp = imax (scale_factor+1, static_cast<int>(scale_factor*m_scale_factor));
00360         scale_factor = (int)temp;
00361       }
00362       // make the last scale such that the window gets as close as possible to the full image
00363       scale_factor = imin(max_x_scale_factor,max_y_scale_factor);
00364       scale_factors.push_back(scale_factor);
00365     }
00366   }
00367   void SetScaleFactorsNew(int start, int scale_size, float percent){
00368     //Find maximum scales
00369     int max_y_scale_factor = static_cast<int>(m_image[0]->height / (m_window_y+1));
00370     int max_x_scale_factor = static_cast<int>(m_image[0]->width / (m_window_x+1));
00371     if (max_x_scale_factor && max_y_scale_factor){
00372       int max_scale_factor = imin(max_x_scale_factor, max_y_scale_factor);
00373       int current_scale = 0;
00374       int previous_scale = start;
00375       int previous_point, current_point;
00376       scale_factors.push_back(start);
00377       while(current_scale < max_scale_factor){
00378         current_scale = previous_scale+1;
00379         previous_point = scale(previous_scale, scale_size) + (scale(previous_scale, scale_size) * percent);
00380         while(current_scale < max_scale_factor){
00381           current_point = scale(current_scale, scale_size) - (scale(current_scale, scale_size) * percent);
00382           if(current_point < previous_point)
00383             current_scale++;
00384           else{
00385             if(current_scale - 1 == previous_scale)
00386               current_scale++;//to make sure next scale != to previous scale
00387             scale_factors.push_back(current_scale - 1);
00388             previous_scale = current_scale - 1;
00389             break;
00390           }
00391         }
00392       }
00393       // make the last scale such that the window gets as close as possible to the full image
00394       // if gap between previous_scale and max_scale then also add prior scale
00395       current_point = scale(max_scale_factor, scale_size) - (scale(max_scale_factor, scale_size) * percent);
00396       if(current_point > previous_point && (max_scale_factor - 1) > previous_scale)
00397         scale_factors.push_back(max_scale_factor -1);
00398       scale_factors.push_back(max_scale_factor);
00399     }
00400   }
00401   void InitROIvectors(){
00402     m_roi.vmin_x.clear();
00403     m_roi.vmax_x.clear();
00404     m_roi.vmin_y.clear();
00405     m_roi.vmax_y.clear();
00406     for(unsigned int i=0; i < scale_factors.size(); ++i){
00407       m_roi.vmin_x.push_back(m_roi.m_min_x);
00408       m_roi.vmax_x.push_back(m_roi.m_max_x);
00409       m_roi.vmin_y.push_back(m_roi.m_min_y);
00410       m_roi.vmax_y.push_back(m_roi.m_max_y);
00411     }
00412   }
00413 
00414  public:
00415   void InitROI(){
00416     m_roi.m_min_x = 0;
00417     m_roi.m_min_y = 0;
00418     m_roi.m_min_scale = 0;
00419     m_roi.m_max_x = m_image[0]->width;
00420     m_roi.m_max_y = m_image[0]->height;
00421     m_roi.m_max_scale = scale_factors.size();
00422     m_roi.m_limit_scale = scale_factors.size();
00423     InitROIvectors();
00424   }
00425   ROI SetROI(ROI &roi){
00426     // set ROI to boundaries of image and scales
00427           //std::cout << "MPIImage::SetROI: roi = " << roi << endl;
00428     m_roi = roi;
00429     if(m_roi.m_min_x < 0) m_roi.m_min_x = 0;
00430     if(m_roi.m_max_x > m_image[0]->width) m_roi.m_max_x = m_image[0]->width;
00431     if(m_roi.m_min_y < 0) m_roi.m_min_y = 0;
00432     if(m_roi.m_max_y > m_image[0]->height) m_roi.m_max_y = m_image[0]->height;
00433     if(m_roi.m_min_scale < 0) m_roi.m_min_scale = 0;
00434     if(m_roi.m_max_scale > (int)scale_factors.size()) m_roi.m_max_scale = scale_factors.size();
00435     // if vector parts are empty, initialize them to full image pyramid
00436     if(!m_roi.vmin_x.size() && !m_roi.vmax_x.size() && !m_roi.vmin_y.size() && !m_roi.vmax_y.size()){
00437       InitROIvectors();
00438     }
00439     // if they are not empty but different from correct size, reinitialize them
00440     else {
00441       if((m_roi.vmin_x.size() != scale_factors.size()) || 
00442                                 (m_roi.vmax_x.size() != scale_factors.size()) || 
00443                                 (m_roi.vmin_y.size() != scale_factors.size()) || 
00444                                 (m_roi.vmax_y.size() != scale_factors.size()) ){
00445                                 std::cerr << "MPIImagePyramid::SetROI():  Received inconsistent vector part of ROI! Resetting ROI vectors" << endl;
00446                                 InitROIvectors();
00447       }
00448       // Ok, suppose it has a valid vector part, then
00449       // make sure no vector parts go outside of image boundary
00450       else{
00451                                 for(unsigned int i=0; i < scale_factors.size(); ++i){
00452                                         if(m_roi.vmin_x[i] < 0) m_roi.vmin_x[i] = 0;
00453                                         if(m_roi.vmax_x[i] > m_image[0]->width) m_roi.vmax_x[i] = m_image[0]->width;
00454                                         if(m_roi.vmin_y[i] < 0) m_roi.vmin_y[i] = 0;
00455                                         if(m_roi.vmax_y[i] > m_image[0]->height) m_roi.vmax_y[i] = m_image[0]->height;
00456                                 }
00457       }
00458       // Make sure the ROI holds correct values for the absolute min and max
00459       for(unsigned int i=0; i < scale_factors.size(); ++i){
00460                                 if(m_roi.m_min_x > m_roi.vmin_x[i]) m_roi.m_min_x = m_roi.vmin_x[i];
00461                                 if(m_roi.m_max_x < m_roi.vmax_x[i]) m_roi.m_max_x = m_roi.vmax_x[i];
00462                                 if(m_roi.m_min_y > m_roi.vmin_y[i]) m_roi.m_min_y = m_roi.vmin_y[i];
00463                                 if(m_roi.m_max_y < m_roi.vmax_y[i]) m_roi.m_max_y = m_roi.vmax_y[i];
00464       }
00465     }
00466     return m_roi;
00467   }
00468   ROI getROI() const { return m_roi; }
00469   int getClosestScale(float input_scale_factor){
00470     // if scale_factors were a map, could use stl algorithms, but its small so whatever
00471     for(int i = 1; i<scale_factors.size(); ++i)
00472       if(static_cast<float>(scale_factors[i])>input_scale_factor)
00473         return i-1;
00474     return scale_factors.size()-1;
00475   }
00476 };
00477 
00478 
00479 #endif
00480 
00481 
00482 /*
00483 * 
00484 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00485 *
00486 *    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00487 *    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
00488 *    3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
00489 * 
00490 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00491 * 
00492 */
00493 

Generated on Mon Nov 8 17:07:44 2004 for MPT by  doxygen 1.3.9.1