Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
qdRotCensus.hpp
00001 #ifndef QD_ROTCENSUS_HPP
00002 #define QD_ROTCENSUS_HPP
00003 
00004 #include <iostream>
00005 #include <fstream>
00006 #include <sstream>
00007 #include <string>
00008 #include <vector>
00009 #include <bitset>
00010 
00011 #include <math.h>
00012 
00013 #include "kernel/jafarMacro.hpp"
00014 #include "jmath/jblas.hpp"
00015 #include "image/Image.hpp"
00016 #include "quasidense/qdImgCensus.hpp"
00017 #include "boost/timer.hpp"
00018 
00019 namespace jafar {
00020 
00021   namespace quasidense {
00022 
00031     struct rotDataCensus {
00032       
00034       //boost::numeric::ublas::matrix<bitset80> censusData;
00035       bitset80 *censusData;
00036 
00038       unsigned int width;
00039       unsigned int height;
00040       unsigned int widthstep;
00041       
00043       boost::numeric::ublas::matrix<bool> vMask;      
00044       
00045     private :
00046 
00047       unsigned int rExclu;
00048 
00049       unsigned int estimExcluRadius (double angle);
00050       
00051       void censusShiftsGenerator (long int *tab, unsigned int tabSize,
00052           unsigned int indCircQuadrant, unsigned int indRotAngle);
00053             
00054       
00055     public :
00056 
00061       rotDataCensus (jafar::image::Image &img, double angle, double cmThreshold=0.01) :
00062   width(img.width()),
00063   height(img.height()),
00064   widthstep(img.step()),
00065   vMask(img.height(),img.width())
00066       {
00067   JFR_PRECOND(angle>-M_PI && angle<=M_PI, "quadisense::rotDataCensus::rotDataCensus : Constructor waits for angle in ]-PI,PI]");
00068   JFR_PRECOND(img.depth() == IPL_DEPTH_8U , "quasidense::rotDataCensus::rotDataCensus : Constructor don't tolerate float images");
00069   
00070   unsigned int pos, posIma;
00071   unsigned int rExclu;
00072   unsigned int nbrow = img.height(), nbcol = img.width();;
00073   double vmax1, vmax2, cstnormal;
00074   double *diffv, *diffh;
00075 
00076   diffv = new double [nbrow*nbcol];
00077   diffh = new double [nbrow*nbcol];
00078     
00079 //  width = img.width();
00080 //  height = img.height();
00081 //  widthstep = img.step(); 
00082   censusData = new bitset80[nbrow*widthstep];
00083 
00084   unsigned char *rawData = reinterpret_cast<unsigned char*>(img.data());
00085   unsigned char current_gl;
00086   cstnormal = 1.0/255.0;
00087   
00088   boost::timer chrono;
00089 
00090   // ******************************************************************
00091   //
00092   //                       PART 0 : ANGLE DECOMPOSITION
00093   //  
00094   // ******************************************************************
00095   
00096   if (angle<-13*M_PI/180)
00097     angle += 2.0*M_PI;
00098   
00099   unsigned int configBase, configLUT;
00100   double angleRed;
00101 
00102   if (angle<77*M_PI/180)
00103     configBase = 0;
00104   else if (angle<167*M_PI/180)
00105     configBase = 1;
00106   else if (angle<257*M_PI/180)
00107     configBase = 2;
00108   else 
00109     configBase = 3;
00110     
00111   angleRed = angle - configBase*M_PI_2;
00112   rExclu = 3;
00113 
00114   if (angleRed<13*M_PI/180)
00115     {
00116       rExclu = 2;
00117       configLUT = 0;
00118     }
00119   else if (angleRed<18*M_PI/180)
00120     {
00121       rExclu = 2;
00122       configLUT = 1;
00123     }
00124   else if (angleRed<25*M_PI/180)
00125     configLUT = 2;
00126   else if (angleRed<35*M_PI/180)
00127     configLUT = 3;
00128   else if (angleRed<40*M_PI/180)
00129     configLUT = 4;  
00130   else if (angleRed<50*M_PI/180)
00131     configLUT = 5;  
00132   else if (angleRed<55*M_PI/180)
00133     configLUT = 6;  
00134   else if (angleRed<66*M_PI/180)
00135     configLUT = 7;  
00136   else if (angleRed<73*M_PI/180)
00137     configLUT = 8;
00138   else if (angleRed<77*M_PI/180)
00139     {
00140       rExclu = 2;
00141       configLUT = 9;
00142     }          
00143   
00144   // ******************************************************************
00145   //
00146   //                       PART I : MASK GENERATION
00147   //  
00148   // ******************************************************************
00149   
00150 
00151         // ******************************************************************
00152   //  vMask initialization and optimized diffmap computation 
00153   //  4 steps : upper left corner / first row / first line / the rest
00154   //
00155   
00156   vMask(0,0) = false;
00157   diffv[0] = 0.0;
00158   diffh[0] = 0.0;
00159   
00160   pos = nbcol;
00161   for (unsigned int cptr=1; cptr<nbrow ; ++cptr,pos+=nbcol)
00162     {  
00163       vMask(cptr,0) = false;
00164       diffv[pos] = cstnormal*fabs((double)rawData[cptr*widthstep]-(double)rawData[(cptr-1)*widthstep]);
00165       diffh[pos] = 0.0;
00166     }
00167   
00168   for (unsigned int cptc=1; cptc<nbcol;cptc++)
00169     {  
00170       vMask(0,cptc) = false;
00171       diffv[cptc] = 0.0;
00172       diffh[cptc] = cstnormal*fabs((double)rawData[cptc]-(double)rawData[cptc-1]);
00173     }
00174   
00175   pos = nbcol;
00176   for (unsigned int cptr = 1; cptr<nbrow; ++cptr)   
00177     {
00178       pos++;
00179       posIma = cptr*widthstep;
00180       for (unsigned int cptc = 1; cptc<nbcol; ++cptc, ++pos)
00181         {
00182     vMask(cptr,cptc) = false;
00183     diffv[pos] = cstnormal*fabs((double)rawData[posIma+cptc]-(double)rawData[posIma+cptc-widthstep]);
00184     diffh[pos] = cstnormal*fabs((double)rawData[posIma+cptc]-(double)rawData[posIma+cptc-1]);
00185         }
00186     } 
00187   
00188   // *******************************************
00189         //  Mask Generation
00190   //  We exclude points too near of image sides
00191   //  In order to taking into account rotated 
00192   //  patch, exlcusion radius is doubled
00193   //
00194 
00195   for (unsigned int cptr=2*rExclu;cptr<(nbrow-2*rExclu);++cptr)
00196     {
00197       pos = cptr*nbcol+2*rExclu;
00198       for (unsigned int cptc=2*rExclu;cptc<(nbcol-2*rExclu);++pos,++cptc)
00199         {
00200     vmax1 = (diffv[pos]<diffh[pos])?diffh[pos]:diffv[pos];
00201     vmax2 = (diffv[pos+nbcol]<diffh[pos+1])?diffh[pos+1]:diffv[pos+nbcol];
00202     if ((vmax1>=cmThreshold)||(vmax2>=cmThreshold))
00203       vMask(cptr,cptc) = true;        
00204         }  
00205     }       
00206 
00207   // ******************************************************************
00208   //
00209   //                 PART II : CENSUS TRANSFORMATION
00210   //  
00211   // ******************************************************************
00212 
00213     
00214   // Variables for rank Transform
00215   unsigned int N, rCensus = 2;
00216   unsigned int testNumber;
00217   long int *shiftsTabular;
00218 
00219   N = (rCensus*2+1);
00220   testNumber = (N*N-1)/2;
00221 
00222   // Memory Allocation
00223   shiftsTabular = new long int [testNumber];  
00224   censusShiftsGenerator (shiftsTabular, testNumber, configBase, configLUT);
00225   
00226   //
00227   // Census Transform
00228   //
00229   // Process is optimized by using the symetry of the process
00230   // (comparison of pixels A and B permits to update bitstream
00231   // corresponding to A and B in the same time). To avoid
00232   // border effects, pixels located in a 2rExclu-width band
00233   // are marked as unused in vmask.
00234   //   
00235   
00236   unsigned int current_pos, tested_pos, irow, icol;
00237   
00238   for (pos=0;pos<widthstep*nbrow;++pos)
00239     censusData[pos].reset();
00240   
00241   for (irow = rExclu; irow<(nbrow-rExclu) ; ++irow)
00242     {
00243       pos = irow*widthstep;
00244       for ( icol = rExclu; icol<(nbcol-rExclu) ; ++icol)
00245         {
00246     current_pos = pos+icol;
00247     current_gl = rawData[current_pos];
00248 
00249     for (unsigned int cpt_test=0;cpt_test<testNumber;++cpt_test)
00250       {
00251         tested_pos = current_pos+shiftsTabular[cpt_test];
00252         if (current_gl!=rawData[tested_pos])
00253           if (current_gl<rawData[tested_pos])
00254       censusData[current_pos].set(cpt_test,1);
00255           else      
00256       censusData[tested_pos].set(N*N-1-cpt_test,1);
00257       }
00258         }
00259     }
00260 
00261   // 
00262   std::cout << " Census Transform accomplished in " << chrono.elapsed() << "sec." << std::endl;
00263       
00264   // ******************************************************************
00265   // 
00266   //                 PART III : SOME CLEANING
00267   //
00268   // ******************************************************************
00269 
00270   delete[] diffv;
00271   delete[] diffh;
00272   delete[] shiftsTabular; 
00273 
00274       }; // end of constructor
00275 
00276       ~rotDataCensus(void)
00277       {
00278   delete[] censusData;
00279       };
00280       
00281     }; // end of struct rotDataCensus
00282     
00283 
00284         
00293     class rotPairCensus {
00294       
00295       rotDataCensus img1;
00296       
00297       rotDataCensus img2;
00298             
00299     public :
00303       rotPairCensus (jafar::image::Image &img1_, jafar::image::Image &img2_, double angle_=0.0, double cmThreshold_=0.01) : 
00304   img1(img1_, 0.0, cmThreshold_),
00305   img2(img2_, angle_, cmThreshold_)
00306       {  };      
00307       
00311       bool isPointValidinIma1 (int u, int v);
00312       bool isPointValidinIma2 (int u, int v);
00313 
00317       bool isMatchValid (int u1, int v1, int u2, int v2);
00318       bool isMatchValid (int u1, int v1, int u2, int v2, unsigned int radius);
00319       
00323       double matchEval (int u1, int v1, int u2, int v2);
00324       double matchEval (int u1, int v1, int u2, int v2, unsigned int radius);
00325 
00329       void confirmedMatch (int u1, int v1, int u2, int v2)
00330       {
00331   img1.vMask(v1,u1) = false;
00332   img2.vMask(v2,u2) = false;
00333       };
00334       
00335     }; // end of class imgPairRank
00336           
00337              
00338   } // end namespace quasidense
00339 
00340 }// end namespace jafar
00341 
00342 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:26 for Jafar by doxygen 1.7.6.1
LAAS-CNRS