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

DoG.h

Go to the documentation of this file.
00001 
00002 #ifndef Impala_Core_Array_DoG_h
00003 #define Impala_Core_Array_DoG_h
00004 
00005 #include "Core/Keypoint/Detector.h"
00006 #include "Core/Array/Octaves.h"
00007 
00008 
00009 namespace Impala{
00010 namespace Core{
00011 namespace KeyPoint{
00012 
00013 //using namespace Impala::Core::Array;
00014 
00015 class DoG:public Detector{
00016     
00017 private:
00018     ILOG_VAR_DEC;
00019     Array::Octaves* mOctaves;
00020     Array2dScalarReal64** mDoG;
00021     Array2dScalarReal64** mLevelExtrema;
00022     Array2dScalarReal64** mOctaveExtrema;
00023 
00024     int mOctaveCnt;
00025     int mLevelCnt;
00026     int mScaleCnt;
00027     int mCancelled;
00028 
00029 public:
00030     DoG(Array::Octaves* o)
00031     {
00032         mOctaves=o;
00033         mOctaveCnt=o->GetOctaveCount();
00034         mLevelCnt=o->GetLevelCount();
00035         mScaleCnt=o->GetScaleCount();
00036         Init();
00037         
00038     }
00039     ~DoG(){
00040         for(int i=0; i<mOctaveCnt*(mScaleCnt-1);i++)
00041         {
00042             delete mDoG[i];
00043         }
00044         delete [] mDoG;
00045         for(int i=0; i<mOctaveCnt*mLevelCnt;i++)
00046         {
00047             delete mLevelExtrema[i];
00048         }
00049         delete [] mLevelExtrema;
00050         for(int i=0; i<mOctaveCnt;i++)
00051         {
00052             delete mOctaveExtrema[i];
00053         }
00054         delete [] mOctaveExtrema;
00055     }
00056     void Init(){
00057         mCancelled=0;
00058 
00060         //mDoG holds the difference of gaussians between successive levels
00061         mDoG = new Array2dScalarReal64*[mOctaveCnt*(mScaleCnt-1)];
00062         for(int i=0;i<mOctaveCnt*(mScaleCnt-1);i++)
00063             mDoG[i]=0;
00064         
00065 
00067         //mLevelExtrema holds the max/min of successive levels(mScaleCnt-3)
00068         //mGradMag holds the gradient magnitude of different levels
00069         //mGradAng holds the gradient orientation of different levels
00070         mLevelExtrema= new Array2dScalarReal64*[mOctaveCnt*mLevelCnt];
00071 
00072         for(int i=0;i<mOctaveCnt*mLevelCnt;i++){
00073             mLevelExtrema[i] = 0;
00074         }
00075         
00076         mOctaveExtrema = new  Array2dScalarReal64*[mOctaveCnt];
00077         for(int i=0;i<mOctaveCnt;i++)
00078             mOctaveExtrema[i]=0;
00080         mKeyPoints=new KeyPointTableType(0);
00081     
00082     }
00083     KeyPointTableType* GetKeyPoints(){
00084         return mKeyPoints;
00085     }
00086     
00087     Array2dScalarReal64* GetDoG(int o,int l)
00088     {
00089         if(l>mScaleCnt-2){
00090             ILOG_INFO("Clipping, only "<<mScaleCnt-1<< " DoG at each octave!");
00091             l=mScaleCnt-2;
00092         }
00093         return mDoG[o*(mScaleCnt-1)+l];
00094     }
00095     
00096     Array2dScalarReal64* GetLevelExtrema(int o,int l)
00097     {
00098         if(l>mLevelCnt-1){
00099             ILOG_INFO("Clipping, only "<<mLevelCnt<< " extrema at each octave!");
00100             l=mLevelCnt-1;
00101         }
00102         return mLevelExtrema[o*mLevelCnt+l];
00103     }
00104     Array2dScalarReal64* GetOctaveExtrema(int o)
00105     {
00106         if(o>mOctaveCnt){
00107             ILOG_INFO("Clipping, only "<<mOctaveCnt<< " octaves!");
00108             o=mOctaveCnt;
00109         }
00110         return mOctaveExtrema[o];
00111     }
00112 
00113     void FindKeyPoints()
00114     {
00115         CalculateDoG();
00116         //CalculateDoGExtrema();
00117         CalculateOctaveExtrema();
00118         RejectLowContrast();
00119         RejectEdgeResponse();
00120         AcquireKeypoints();
00121         //Filter points
00122         LocalizeKeypoints();
00123     
00124     
00125     }
00126     void CalculateDoG(){
00127         ILOG_INFO("Calculating DoG ...");
00128         for(int o=0;o<mOctaveCnt;o++){
00129             for(int l=0;l<mScaleCnt-1;l++){
00130                 Sub(mDoG[o*(mScaleCnt-1)+l],
00131                     mOctaves->GetOctave(o,l),
00132                     mOctaves->GetOctave(o,l+1));
00133             }
00134         }
00135     }
00136 
00137     void CalculateOctaveExtrema()
00138     {
00139         ILOG_INFO("Calculating Octave Extrema ...");
00140         for(int o=0;o<mOctaveCnt;o++)
00141         {
00142             mOctaveExtrema[o] = 0;
00143             for(int l=0;l<mLevelCnt;l++)
00144             {
00145                 
00146                 mLevelExtrema[o*mLevelCnt+l]=
00147                     GetLSSE(mDoG[o*(mScaleCnt-1)+l],
00148                             mDoG[o*(mScaleCnt-1)+l+1],
00149                             mDoG[o*(mScaleCnt-1)+l+2]);
00150                 if(l==0)
00151                     Set(mOctaveExtrema[o],mLevelExtrema[o*mLevelCnt+l]);
00152                 else
00153                     Add(mOctaveExtrema[o],mOctaveExtrema[o],
00154                             mLevelExtrema[o*mLevelCnt+l]);
00155             }
00156         }
00157     }
00158     Array2dScalarReal64* GetLSSE(Array2dScalarReal64* u,
00159                 Array2dScalarReal64* c,
00160                 Array2dScalarReal64* l)
00161     {
00162         Array2dScalarReal64* res = 0 ;
00163         Array2dScalarReal64* arrays[3];
00164 
00165         arrays[0]=u;
00166         arrays[1]=c;
00167         arrays[2]=l;
00168 
00169         Set(res,c);
00170         SetVal(res,0);
00171         /*
00172         ILOG_DEBUG("LSSE sizes: "<<l->CH()<<"x"<<l->CW()
00173                                 <<" | "<<c->CH()<<"x"<<c->CW()
00174                                 <<" | "<<u->CH()<<"x"<<u->CW());
00175                                 */
00176         Real64  max;
00177         int i,j,m,n,a;
00178         bool is_max;
00179         for(i=1;i<c->CW()-1;i++){
00180             for(j=1;j<c->CH()-1;j++)
00181             {
00182                 max = arrays[1]->Value(i,j);
00183                 is_max = true;
00184                 for(a=0;a<3;a++)
00185                 {
00186                     for(m=-1;m<2;m++)
00187                     {
00188                         for(n=-1;n<2;n++)
00189                         {
00190                             if(max <= arrays[a]->Value(i+m,j+n))
00191                             {
00192                                 if((a==1)&&(m==0)&&(n==0))
00193                                     continue;
00194                                 //ILOG_DEBUG(a<<"\t"<<m<<"\t"<<n);
00195                                 is_max=false;
00196                                 break;  
00197                             }
00198                         }
00199                         if(!is_max)
00200                             break;
00201                     }
00202                     if(!is_max)
00203                         break;
00204                 }
00205                 if(is_max)
00206                     res->SetValue(1,i,j);
00207             }
00208         }
00209        return res;
00210 
00211     }
00212 
00213     void RejectLowContrast()
00214     {
00215         ILOG_WARN("Reject low contrast not implemented yet!");
00216     }
00217     void RejectEdgeResponse()
00218     {
00219         ILOG_WARN("Reject edge response not implemented!");
00220         return;    
00221     }
00222     void AcquireKeypoints()
00223     {
00224         ILOG_INFO("Acquiring Keypoints");
00225         for(int o=0;o<mOctaveCnt;o++)
00226         {
00227             for(int l=0;l<mLevelCnt;l++)
00228             {
00229                 Array2dScalarReal64* arr = mLevelExtrema[o*mLevelCnt+l];
00230                 for(int i=0;i<arr->CW();i++){
00231                     for(int j=0;j<arr->CH();j++)
00232                     {
00233                         if(arr->Value(i,j)!=0)
00234                         {
00235                             mKeyPoints->Add(mOctaves->GetSigma(o,l+2),i,j,o,l,0);
00236                         }
00237                     }
00238                 }
00239             }
00240         }
00241         ILOG_INFO("Total "<<mKeyPoints->Size()<<" keypoints!");
00242 
00243     }
00244 
00245     void LocalizeKeypoints()
00246     {   
00247         int k = 0 ;
00248         int OrigSize=mKeyPoints->Size();
00249         ILOG_INFO("Localizing "<<OrigSize<<" Keypoints");
00250         int new_i;
00251         int new_j;
00252         int last=0;
00253         int count=0;
00254         mCancelled=0;
00255         double H[4];
00256         double G[2];
00257         double S[2];
00258         Real64 Dx=0;
00259         Array2dScalarReal64* Octave;
00261         //form the Hessian matrix &Gradient vector around each point, 
00262         //and find the shift from 
00263         // -inv((Hessian(A))*Grad(A)) : evaluated at the keypoint
00264         while(k<OrigSize)
00265         {
00266             Real64 sigma=mKeyPoints->Get1(k);
00267             int i = mKeyPoints->Get2(k);
00268             int j = mKeyPoints->Get3(k);
00269             int o = mKeyPoints->Get4(k);
00270             int l = mKeyPoints->Get5(k);
00271 
00272 
00273             Octave=mOctaves->GetOctave(o,l);
00274 
00275             int Width=mOctaves->GetOctave(o,l)->CW();
00276             int Height=mOctaves->GetOctave(o,l)->CH();
00277 
00278 
00279             //dd stands for derivative distance..something I just made up now-)
00280             int dd;
00281 
00283             // If resampling is enabled, we have already reduced 
00284             // the scale by two at every octave(doubling of sigma). 
00285             // Therefore the derivative is the immediate neighbors.
00286             //
00287             // Otherwise we have to jump as much as one sigma for a derivative,
00288             // since the images are not scaled down as well.
00289             if(mOctaves->IsResamplingEnabled())
00290                 dd=1;
00291             else
00292                 dd=sigma;
00293                 
00294             //ILOG_DEBUG("Using "<<dd<<" as der.distance @ ("<<o<<","<<l<<")");
00295             if((i+2*dd>=Width)||(j+2*dd>=Height)||(i-2*dd<0)||(j-2*dd<0))
00296             {
00297                 //ILOG_WARN("Should cancel the keypoint");
00298                 mCancelled++;
00299                 mKeyPoints->Set2(k,0);
00300                 mKeyPoints->Set3(k,0);
00301                 count=0;
00302                 k++;
00303                 last=k;
00304                 continue;
00305             }
00306                 
00307         
00308 
00309             //Second row of Hessian
00310             //this is the first derivative wrt. x
00311             //[ -1 0 1 ]
00312             G[0] = Octave->Value(i+dd,j) - Octave->Value(i-dd,j);
00313 
00314 
00315             //second derivative wrt. x
00316             //[ 1 0 -2 0 1 ]
00317             H[0]= -2*Octave->Value(i,j)  +
00318                     Octave->Value(i-2*dd,j) +
00319                     Octave->Value(i+2*dd,j) ;
00320             /* Second Derivative
00321             [ 1  0 -1]
00322             [ 0  0  0]
00323             [-1  0  1]*/
00324             //second derivative wrt. y
00325             H[1]=    Octave->Value(i-dd,j-dd) +
00326                      Octave->Value(i+dd,j+dd) -
00327                      Octave->Value(i-dd,j+dd) -
00328                      Octave->Value(i+dd,j-dd) ;
00329 
00330             //Third row of Hessian
00331             //this is the first derivative wrt. y
00332             G[1] = Octave->Value(i,j+dd) - Octave->Value(i,j-dd);
00333 
00334             //second derivative wrt. y
00335             //[ 1 0 -2 0 1 ]
00336             H[2]= -2*Octave->Value(i,j)  +
00337                     Octave->Value(i,j-2*dd) +
00338                     Octave->Value(i,j+2*dd) ;
00339 
00340             /* Second Derivative
00341             [ 1  0 -1]
00342             [ 0  0  0]
00343             [-1  0  1]*/
00344             //second derivative wrt. y
00345             H[3]=   Octave->Value(i-dd,j-dd) +  Octave->Value(i+dd,j+dd) -
00346                     Octave->Value(i-dd,j+dd) -  Octave->Value(i+dd,j-dd) ;
00347 
00348             Real64 div = H[0]*H[3]-H[1]*H[2];
00349             S[0]=(-H[3]*G[0]+H[1]*G[1])/div;
00350             S[1]=(H[2]*G[0]-H[0]*G[1])/div;
00351     
00352             Dx= Octave->Value(i,j)+.5*(S[0]*G[0]+S[1]+G[1]);
00353             if(Dx<.03){
00354                 //ILOG_WARN("Should cancel the keypoint");
00355                 mCancelled++;
00356                 mKeyPoints->Set2(k,0);
00357                 mKeyPoints->Set3(k,0);
00358                 count=0;
00359                 k++;
00360                 last=k;
00361                 continue;
00362             }
00363             //advance to the next keypoint
00364             if(!((S[0]> 0.5)||(S[1]> 0.5)||(S[0]<-.5)||(S[1]<-.5))){
00365                k++;
00366                last=k;
00367                count=0;
00368             }else{
00369                 new_i=i+S[0];
00370                 new_j=j+S[1];
00371                 if((new_i>0)&&(new_i<Width)){
00372                     mKeyPoints->Set2(k,new_i);
00373                 }else{
00374                     //ILOG_INFO("Keypoint "<<k<<" : Location out of border");
00375                     count=0;
00376                     k++;
00377                     last=k;
00378                     continue;
00379                 }
00380 
00381 
00382                 if((new_j>0)&&(new_j<Height)){
00383                     mKeyPoints->Set3(k,new_j);
00384                 }else{
00385                     //ILOG_INFO("Keypoint "<<k<<" : Location out of border");
00386                     count=0;
00387                     k++;
00388                     last=k;
00389                     continue;
00390                 }
00391 
00392                 if(last==k)
00393                     count++;
00394                 /*
00395                 ILOG_DEBUG("Keypoint "<<k<<" : Location shifted!("<<count<<")");
00396                 ILOG_DEBUG("Estimated Shift : "<<S[0]<<"x"<<S[1]);
00397                 */
00398 
00399                 if(count>10){
00400                     k++;
00401                     last=k;
00402                     count=0;
00403                 }
00404             }
00405 
00406         }
00407         ILOG_INFO("Cancel count:"<<mCancelled<<"/"<<OrigSize);
00408 
00409     }
00410 
00411     
00412 
00413 
00414 };
00415 ILOG_VAR_INIT(DoG, Impala.Core.Array);
00416 
00417 }}}
00418 #endif

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