Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
qdOmniCensus.hpp
00001 #ifndef QD_OMNICENSUS_HPP
00002 #define QD_OMNICENSUS_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/qdOmniMask.hpp"
00017 #include "quasidense/qdImgCensus.hpp"
00018 
00019 #include "boost/timer.hpp"
00020 
00021 namespace jafar {
00022 
00023   namespace quasidense {
00024 
00025     
00034     struct omniDataCensus {
00035       
00037       jafar::quasidense::bitset80 *censusData;
00038 
00040       unsigned int width;
00041 
00043       unsigned int height;
00044 
00046       unsigned int widthstep;
00047       
00049       boost::numeric::ublas::matrix<bool> vMask;      
00050       
00061       omniDataCensus (jafar::image::Image &img , jafar::camera::CameraBarreto &omniCam,
00062           jafar::quasidense::omniMask &geomMask, double oasCensus=0.0079, 
00063           unsigned int rCensus=2, double hrdThreshold=0.01) :
00064   width(img.width()),
00065   height(img.height()),
00066   widthstep(img.step()),
00067   vMask(img.height(),img.width())
00068       {
00069   JFR_PRECOND(img.depth() == IPL_DEPTH_8U , "quasidense::omniDataCensus::omniDataCensus : Constructor don't tolerate float images");
00070   JFR_PRECOND( rCensus<=4, "quasidense::ingDataCensus::imgDataCensus : 4 is the maximal radius tolarated by Census Transform");
00071   
00072   boost::timer chrono;
00073 
00074   unsigned int pos, posIma;
00075   unsigned int nbrow = img.height(), nbcol = img.width();
00076   double vmax1, vmax2, vmaxS1, vmaxS2, cstnormal;
00077   double *diffu, *diffl, *difful, *diffur;
00078 
00079   diffu = new double [nbrow*nbcol];
00080   diffl = new double [nbrow*nbcol];
00081   difful = new double [nbrow*nbcol];
00082   diffur = new double [nbrow*nbcol];
00083     
00084   censusData = new bitset80[nbrow*widthstep];
00085 
00086   unsigned char *rawData = reinterpret_cast<unsigned char*>(img.data());
00087   cstnormal = 1.0/255.0;
00088   
00089 
00090   // ******************************************************************
00091   //
00092   //                       PART I : MASK GENERATION
00093   //  
00094   // ******************************************************************
00095 
00096   // ******************************************************************
00097 
00098         // ******************************************************************
00099   //  vMask initialization and optimized diffmap computation 
00100   //  5 steps : first row/last row/first column/last column/the rest
00101   //  
00102   
00103   chrono.restart();
00104   
00105   // First row
00106   for (unsigned int cptc=0, cptr=0; cptc<nbcol; ++cptc)
00107     {
00108       vMask(cptr,cptc) = false;
00109       diffu[cptc] = 0.0;
00110       diffl[cptc] = 0.0;
00111       difful[cptc] = 0.0;
00112       diffur[cptc] = 0.0;
00113     }
00114 
00115   // Last row
00116   pos = nbcol*(nbrow-1);
00117   posIma = (nbrow-1)*widthstep;
00118   for (unsigned int cptc=1, cptr=nbrow-1; cptc<=(nbcol-2); ++cptc)
00119     {
00120       vMask(cptr,cptc) = false;
00121 
00122       diffl[pos+cptc] = 0.0;
00123       diffu[pos+cptc] = cstnormal*fabs( (double)rawData[posIma+cptc] - 
00124                 (double)rawData[posIma-widthstep+cptc] );
00125 
00126       difful[pos+cptc] = cstnormal*fabs( (double)rawData[posIma+cptc] - 
00127                  (double)rawData[posIma-widthstep+cptc-1] );     
00128 
00129       diffur[pos+cptc] = cstnormal*fabs( (double)rawData[posIma+cptc] - 
00130                  (double)rawData[posIma-widthstep+cptc+1] );
00131     }
00132 
00133   // First Column
00134   for (unsigned int cptc=0, cptr=1; cptr<nbrow; ++cptr)
00135     {
00136       vMask(cptr,cptc) = false;
00137 
00138       diffl[cptr*nbcol] = 0.0;
00139       diffu[cptr*nbcol] = cstnormal*fabs( (double)rawData[cptr*widthstep+cptc] - 
00140             (double)rawData[(cptr-1)*widthstep+cptc] );
00141 
00142       difful[cptr*nbcol] = 0.0;
00143       diffur[cptr*nbcol] = cstnormal*fabs( (double)rawData[cptr*widthstep+cptc] - 
00144              (double)rawData[(cptr-1)*widthstep+cptc+1] );
00145     } 
00146 
00147   // Last Column  
00148   for (unsigned int cptc=nbcol-1, cptr=1; cptr<nbrow; ++cptr)
00149     {
00150       vMask(cptr,cptc) = false;
00151 
00152       diffl[(cptr+1)*nbcol-1] = cstnormal*fabs( (double)rawData[cptr*widthstep+cptc] - 
00153                   (double)rawData[cptr*widthstep+cptc-1] );
00154       diffu[(cptr+1)*nbcol-1] = cstnormal*fabs( (double)rawData[cptr*widthstep+cptc] - 
00155                   (double)rawData[(cptr-1)*widthstep+cptc] );
00156       
00157       diffur[(cptr+1)*nbcol-1] = 0.0;
00158       difful[(cptr+1)*nbcol-1] = cstnormal*fabs( (double)rawData[cptr*widthstep+cptc] - 
00159                    (double)rawData[(cptr-1)*widthstep+cptc-1] );
00160     } 
00161   
00162   // The rest
00163   for (unsigned int cptr=1;cptr<=(nbrow-2);++cptr)
00164     {
00165       pos = cptr*nbcol;
00166       posIma = cptr*widthstep;
00167 
00168       for (unsigned int cptc=1;cptc<=(nbcol-2);++cptc)
00169         {
00170     vMask(cptr,cptc) = false;
00171     diffl[pos+cptc] = cstnormal*fabs( (double)rawData[posIma+cptc] - 
00172               (double)rawData[posIma+cptc-1] );
00173     diffu[pos+cptc] = cstnormal*fabs( (double)rawData[posIma+cptc] - 
00174               (double)rawData[posIma-widthstep+cptc] );
00175       
00176     diffur[pos+cptc] = cstnormal*fabs( (double)rawData[posIma+cptc] - 
00177                (double)rawData[posIma-widthstep+cptc+1] );
00178     difful[pos+cptc] = cstnormal*fabs( (double)rawData[posIma+cptc] - 
00179                (double)rawData[posIma-widthstep+cptc-1] );
00180         }
00181     } 
00182 
00183   std::cout << " First step of Homogeneous area detection accomplished in " << chrono.elapsed() << "sec." << std::endl;
00184  
00185 
00186   // *******************************************
00187         //  Mask Generation
00188   //  We exclude points too near of image sides
00189   //
00190 
00191   chrono.restart();
00192   
00193   for (unsigned int cptr=1; cptr<=(nbrow-2); ++cptr)
00194     {
00195       pos = cptr*nbcol;
00196       for (unsigned int cptc=1; cptc<=(nbcol-2); ++pos, ++cptc)
00197         if (geomMask.isPixelValid(cptc,cptr))
00198     {     
00199       vmaxS1 = (diffl[pos]>diffu[pos])?diffl[pos]:diffu[pos];
00200       vmaxS2 = (difful[pos]>diffur[pos])?difful[pos]:diffur[pos];
00201       vmax1 = (vmaxS1>vmaxS2)?vmaxS1:vmaxS2;
00202       
00203       vmaxS1 = (diffl[pos+1]>diffu[pos+nbcol])?diffl[pos+1]:diffu[pos+nbcol];
00204       vmaxS2 = (difful[pos+nbcol+1]>diffur[pos+nbcol-1])?difful[pos+nbcol+1]:diffur[pos+nbcol-1];
00205       vmax2 = (vmaxS1>vmaxS2)?vmaxS1:vmaxS2;
00206         
00207       if ((vmax1>=hrdThreshold)||(vmax2>=hrdThreshold))
00208         vMask(cptr,cptc) = true; 
00209     }
00210     }
00211 
00212   std::cout << " Second step of Homogeneous area detection accomplished in " << chrono.elapsed() << "sec." << std::endl;
00213 
00214 //  jafar::image::Image exportIma(nbcol,nbrow,IPL_DEPTH_8U,JfrImage_CS_GRAY);
00215   
00216 //  unsigned int nbpixelvalid = 0;
00217   
00218 //  for (unsigned int cptr = 0; cptr<nbrow; ++cptr)
00219 //    for (unsigned int cptc = 0; cptc<nbcol; ++cptc)     
00220 //      if (vMask(cptr,cptc))
00221 //        {
00222 //    exportIma.setPixelValue<unsigned char>(255,cptc,cptr,0);
00223 //    ++nbpixelvalid;
00224 //        }
00225 //      else
00226 //        exportIma.setPixelValue<unsigned char>(0,cptc,cptr,0);  
00227 //  exportIma.save("/home/msanfour/testMasque.tiff","disparityMap");
00228 
00229 //  std::cout << "Nombre de pixels valides : " << nbpixelvalid << " / " << width*height << std::endl;
00230   
00231   // ******************************************************************
00232   //
00233   //                 PART II : CENSUS TRANSFORMATION
00234   //  
00235   // ******************************************************************
00236   
00237   jblas::vec2 targetPix, onePixTest;
00238   jblas::vec3 pt3D, pt3DTest;
00239   
00240   unsigned char currentGL;
00241   unsigned int currentPOS;
00242 
00243   int winWcpt=0, winHcpt=0;
00244 
00245   double elev, elev0, azim, azim0, norm3D, targetGL;
00246   
00247   chrono.restart();
00248 
00249   for (unsigned int cptr=1; cptr<=(nbrow-2); ++cptr)
00250     {
00251 
00252       targetPix[1] = cptr;
00253       currentPOS = cptr*widthstep;
00254 
00255       for (unsigned int cptc=1; cptc<=(nbcol-2); ++cptc)
00256         {
00257     
00258     targetPix[0] = cptc;
00259     if (vMask(cptr,cptc))
00260       {
00261         // get grey level of the current pixel
00262         currentGL = rawData[currentPOS+cptc];
00263         
00264         // pixel to angular position on equivalent sphere
00265         omniCam.imageToCameraFrame<jblas::vec2,jblas::vec3>(targetPix,pt3D);
00266         norm3D = ublas::norm_2(pt3D);
00267         elev0 = M_PI_2 - asin(pt3D[2]/norm3D);
00268         azim0 = atan2(pt3D[1],pt3D[0]);       
00269 
00270         censusData[currentPOS+cptc].reset();
00271 
00272  //         if (popo==0)
00273 //          {
00274 //      std::cout << "initial bitstream = " << censusData[currentPOS+cptc] << std::endl;
00275 //      std::cout << "CurrentGL = " << (unsigned int)currentGL << std::endl;
00276 //          }
00277 
00278         // Boucle Principale
00279         for (pos = 0, winWcpt=-rCensus; winWcpt<=(int)rCensus; ++winWcpt)
00280           {
00281       azim = azim0 + winWcpt*oasCensus/(double)rCensus;
00282       for (winHcpt=-rCensus; winHcpt<=(int)rCensus; ++winHcpt, ++pos)
00283         {
00284           if ( (winWcpt==0) && (winHcpt==0) )
00285             {
00286         --pos;
00287         continue;
00288             }
00289           elev = elev0 + winHcpt*oasCensus/(double)rCensus;
00290           
00291           // angular position to position on the equivalent sphere
00292           pt3DTest[0] = sin(elev)*cos(azim);
00293           pt3DTest[1] = sin(elev)*sin(azim);
00294           pt3DTest[2] = cos(elev);
00295       
00296           // point on sphere to pixel
00297           omniCam.project<jblas::vec3,jblas::vec2>(pt3DTest,onePixTest);
00298 
00299           // get radiometry on onePixTest
00300           targetGL = img.getSubPixelValue<unsigned char>(onePixTest[0],onePixTest[1]);          
00301       
00302 //          if (popo==0)
00303 //            std::cout << "targetGL = " << targetGL << std::endl;
00304           
00305           if ((double)currentGL>=targetGL)
00306             censusData[currentPOS+cptc].set(pos,1);
00307 
00308         } // end loop on winHcpt
00309       
00310           } // end loop on winWcpt    
00311         
00312 //        if (popo==0)
00313 //          {
00314 //      std::cout << "final bitstream = " << censusData[currentPOS+cptc] << std::endl;
00315 //      popo = 1;
00316 //          }
00317         
00318       } // end test on vMask
00319 
00320         } // end of the loop on image columns
00321         
00322     } // end of the loop on image rows
00323 
00324         std::cout << " Census Transform accomplished in " << chrono.elapsed() << "sec." << std::endl;
00325     
00326 
00327       
00328   // ******************************************************************
00329   // 
00330   //                 PART III : SOME CLEANING
00331   //
00332   // ******************************************************************
00333 
00334   delete[] diffl;
00335   delete[] diffu;
00336   delete[] difful;
00337   delete[] diffur;  
00338 
00339       }; // end of constructor
00340 
00341       ~omniDataCensus(void)
00342       {
00343   delete[] censusData;
00344       };
00345       
00346     }; // end of struct omniDataCensus
00347 
00348     class omniPairCensus {
00349 
00350       omniDataCensus img1;
00351       
00352       omniDataCensus img2;
00353       
00354       unsigned int rCensus;
00355       
00356       unsigned int winWidth;
00357       
00358     public :
00359       
00363       omniPairCensus (jafar::image::Image &img1_, jafar::image::Image &img2_,
00364           jafar::camera::CameraBarreto &omnicam_,
00365           jafar::quasidense::omniMask &geomMask_,
00366           double oasCensus_=0.0079,
00367           unsigned int rCensus_=2,
00368           double hrdThreshold_=0.01) :
00369           
00370   img1(img1_, omnicam_, geomMask_, oasCensus_, rCensus_, hrdThreshold_),
00371   img2(img2_, omnicam_, geomMask_, oasCensus_, rCensus_, hrdThreshold_),
00372   rCensus(rCensus_),        
00373   winWidth(2*rCensus_+1)       
00374       {  };      
00375       
00379       bool isPointValidinIma1 (int u, int v);
00380       bool isPointValidinIma2 (int u, int v);
00381 
00385       bool isMatchValid (int u1, int v1, int u2, int v2);
00386       bool isMatchValid (int u1, int v1, int u2, int v2, unsigned int radius);
00387       
00391       double matchEval (int u1, int v1, int u2, int v2);
00392       double matchEval (int u1, int v1, int u2, int v2, unsigned int radius);
00393 
00397       void confirmedMatch (int u1, int v1, int u2, int v2)
00398       {
00399   img1.vMask(v1,u1) = false;
00400   img2.vMask(v2,u2) = false;
00401       };
00402       
00403     }; // end of class imgPairRank                        
00404 
00405   } // end of namespace quasidense
00406 
00407 } // end of namespace jafar
00408     
00409 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

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