Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

ImagePyramid.h

Go to the documentation of this file.
00001 #ifndef ImagePyramid_h
00002 #define ImagePyramid_h
00003 
00004 #include <vector>
00005 #include "Core/Array/Arrays.h"
00006 #include "Core/Array/GaussDerivative.h"
00007 #include "Core/Array/Scale.h"
00008 
00009 #include "Core/Tracking/BasicTypes.h"
00010 
00011 namespace Impala
00012 {
00013 namespace Core
00014 {
00015 namespace Tracking
00016 {
00017 
00018 
00019 class ImagePyramid
00020 {
00021 public:
00022     ImagePyramid(Array::Array2dVec3Real64* base) // the base image is stored, but not owned
00023     {
00024         // the base image is stored, but not owned
00025         mLevels.reserve(8);
00026         mLevels.push_back(base);
00027         mScratch = new Array::Array2dVec3Real64(base->CW(), base->CH(), base->BW(), base->BH(), 0);
00028             Array::Array2dScalarReal64* kernel = Array::MakeGaussian1d(1.0, 0, 1.0, 3);
00029         mGaussKernel = new Array::Array2dVec3Real64(kernel->CW(), kernel->CH(), kernel->BW(), kernel->BH(), 0);
00030         Array::Pattern::PatSet(mGaussKernel,kernel,0,0,kernel->CW(),kernel->CH(),0,0);
00031         delete kernel;
00032 
00033         int w,h;
00034         w = base->CW();
00035         h = base->CH();
00036         mMaxTop = 1;
00037         while( w>2 && h>2 && w*h>100)
00038         {
00039             w/=2;
00040             h/=2;
00041             mMaxTop++;
00042         }
00043     }
00044 
00045     virtual ~ImagePyramid()
00046     {
00047         //delete all levels except the bottom one which is not owned...
00048         while(mLevels.size()>1)
00049         {
00050             delete mLevels.back();
00051             mLevels.pop_back();
00052         }
00053         delete mGaussKernel;
00054         delete mScratch;
00055     }
00056 
00057     void ComputeLevels(int top)
00058     {
00059         if(top > mMaxTop)
00060             top = mMaxTop;
00061         if(top == 0)
00062             top = mMaxTop;
00063         while(top>Levels())
00064             ComputeNextLevel();
00065     }
00066 
00067     Array::Array2dVec3Real64* GetLevel(int level)
00068     {
00069         if(level>=Levels())
00070             throw std::invalid_argument("[ImagePyramid::GetLevel] invalid level");
00071         return mLevels[level];
00072     }
00073 
00074     void PropagateBaseChanges()
00075     {
00076         int i;
00077         for(i=0 ; i<Levels()-1 ; i++)
00078         {
00079             ScaleAndCopy(i);
00080         }
00081     }
00082 
00083     int Levels()
00084     {
00085         return mLevels.size();
00086     }
00087 
00088     Point GetSize(int level)
00089     {
00090         Array::Array2dVec3Real64* img;
00091         img = GetLevel(level);
00092         return Point(img->CW(), img->CH());
00093     }
00094 
00095 private:
00096     std::vector<Array::Array2dVec3Real64*> mLevels;
00097     Array::Array2dVec3Real64* mScratch;
00098     Array::Array2dVec3Real64* mGaussKernel;
00099     int mMaxTop; //the level at which you can't sub sample any more
00100 
00101     void ComputeNextLevel()
00102     {
00103         int w,h;
00104         w = mLevels[Levels()-1]->CW() / 2;
00105         h = mLevels[Levels()-1]->CH() / 2;
00106         int bw,bh;
00107         bw = mLevels[Levels()-1]->BW() / 2;
00108         bh = mLevels[Levels()-1]->BH() / 2;
00109         mLevels.push_back(new Array::Array2dVec3Real64(w,h,bw,bh));
00110         ScaleAndCopy(Levels()-2);
00111     }
00112 
00113     void ScaleAndCopy(int srcLevel)
00114     {
00115         int w,h;
00116         w = mLevels[srcLevel]->CW();
00117         h = mLevels[srcLevel]->CH();
00118         FakeResizeScratch(w,h);
00119 
00120         //warning: very very dirty tricks...
00121         //I'm incrementing the data pointer of the arrays so the gause filter 
00122         //processes the red,green and bleu planes appart
00123 
00124         //red
00125         Array::GaussDerivative(mScratch, mLevels[srcLevel], 1.0, 0, 0, 2.0);
00126 
00127         //green
00128         mScratch->mData += 1;
00129         mLevels[srcLevel]->mData += 1;
00130         Array::GaussDerivative<Array::Array2dVec3Real64,Array::Array2dVec3Real64>
00131             (mScratch, mLevels[srcLevel], 1.0, 0, 0, 2.0);
00132         
00133         //blue
00134         mScratch->mData += 1;
00135         mLevels[srcLevel]->mData += 1;
00136         Array::GaussDerivative(mScratch, mLevels[srcLevel], 1.0, 0, 0, 2.0);
00137         
00138         //restore pointer
00139         mScratch->mData -= 2;
00140         mLevels[srcLevel]->mData -= 2;
00141 
00142         Array::Scale(mLevels[srcLevel+1], mScratch, 0.5, 0.5, Geometry::NEAREST);
00143     }
00144 
00145     void FakeResizeScratch(int w, int h)
00146     {
00147         if(w>mLevels[0]->CW() || h>mLevels[0]->CH())
00148             throw std::logic_error("[ImagePyramid::FakeResizeScratch] too big");
00149         mScratch->mCW = w;
00150         mScratch->mCH = h;
00151     }
00152 
00153     //disable copying
00154     ImagePyramid(const ImagePyramid& copy);// {}
00155     ImagePyramid& operator=(const ImagePyramid& copy);// {return *this;}
00156 };
00157 
00158 } // namespace Tracking
00159 } // namespace Core
00160 } // namespace Impala
00161 
00162 #endif ImagePyramid_h

Generated on Fri Mar 19 09:31:22 2010 for ImpalaSrc by  doxygen 1.5.1