ransac_matching.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004-2012                                           \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 #ifndef RANSAC_MATCHING_H
00025 #define RANSAC_MATCHING_H
00026 #include<vcg/complex/algorithms/point_sampling.h>
00027 #include<vcg/complex/algorithms/update/color.h>
00028 #include<vcg/complex/algorithms/smooth.h>
00029 #include<vcg/space/index/kdtree/kdtree.h>
00030 #include<vcg/space/point_matching.h>
00031 namespace vcg
00032 {
00038 template <class MeshType> 
00039 class BaseFeature
00040 {
00041 public:
00042   BaseFeature():_v(0) {}
00043   typename MeshType::VertexType *_v;  
00044   typename MeshType::CoordType P() {return _v->cP();}    
00045 };
00046 
00047 
00048 template <class MeshType>
00049 class BaseFeatureSet 
00050 {
00051 public: 
00052   typedef   BaseFeature<MeshType> FeatureType;  
00053   typedef typename MeshType::VertexType      VertexType;
00054   typedef typename MeshType::ScalarType      ScalarType;  
00055   
00056   class Param 
00057   {
00058   public:
00059     Param()
00060     {
00061       featureSampleRatio = 0.5; // the number of feature that we choose on the total number of samples.
00062     }
00063 
00064     ScalarType featureSampleRatio;
00065   };
00066 
00067  
00068   std::vector<FeatureType> fixFeatureVec;
00069   std::vector<FeatureType> movFeatureVec;
00070   
00071   FeatureType &ff(int i) { return fixFeatureVec[i]; }
00072   FeatureType &mf(int i) { return movFeatureVec[i]; }
00073   int ffNum() const { return fixFeatureVec.size(); }
00074   int mfNum() const { return movFeatureVec.size(); }
00075   
00076   void Init(MeshType &fix, MeshType &mov,  
00077             std::vector<VertexType *> &fixSampleVec, std::vector<VertexType *> &movSampleVec,
00078             Param &fpp)
00079   {
00080     this->fixFeatureVec.resize(fixSampleVec.size()*fpp.featureSampleRatio);
00081     for(int i=0;i<fixFeatureVec.size();++i) 
00082       this->fixFeatureVec[i]._v = fixSampleVec[i];
00083       
00084     this->movFeatureVec.resize(movSampleVec.size()*fpp.featureSampleRatio);
00085     for(int i=0;i<movFeatureVec.size();++i) 
00086       this->movFeatureVec[i]._v = movSampleVec[i];
00087     
00088     printf("Generated %i Features on Fix\n",this->fixFeatureVec.size());
00089     printf("Generated %i Features on Mov\n",this->movFeatureVec.size());
00090   }
00091  
00092  // Returns the indexes of all the fix features matching a given one (from mov usually) 
00093  // remember that the idea is that 
00094  // we are aliging mov (that could be a single map) to fix (that could be a set of already aligned maps)
00095  void getMatchingFixFeatureVec(FeatureType &q, vector<int> &ffiVec, size_t maxMatchingFeature)
00096  {
00097   ffiVec.resize(std::min(fixFeatureVec.size(),maxMatchingFeature));
00098   
00099   for(int i=0;i<ffiVec.size();++i)
00100     ffiVec[i]=i;
00101  } 
00102 };
00103 
00104 /*******************/ 
00105 
00106 template <class MeshType> 
00107 class NDFeature 
00108 {
00109 public:
00110   NDFeature():_v(0) {}
00111   typename MeshType::VertexType *_v;  
00112   typename MeshType::CoordType nd; //   
00113   typename MeshType::CoordType P() {return _v->cP();}    
00114 };
00115 
00116 
00117 template <class MeshType>
00118 class NDFeatureSet 
00119 {
00120 public: 
00121   typedef   NDFeature<MeshType> FeatureType;  
00122   typedef typename MeshType::VertexType      VertexType;
00123   typedef typename MeshType::CoordType      CoordType;
00124   typedef typename MeshType::ScalarType      ScalarType;
00125  
00126   class Param
00127   {
00128   public:
00129     Param()
00130     {
00131       levAbs=CoordType(0,0,0);
00132       levPerc[0] = 0.01;
00133       levPerc[1] = levPerc[0]*2.0;
00134       levPerc[2] = levPerc[1]*2.0;      
00135     }
00136 
00137     CoordType levPerc; 
00138     CoordType levAbs; 
00139   };
00140   
00141   std::vector<FeatureType> fixFeatureVec;
00142   std::vector<FeatureType> movFeatureVec;
00143   KdTree<ScalarType> *fixFeatureTree;
00144   
00145   FeatureType &ff(int i) { return fixFeatureVec[i]; }
00146   FeatureType &mf(int i) { return movFeatureVec[i]; }
00147   int ffNum() const { return fixFeatureVec.size(); }
00148   int mfNum() const { return movFeatureVec.size(); }
00149   
00150   void Init(MeshType &fix, MeshType &mov,  
00151             std::vector<VertexType *> &fixSampleVec, std::vector<VertexType *> &movSampleVec, Param &pp)
00152   {
00153     ScalarType dd = std::max(fix.bbox.Diag(),mov.bbox.Diag());
00154     if(pp.levAbs == CoordType(0,0,0))
00155       pp.levAbs= pp.levPerc * dd;
00156         
00157     BuildNDFeatureVector(fix,fixSampleVec,pp.levAbs,fixFeatureVec);
00158     BuildNDFeatureVector(mov,movSampleVec,pp.levAbs,movFeatureVec);
00159     
00160     ConstDataWrapper<CoordType> cdw( &(fixFeatureVec[0].nd), fixFeatureVec.size(), sizeof(FeatureType));        
00161     fixFeatureTree = new  KdTree<ScalarType>(cdw); 
00162             
00163     printf("Generated %i ND Features on Fix\n",this->fixFeatureVec.size());
00164     printf("Generated %i ND Features on Mov\n",this->movFeatureVec.size());
00165   }
00166  
00167   
00168   static void BuildNDFeatureVector(MeshType &m, std::vector<VertexType *> &sampleVec, Point3f &distLev, std::vector<FeatureType> &featureVec )
00169   {    
00170     tri::UpdateNormal<MeshType>::PerVertexNormalized(m);
00171     tri::Smooth<MeshType>::VertexNormalLaplacian(m,10);
00172     
00173     VertexConstDataWrapper<MeshType > ww(m);
00174     KdTree<ScalarType> tree(ww); 
00175     featureVec.resize(sampleVec.size());
00176     const Point3f sqDistLev(distLev[0]*distLev[0], distLev[1]*distLev[1], distLev[2]*distLev[2]);
00177     for(int i=0;i<sampleVec.size();++i)
00178     {
00179       featureVec[i]._v=sampleVec[i];
00180       std::vector<unsigned int> ptIndVec;
00181       std::vector<ScalarType> sqDistVec;    
00182       tree.doQueryDist(sampleVec[i]->P(), distLev[2], ptIndVec, sqDistVec);
00183       Point3f varSum(0,0,0);
00184       Point3i varCnt(0,0,0);
00185       
00186       for(int j=0;j<sqDistVec.size();++j)
00187       {
00188         ScalarType nDist = Distance(m.vert[i].N(),m.vert[ptIndVec[j]].N()); 
00189         if(sqDistVec[j]<sqDistLev[0]) {
00190           varSum[0] += nDist;
00191           ++varCnt[0];
00192         }
00193         if(sqDistVec[j]<sqDistLev[1]) {
00194           varSum[1] += nDist; 
00195           ++varCnt[1];
00196         } 
00197         {
00198         varSum[2] += nDist; 
00199         ++varCnt[2];                
00200         }
00201       }      
00202       featureVec[i].nd[0] = varSum[0]/ScalarType(varCnt[0]);
00203       featureVec[i].nd[1] = varSum[1]/ScalarType(varCnt[1]);
00204       featureVec[i].nd[2] = varSum[2]/ScalarType(varCnt[2]);           
00205     }  
00206   }
00207   
00208   
00209  // Returns the indexes of all the fix features matching a given one (from mov usually) 
00210 void getMatchingFixFeatureVec(FeatureType &q, vector<int> &ffiVec, int maxNum)
00211 {
00212   ffiVec.clear();
00213   typename KdTree<ScalarType>::PriorityQueue pq;
00214   this->fixFeatureTree->doQueryK(q.nd,maxNum,pq);
00215   for(int i=0;i<pq.getNofElements();++i)
00216   {
00217     ffiVec.push_back(pq.getIndex(i));
00218   }
00219 } 
00220 };
00221 
00222 
00239 template <class MeshType, class FeatureSetType>
00240 class RansacFramework
00241 {
00242   typedef typename FeatureSetType::FeatureType       FeatureType;
00243   typedef typename FeatureSetType::Param       FeatureParam;
00244   
00245   typedef typename MeshType::CoordType       CoordType;
00246   typedef typename MeshType::BoxType         BoxType;
00247   typedef typename MeshType::ScalarType      ScalarType;
00248   typedef typename MeshType::VertexType      VertexType;
00249   typedef typename MeshType::VertexPointer   VertexPointer;
00250   typedef typename MeshType::VertexIterator  VertexIterator;
00251   typedef typename MeshType::EdgeType        EdgeType;
00252   typedef typename MeshType::EdgeIterator    EdgeIterator;
00253   typedef typename MeshType::FaceType        FaceType;
00254   typedef typename MeshType::FacePointer     FacePointer;
00255   typedef typename MeshType::FaceIterator    FaceIterator;
00256   typedef typename MeshType::FaceContainer   FaceContainer;
00257   typedef Matrix44<ScalarType>               Matrix44Type;
00258   
00259 public:
00260   class Param
00261   {
00262   public:
00263     Param()
00264     {
00265       iterMax=100;
00266       samplingRadiusPerc=0.005;
00267       samplingRadiusAbs=0;
00268       evalSize=1000;
00269       inlierRatioThr=0.3;
00270       inlierDistanceThrPerc = 1.5; // the distance between a transformed mov sample and the corresponding on fix should be 1.5 * sampling dist.
00271       congruenceThrPerc = 2.0; // the distance between two matching features must be  within 2.0 * sampling distance 
00272       minFeatureDistancePerc = 4.0; // the distance between two chosen features must be  at least 4.0 * sampling distance 
00273       maxMatchingFeatureNum = 100;
00274       areaThrPerc = 20.0;    // Triplets that make small triangles are discarded 
00275       
00276     }
00277    
00278     ScalarType inlierRatioThr;
00279     ScalarType inlierDistanceThrPerc;
00280     ScalarType congruenceThrPerc;
00281     ScalarType minFeatureDistancePerc;
00282     ScalarType samplingRadiusPerc;
00283     ScalarType samplingRadiusAbs;
00284     ScalarType areaThrPerc;
00285     int iterMax;
00286     int evalSize;
00287     int maxMatchingFeatureNum;
00288     
00289     ScalarType inlierSquareThr() const { return pow(samplingRadiusAbs* inlierDistanceThrPerc,2); }
00290   };
00291   
00292   class Candidate
00293   {
00294   public:
00295     int fixInd[3];
00296     int movInd[3];  
00297     int inlierNum;
00298     int evalSize;
00299     Matrix44Type Tr;
00300     ScalarType err() const {return float(inlierNum)/float(evalSize);}
00301     bool operator <(const Candidate &cc) const
00302     {
00303       return this->err() > cc.err();
00304     }
00305     
00306   };
00307 
00308   FeatureSetType FS;
00309   std::vector<Point3f> fixConsensusVec, movConsensusVec;
00310   KdTree<ScalarType> *consensusTree;
00311   
00312   
00313   // Given three pairs of sufficiently different distances (e.g. the edges of a scalene triangle)
00314   // it finds the permutation that brings the vertexes so that the distances match.
00315   // The meaning of the permutation vector nm0,nm1,nm2 is that the (N)ew index of (M)ov vertx i is the value of nmi 
00316   
00317   bool FindPermutation(int d01, int d02, int d12, int m01, int m02, int m12, int nm[], Param &pp)
00318   {
00319     ScalarType eps = pp.samplingRadiusAbs*2.0;
00320         
00321     if(fabs(d01-m01)<eps) {
00322       if(fabs(d02-m02)<eps) {
00323         if(fabs(d12-m12)<eps){ nm[0]=0;nm[1]=1;nm[2]=2; return true; }
00324             else return false;
00325       }
00326       if(fabs(d02-m12)<eps) {
00327         if(fabs(d12-m02)<eps){ nm[0]=1;nm[1]=0;nm[2]=2; return true; }
00328             else return false;        
00329       }        
00330     }
00331     
00332     if(fabs(d01-m02)<eps) {
00333       if(fabs(d02-m01)<eps) {
00334         if(fabs(d12-m12)<eps){ nm[0]=0;nm[1]=2;nm[2]=1; return true; }
00335             else return false;
00336       }
00337       if(fabs(d02-m12)<eps) {
00338         if(fabs(d12-m01)<eps){ nm[0]=2;nm[1]=0;nm[2]=1; return true; }
00339             else return false;        
00340       }        
00341     }
00342 
00343     if(fabs(d01-m12)<eps) {
00344       if(fabs(d02-m01)<eps) {
00345         if(fabs(d12-m02)<eps){ nm[0]=1;nm[1]=2;nm[2]=0; return true; }
00346             else return false;
00347       }
00348       if(fabs(d02-m02)<eps) {
00349         if(fabs(d12-m01)<eps){ nm[0]=2;nm[1]=1;nm[2]=0; return true; }
00350             else return false;        
00351       }        
00352     }
00353     return false;
00354   }
00355     
00356   
00357   
00358   // Scan the feature set of 
00359   void EvaluateFeature(int testSize, const char *filename, Param &pp)
00360   {
00361 //    VertexConstDataWrapper<MeshType> ww(fixM);
00362 //    KdTree<ScalarType>(ww) mTree;
00363     MeshType tmpM;  
00364     int neededSizeSum=0;
00365     int foundCnt=0;
00366     printf("Testing Feature size %i\n",testSize);
00367     for(int i=0;i<FS.mfNum();++i)
00368     {
00369       int neededSize = testSize;
00370       for(int j=1;j<neededSize;++j)
00371       {
00372         std::vector<int> closeFeatureVec; 
00373         FS.getMatchingFixFeatureVec(FS.mf(i), closeFeatureVec, j);        
00374         for(int k=0; k<closeFeatureVec.size();++k)
00375         {
00376           if(Distance(FS.mf(i).P(),FS.ff(closeFeatureVec[k]).P() )<pp.samplingRadiusAbs *3.0 )  
00377             neededSize = j;
00378         }
00379       }      
00380       tri::Allocator<MeshType>::AddVertex(tmpM, FS.mf(i).P());      
00381       tmpM.vert.back().Q() = neededSize;      
00382       neededSizeSum+=neededSize;
00383       if(neededSize<testSize) foundCnt++;
00384     }
00385     
00386     tri::UpdateColor<MeshType>::PerVertexQualityRamp(tmpM);
00387     tri::io::ExporterPLY<MeshType>::Save(tmpM,filename, tri::io::Mask::IOM_VERTCOLOR + tri::io::Mask::IOM_VERTQUALITY);    
00388     printf("Found %i / %i Average Needed Size %5.2f on %i\n",foundCnt,FS.mfNum(), float(neededSizeSum)/FS.mfNum(),testSize);
00389     
00390   }
00391 
00392   // The main loop. 
00393   // Choose three points on mov that make a scalene triangle 
00394   // and search on fix three other points with matchng distances 
00395   
00396   void Process_SearchEvaluateTriple (vector<Candidate> &cVec, Param &pp)
00397   {
00398     math::MarsenneTwisterRNG rnd;
00399 //    ScalarType congruenceEps = pow(pp.samplingRadiusAbs * pp.congruenceThrPerc,2.0f);
00400     ScalarType congruenceEps = pp.samplingRadiusAbs * pp.congruenceThrPerc;
00401     ScalarType minFeatureDistEps = pp.samplingRadiusAbs * pp.minFeatureDistancePerc;
00402     ScalarType minAreaThr = pp.samplingRadiusAbs * pp.samplingRadiusAbs *pp.areaThrPerc;
00403     printf("Starting search congruenceEps = samplingRadiusAbs * 3.0 = %6.2f \n",congruenceEps);
00404     int iterCnt=0;
00405     
00406     while ( (iterCnt < pp.iterMax) && (cVec.size()<100) )
00407     {
00408       Candidate c;
00409       // Choose a random pair of features from mov 
00410       c.movInd[0] = rnd.generate(FS.mfNum());
00411       c.movInd[1] = rnd.generate(FS.mfNum());
00412       ScalarType d01 = Distance(FS.mf(c.movInd[0]).P(),FS.mf(c.movInd[1]).P());
00413       if( d01 > minFeatureDistEps )
00414       {
00415         c.movInd[2] = rnd.generate(FS.mfNum());
00416         ScalarType d02=Distance(FS.mf(c.movInd[0]).P(),FS.mf(c.movInd[2]).P());
00417         ScalarType d12=Distance(FS.mf(c.movInd[1]).P(),FS.mf(c.movInd[2]).P());
00418         ScalarType areaTri = DoubleArea(Triangle3<ScalarType>(FS.mf(c.movInd[0]).P(), FS.mf(c.movInd[1]).P(), FS.mf(c.movInd[2]).P() ));
00419         if( ( d02 > minFeatureDistEps ) &&  // Sample are sufficiently distant
00420             ( d12 > minFeatureDistEps ) && 
00421             ( areaTri > minAreaThr) && 
00422             ( fabs(d01-d02) > congruenceEps ) && // and they make a scalene triangle
00423             ( fabs(d01-d12) > congruenceEps ) && 
00424             ( fabs(d12-d02) > congruenceEps ) )
00425         {
00426           // Find a congruent triple on mov 
00427           printf("Starting search of a [%i] congruent triple for %4i %4i %4i - %6.2f %6.2f %6.2f\n",
00428                  iterCnt,c.movInd[0],c.movInd[1],c.movInd[2],d01,d02,d12);
00429           // As a first Step we ask for three vectors of matching features;
00430           
00431           std::vector<int> fixFeatureVec0; 
00432           FS.getMatchingFixFeatureVec(FS.mf(c.movInd[0]), fixFeatureVec0,pp.maxMatchingFeatureNum);
00433           std::vector<int> fixFeatureVec1; 
00434           FS.getMatchingFixFeatureVec(FS.mf(c.movInd[1]), fixFeatureVec1,pp.maxMatchingFeatureNum);
00435           std::vector<int> fixFeatureVec2; 
00436           FS.getMatchingFixFeatureVec(FS.mf(c.movInd[2]), fixFeatureVec2,pp.maxMatchingFeatureNum);
00437           
00438           int congrNum=0;
00439           int congrGoodNum=0;
00440           for(int i=0;i<fixFeatureVec0.size();++i)
00441           { 
00442             if(cVec.size()>100) break;
00443             c.fixInd[0]=fixFeatureVec0[i];
00444             for(int j=0;j<fixFeatureVec1.size();++j)
00445             {               
00446               if(cVec.size()>100) break;             
00447               c.fixInd[1]=fixFeatureVec1[j];              
00448               ScalarType m01 = Distance(FS.ff(c.fixInd[0]).P(),FS.ff(c.fixInd[1]).P());
00449               if( (fabs(m01-d01)<congruenceEps) )
00450               {
00451 //                printf("- Found a congruent pair %i %i %6.2f\n", c.movInd[0],c.movInd[1], m01);                
00452                 ++congrNum;
00453                 for(int k=0;k<fixFeatureVec2.size();++k)
00454                 { 
00455                   if(cVec.size()>100) break;                  
00456                   c.fixInd[2]=fixFeatureVec2[k];
00457                   ScalarType m02=Distance(FS.ff(c.fixInd[0]).P(),FS.ff(c.fixInd[2]).P());
00458                   ScalarType m12=Distance(FS.ff(c.fixInd[1]).P(),FS.ff(c.fixInd[2]).P());
00459                   if( (fabs(m02-d02)<congruenceEps)  && (fabs(m12-d12)<congruenceEps ) )
00460                   {
00461                     c.Tr = GenerateMatchingMatrix(c,pp);
00462                     
00463                     EvaluateMatrix(c,pp);
00464                     if(c.err() > pp.inlierRatioThr ){
00465                       printf("- - Found  %lu th good congruent triple %i %i %i -- %f / %i \n", cVec.size(), c.movInd[0],c.movInd[1],c.movInd[2],c.err(),pp.evalSize);
00466 //                      printf("      - %4.3f %4.3f %4.3f - %4.3f %4.3f %4.3f \n",
00467 //                             FS.ff(c.fixInd[0]).nd[0], FS.ff(c.fixInd[0]).nd[1], FS.ff(c.fixInd[0]).nd[2],
00468 //                             FS.mf(c.movInd[0]).nd[0], FS.mf(c.movInd[0]).nd[1],FS.mf(c.movInd[0]).nd[2]);
00469                       
00470                       ++congrGoodNum;                      
00471                       cVec.push_back(c);
00472                     }
00473                   }
00474                 }
00475               }                
00476             }
00477           }
00478           printf("Completed Search of congruent triple (found %i / %i good/congruent)\n",congrGoodNum,congrNum);
00479         }               
00480       }
00481       ++iterCnt;
00482     } // end While
00483 
00484     printf("Found %lu candidates \n",cVec.size());
00485     sort(cVec.begin(),cVec.end());
00486     printf("best candidate %f \n",cVec[0].err());
00487     
00488     pp.evalSize = FS.mfNum();
00489     
00490     for(int i=0;i<cVec.size();++i)
00491       EvaluateMatrix(cVec[i],pp);
00492     
00493     sort(cVec.begin(),cVec.end());
00494     
00495     printf("After re-evaluation best is %f",cVec[0].err());
00496         
00497       
00498     
00499   } // end Process
00500   
00501   
00512   void EvaluateMatrix(Candidate &c, Param &pp)
00513   {
00514     c.inlierNum=0;
00515     c.evalSize=pp.evalSize;    
00516     
00517     ScalarType sqThr = pp.inlierSquareThr();
00518     int mid = pp.evalSize/2;
00519     uint ind;
00520     ScalarType squareDist;
00521     std::vector<Point3f>::iterator pi=movConsensusVec.begin();
00522     
00523     for(int j=0;j<2;++j)
00524     {
00525       for(int i=0;i<mid;++i)
00526       {
00527         Point3f qp = c.Tr*(*pi);
00528         consensusTree->doQueryClosest(qp,ind,squareDist);
00529         if(squareDist < sqThr)
00530           ++c.inlierNum;
00531         ++pi;
00532       }
00533       // Early bailout if after 1/2 of the test we have a very low consensus reject
00534       if((j==0) && (c.inlierNum < mid/10))  
00535       {
00536         c.inlierNum *=2;
00537         return;
00538       }        
00539     }
00540   }
00541   
00542   void DumpInlier(MeshType &m, Candidate &c, Param &pp)
00543   {
00544     ScalarType sqThr = pp.inlierSquareThr();
00545     for(int i=0;i<pp.evalSize;++i)
00546     {
00547       Point3f qp = c.Tr*movConsensusVec[i];
00548       uint ind;
00549       ScalarType squareDist;
00550       consensusTree->doQueryClosest(qp,ind,squareDist);
00551       if(squareDist < sqThr)
00552         tri::Allocator<MeshType>::AddVertex(m,qp);
00553     }
00554   }
00555   
00556 
00557 // Find the transformation that matches the mov onto the fix
00558 // eg M * piMov = piFix 
00559 
00560 Matrix44f GenerateMatchingMatrix(Candidate &c, Param pp)
00561 {
00562   std::vector<Point3f> pFix(3);
00563   pFix[0]= FS.ff(c.fixInd[0]).P();
00564   pFix[1]= FS.ff(c.fixInd[1]).P();
00565   pFix[2]= FS.ff(c.fixInd[2]).P();
00566   
00567   std::vector<Point3f> pMov(3);
00568   pMov[0]= FS.mf(c.movInd[0]).P();
00569   pMov[1]= FS.mf(c.movInd[1]).P();
00570   pMov[2]= FS.mf(c.movInd[2]).P();
00571 
00572   Point3f upFix = vcg::Normal(pFix[0],pFix[1],pFix[2]);
00573   Point3f upMov = vcg::Normal(pMov[0],pMov[1],pMov[2]);  
00574   
00575   upFix.Normalize(); 
00576   upMov.Normalize();
00577   
00578   upFix *= Distance(pFix[0],pFix[1]);
00579   upMov *= Distance(pMov[0],pMov[1]);
00580   
00581   for(int i=0;i<3;++i) pFix.push_back(pFix[i]+upFix);
00582   for(int i=0;i<3;++i) pMov.push_back(pMov[i]+upMov);
00583   
00584   Matrix44f res;
00585   ComputeRigidMatchMatrix(pFix,pMov,res);
00586   return res;  
00587 }
00588 
00589 
00590 void Init(MeshType &fixM, MeshType &movM, Param &pp, FeatureParam &fpp)
00591 {
00592   tri::UpdateNormal<MeshType>::PerVertexNormalizedPerFaceNormalized(fixM);
00593   tri::UpdateNormal<MeshType>::PerVertexNormalizedPerFaceNormalized(movM);
00594   
00595   // First a bit of Sampling
00596   typedef tri::TrivialPointerSampler<MeshType> BaseSampler;
00597   typename tri::SurfaceSampling<MeshType, BaseSampler>::PoissonDiskParam pdp;
00598   pdp.randomSeed = 0;
00599   pdp.bestSampleChoiceFlag = true;
00600   pdp.bestSamplePoolSize = 20;
00601   int t0=clock();
00602   pp.samplingRadiusAbs = pp.samplingRadiusPerc *fixM.bbox.Diag();
00603   BaseSampler pdSampler;
00604   std::vector<VertexType *> fixSampleVec;
00605   tri::SurfaceSampling<MeshType,BaseSampler>::PoissonDiskPruning(pdSampler, fixM, pp.samplingRadiusAbs,pdp);
00606   std::swap(pdSampler.sampleVec,fixSampleVec);
00607   std::vector<VertexType *> movSampleVec;  
00608   tri::SurfaceSampling<MeshType,BaseSampler>::PoissonDiskPruning(pdSampler, movM, pp.samplingRadiusAbs,pdp);
00609   std::swap(pdSampler.sampleVec,movSampleVec);
00610   int t1=clock();
00611   printf("Poisson Sampling of surfaces %5.2f ( %iv and %iv) \n",float(t1-t0)/CLOCKS_PER_SEC,fixSampleVec.size(),movSampleVec.size());
00612   printf("Sampling Radius %f \n",pp.samplingRadiusAbs);
00613   
00614   for(int i=0;i<fixSampleVec.size();++i) 
00615     this->fixConsensusVec.push_back(fixSampleVec[i]->P());    
00616 
00617   for(int i=0;i<movSampleVec.size();++i) 
00618     this->movConsensusVec.push_back(movSampleVec[i]->P());
00619   
00620   FS.Init(fixM, movM, fixSampleVec, movSampleVec, fpp);
00621     
00622   std::random_shuffle(movConsensusVec.begin(),movConsensusVec.end());
00623   
00624   VectorConstDataWrapper<std::vector<CoordType> > ww(fixConsensusVec);
00625   consensusTree = new  KdTree<ScalarType>(ww); 
00626 }
00627 
00628 
00629 };
00630 
00631 } //end namespace vcg
00632 
00633 
00634 #endif // RANSAC_MATCHING_H


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:34:59