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

This commit is contained in:
Paolo Cignoni cignoni 2009-07-23 14:11:24 +00:00
parent 20364bcf95
commit e34a4e4c35
2 changed files with 32 additions and 33 deletions

View File

@ -332,7 +332,7 @@ template<class MESH_TYPE, class FEATURE_TYPE> 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 MESH_TYPE, class FEATURE_TYPE> class FeatureAlignment
struct CandidateType
{
//typedef FEATURE_TYPE FeatureType;
//typedef SCALAR_TYPE ScalarType;
int shortCons;
float summedPointDist;
Matrix44<ScalarType> tr;
@ -513,9 +510,10 @@ template<class MESH_TYPE, class FEATURE_TYPE> 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 MESH_TYPE, class FEATURE_TYPE> 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 MESH_TYPE, class FEATURE_TYPE> class FeatureAlignment
}
}
static int Matching(vector<FEATURE_TYPE*>& vecFFix, vector<FEATURE_TYPE*>& vecFMov, ANNkd_tree* kdTree, vector<FEATURE_TYPE**>& baseVec, vector<FEATURE_TYPE**>& matchesVec, Parameters& param, CallBackPos *cb=NULL)
static int SelectBase(vector<FEATURE_TYPE*>& vecFMov, vector<FEATURE_TYPE**>& baseVec, Parameters& param)
{
typedef MESH_TYPE MeshType;
typedef FEATURE_TYPE FeatureType;
typedef typename vector<FeatureType*>::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<FEATURE_TYPE*>& vecFFix, vector<FEATURE_TYPE*>& vecFMov, ANNkd_tree* kdTree, FEATURE_TYPE** base, vector<FEATURE_TYPE**>& 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 MESH_TYPE, class FEATURE_TYPE> class FeatureAlignment
//branch and bound
int* curSolution = new int[param.nBase];
for(int i=0; i<param.nBase; i++) curSolution[i] = 0; //initialization
FeatureAlignment::Match(baseVec, *matchedVec, param.nBase, 0, curSolution, matchesVec, errDist);
FeatureAlignment::Match(base, *matchedVec, param.nBase, 0, curSolution, matchesVec, errDist);
//Cleaning ANN structures
FeatureAlignment::CleanKDTree(NULL, NULL, fqueryPts, fnnIdx, fdists, false);
@ -954,15 +954,13 @@ template<class MESH_TYPE, class FEATURE_TYPE> class FeatureAlignment
}
}
static void Match(vector<FEATURE_TYPE**>& baseVec, vector<vector<FEATURE_TYPE*>* >& matchedVec, int nBase, int level, int curSolution[], vector<FEATURE_TYPE**>& solutionsVec, float errDist, CallBackPos *cb = NULL)
static void Match(FEATURE_TYPE** base, vector<vector<FEATURE_TYPE*>* >& matchedVec, int nBase, int level, int curSolution[], vector<FEATURE_TYPE**>& solutionsVec, float errDist, CallBackPos *cb = NULL)
{
typedef FEATURE_TYPE FeatureType;
assert(level<nBase);
for(unsigned int j=0; j<matchedVec[level]->size(); 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<nBase; h++){
@ -971,20 +969,18 @@ template<class MESH_TYPE, class FEATURE_TYPE> 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<FEATURE_TYPE**>& baseVec, vector<vector<FEATURE_TYPE*>* >& matchedVec, int level, int curSolution[], float errDist)
static bool MatchSolution(FEATURE_TYPE** base, vector<vector<FEATURE_TYPE*>* >& matchedVec, int level, int curSolution[], float errDist)
{
if (level==0) return true;
int currBase = baseVec.size()-1;
for(int j=0; j<level; j++){
float distF = vcg::Distance(baseVec[currBase][level]->pos, 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;
}

View File

@ -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)
{