From e34a4e4c353722bfa61c3ced4ef3f395bb036a0d Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Thu, 23 Jul 2009 14:11:24 +0000 Subject: [PATCH] refactoring: function to select bases has been moved out from matching procedure. this should help us to investigate the importance/efficiency of base selection in the alignment process. major changes will follow in next commit --- .../feature_alignment.h | 54 +++++++++---------- .../filter_feature_alignment.cpp | 11 ++-- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/meshlabplugins/filter_feature_alignment/feature_alignment.h b/src/meshlabplugins/filter_feature_alignment/feature_alignment.h index afae03d76..7c8bd13cd 100644 --- a/src/meshlabplugins/filter_feature_alignment/feature_alignment.h +++ b/src/meshlabplugins/filter_feature_alignment/feature_alignment.h @@ -332,7 +332,7 @@ template class FeatureAlignment int maxNumFullConsensus; //max num of bases tested with full consensus procedure int maxNumShortConsensus; //max num of bases tested with short consensus procedure float mMovBBoxDiag; //mMov bbox diagonal; used to compute distances... - void (*log)(const char * f, ... ); //pointer to log function + void (*log)(int level,const char * f, ... ); //pointer to log function Parameters(MeshType& mFix, MeshType& mMov){ setDefault(mFix, mMov); @@ -408,9 +408,6 @@ template class FeatureAlignment struct CandidateType { - //typedef FEATURE_TYPE FeatureType; - //typedef SCALAR_TYPE ScalarType; - int shortCons; float summedPointDist; Matrix44 tr; @@ -513,9 +510,10 @@ template class FeatureAlignment if(cb){ progBar+=offset; cb(int(progBar),"Computing ransac..."); } assert(vecFMov); assert(vecFFix); - - int errCode = FeatureAlignment::Matching(*vecFFix, *vecFMov, fkdTree, *baseVec, *matchesVec, param); + + int errCode = FeatureAlignment::SelectBase(*vecFMov,*baseVec, param); if(errCode){ res.numSkippedIter++; continue; } //can't find a base, skip this iteration + errCode = FeatureAlignment::Matching(*vecFFix, *vecFMov, fkdTree, (*baseVec)[baseVec->size()-1], *matchesVec, param); assert(baseVec->size()>=1); int currBase = baseVec->size()-1; @@ -543,6 +541,7 @@ template class FeatureAlignment } assert(candidates->size()==matchesVec->size()); } + if(param.log) param.log(3,"%i bases found.", param.ransacIter-res.numSkippedIter); //res.matchingTime = int(difftime(end_loop,start_loop)); @@ -780,26 +779,27 @@ template class FeatureAlignment } } - static int Matching(vector& vecFFix, vector& vecFMov, ANNkd_tree* kdTree, vector& baseVec, vector& matchesVec, Parameters& param, CallBackPos *cb=NULL) + static int SelectBase(vector& vecFMov, vector& baseVec, Parameters& param) { - typedef MESH_TYPE MeshType; - typedef FEATURE_TYPE FeatureType; - typedef typename vector::iterator FeatureIterator; - - float pBar = 0, offset = 100.0f/param.nBase; //used for progresss bar callback - if(cb) cb(0, "Matching..."); assert(param.nBase<=int(vecFMov.size())); //not enough features to pick a base - assert(param.k<=int(vecFFix.size())); //not enough features in kdtree to pick k neighboors - - //compute needed params - float baseDist = param.sparseBaseDist*(param.mMovBBoxDiag/100.0f); - float errDist = param.mutualErrDist*(param.mMovBBoxDiag/100.0f); + float baseDist = param.sparseBaseDist*(param.mMovBBoxDiag/100.0f); //compute needed params FeatureType** base = FeatureAlignment::FeatureUniform(vecFMov, &(param.nBase)); //randomly chooses a base of features from vecFFix if(!VerifyBaseDistances(base, param.nBase, baseDist)) return 4; //if base point are not enough sparse, skip baseVec.push_back(base); + return 0; + } + + static int Matching(vector& vecFFix, vector& vecFMov, ANNkd_tree* kdTree, FEATURE_TYPE** base, vector& matchesVec, Parameters& param, CallBackPos *cb=NULL) + { + float pBar = 0, offset = 100.0f/param.nBase; //used for progresss bar callback + if(cb) cb(0, "Matching..."); + + assert(param.k<=int(vecFFix.size())); //not enough features in kdtree to pick k neighboors + + //compute needed params + float errDist = param.mutualErrDist*(param.mMovBBoxDiag/100.0f); - assert(baseVec.size()>=1); assert((int)vecFFix.size()>=param.nBase); //fill fqueryPts with feature's descriptions in base @@ -832,7 +832,7 @@ template class FeatureAlignment //branch and bound int* curSolution = new int[param.nBase]; for(int i=0; i class FeatureAlignment } } - static void Match(vector& baseVec, vector* >& matchedVec, int nBase, int level, int curSolution[], vector& solutionsVec, float errDist, CallBackPos *cb = NULL) + static void Match(FEATURE_TYPE** base, vector* >& matchedVec, int nBase, int level, int curSolution[], vector& solutionsVec, float errDist, CallBackPos *cb = NULL) { - typedef FEATURE_TYPE FeatureType; - assert(levelsize(); j++){ curSolution[level] = j; - if(MatchSolution(baseVec, matchedVec, level, curSolution, errDist)){ + if(MatchSolution(base, matchedVec, level, curSolution, errDist)){ if(level==nBase-1){ FeatureType** solution = new FeatureType*[nBase]; for(int h=0; h class FeatureAlignment solutionsVec.push_back(solution); } else - Match(baseVec, matchedVec, nBase, level+1, curSolution, solutionsVec, errDist); + Match(base, matchedVec, nBase, level+1, curSolution, solutionsVec, errDist); } } curSolution[level] = 0; } - static bool MatchSolution(vector& baseVec, vector* >& matchedVec, int level, int curSolution[], float errDist) + static bool MatchSolution(FEATURE_TYPE** base, vector* >& matchedVec, int level, int curSolution[], float errDist) { if (level==0) return true; - int currBase = baseVec.size()-1; - for(int j=0; jpos, baseVec[currBase][j]->pos); + float distF = vcg::Distance(base[level]->pos, base[j]->pos); float distM = vcg::Distance((*(matchedVec[level]))[curSolution[level]]->pos, (*(matchedVec[j]))[curSolution[j]]->pos); if( math::Abs(distF-distM)>errDist) return false; } diff --git a/src/meshlabplugins/filter_feature_alignment/filter_feature_alignment.cpp b/src/meshlabplugins/filter_feature_alignment/filter_feature_alignment.cpp index 0b06240ff..63988dd15 100644 --- a/src/meshlabplugins/filter_feature_alignment/filter_feature_alignment.cpp +++ b/src/meshlabplugins/filter_feature_alignment/filter_feature_alignment.cpp @@ -556,7 +556,9 @@ typename ALIGNER_TYPE::Result FilterFeatureAlignment::MatchingOperation(MeshMode if(res.exitCode==ResultType::FAILED) return res; //execute matching procedure with requested parameters; - int errCode = AlignerType::Matching(*(aligner.vecFFix), *(aligner.vecFMov), aligner.fkdTree, *baseVec, *matchesVec, param, cb); + int errCode = AlignerType::SelectBase(*(aligner.vecFMov),*baseVec,param); + if(errCode){ AlignerType::setError(errCode, res); return res; } + errCode = AlignerType::Matching(*(aligner.vecFFix), *(aligner.vecFMov), aligner.fkdTree, (*baseVec)[baseVec->size()-1], *matchesVec, param, cb); if(errCode){ AlignerType::setError(errCode, res); return res; } res.numMatches = matchesVec->size(); //store the numeber of matches found @@ -592,7 +594,9 @@ typename ALIGNER_TYPE::Result FilterFeatureAlignment::RigidTransformationOperati if(res.exitCode==ResultType::FAILED) return res; //execute matching procedure with requested parameters; - int errCode = AlignerType::Matching(*(aligner.vecFFix), *(aligner.vecFMov), aligner.fkdTree, *baseVec, *matchesVec, param, cb); + int errCode = AlignerType::SelectBase(*(aligner.vecFMov),*baseVec,param); + if(errCode){ AlignerType::setError(errCode, res); return res; } + errCode = AlignerType::Matching(*(aligner.vecFFix), *(aligner.vecFMov), aligner.fkdTree, (*baseVec)[baseVec->size()-1], *matchesVec, param, cb); if(errCode){ AlignerType::setError(errCode, res); return res; } res.numMatches = matchesVec->size(); //store the numeber of matches found @@ -655,6 +659,7 @@ typename ALIGNER_TYPE::Result FilterFeatureAlignment::RansacOperation(MeshModel& mMov.updateDataMask(MeshModel::MM_VERTMARK); AlignerType aligner; + param.log = &mylogger; //set the callback used to print infos inside the procedure ResultType res = aligner.init(mFix.cm, mMov.cm, param); if(res.exitCode==ResultType::FAILED) return res; @@ -696,8 +701,6 @@ for(int h=0; h<4; h++) float probSucc = 0.0f, meanTime = 0.0f, meanInitTime = 0.0f, failPerSec = -1.0f; int numWon = 0, trialsTotTime = 0, trialsInitTotTime = 0; param.ransacIter = from; - //param.log = &mylogger; //this is the way to assign a pointer to log function - //move res here while(param.ransacIter<=to) {