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

Generated on Thu Jan 13 09:04:40 2011 for ImpalaSrc by  doxygen 1.5.1