00001 #include "RansacMultiFeatureSetMatcher.h"
00002
00003 #include <boost/random.hpp>
00004 #include <boost/random/uniform_smallint.hpp>
00005 #include <sys/time.h>
00006
00007
00008 RansacMultiFeatureSetMatcher::RansacMultiFeatureSetMatcher(double acceptanceThreshold, double successProbability, double inlierProbability, double distanceThreshold, double rigidityThreshold, bool adaptive):
00009 RansacFeatureSetMatcher(acceptanceThreshold, successProbability, inlierProbability, distanceThreshold, rigidityThreshold, adaptive)
00010 {
00011
00012 }
00013
00014 double RansacMultiFeatureSetMatcher::matchSets(const std::vector<InterestPoint *> &reference, const std::vector<InterestPoint *> &data, OrientedPoint2D& transformation,
00015 std::vector< std::pair<InterestPoint *, InterestPoint *> > &correspondences) const
00016 {
00017 correspondences.clear();
00018 unsigned int iterations = m_adaptive ? 1e17 : ceil(log(1. - m_successProbability)/log(1. - m_inlierProbability * m_inlierProbability));
00019
00020
00021 std::vector< std::pair<InterestPoint *, InterestPoint *> > possibleCorrespondences;
00022 for(unsigned int i = 0; i < data.size(); i++){
00023 for(unsigned int j = 0; j < reference.size(); j++){
00024 double distance = data[i]->getDescriptor()->distance(reference[j]->getDescriptor());
00025 if(distance < m_distanceThreshold){
00026 possibleCorrespondences.push_back(std::make_pair(data[i], reference[j]));
00027 }
00028 }
00029 }
00030
00031
00032 if(possibleCorrespondences.size() < 2){
00033 return 1e17;
00034 }
00035
00036
00037 if(double(possibleCorrespondences.size()) * m_inlierProbability < 2){
00038 return 1e17;
00039 }
00040
00041 boost::mt19937 rng;
00042 boost::uniform_smallint<int> generator(0, possibleCorrespondences.size() - 1);
00043
00044
00045 double minimumScore = 1e17;
00046 for(unsigned int i = 0; i < iterations; i++){
00047 unsigned int first = generator(rng);
00048 unsigned int second = generator(rng);
00049 while(second == first) second = generator(rng);
00050 std::pair< std::pair<InterestPoint *, InterestPoint *>, std::pair<InterestPoint *, InterestPoint *> > minimumSampleSet(possibleCorrespondences[first], possibleCorrespondences[second]);
00051
00052
00053 const Point2D& diffFirst = possibleCorrespondences[first].first->getPosition() - possibleCorrespondences[second].first->getPosition();
00054 const Point2D& diffSecond = possibleCorrespondences[first].second->getPosition() - possibleCorrespondences[second].second->getPosition();
00055 double distanceFirst = diffFirst * diffFirst;
00056 double distanceSecond = diffSecond * diffSecond;
00057 if((distanceFirst - distanceSecond)*(distanceFirst - distanceSecond)/(8*(distanceFirst + distanceSecond )) > m_rigidityThreshold){
00058 continue;
00059 }
00060
00061
00062 std::vector< std::pair<InterestPoint *, InterestPoint *> > inlierSet;
00063 OrientedPoint2D hypothesis = generateHypothesis(minimumSampleSet);
00064
00065
00066 double score = verifyHypothesis(reference, data, hypothesis, inlierSet);
00067 if(score < minimumScore){
00068 minimumScore = score;
00069 transformation = hypothesis;
00070 correspondences = inlierSet;
00071
00072
00073 if (m_adaptive){
00074 double inlierProbability = double(correspondences.size())/double(data.size());
00075 iterations = ceil(log(1. - m_successProbability)/log(1. - inlierProbability * inlierProbability));
00076 }
00077 }
00078 }
00079 std::vector<std::pair<Point2D, Point2D> > pointCorrespondences(correspondences.size());
00080 for(unsigned int i = 0; i < correspondences.size(); i++){
00081 pointCorrespondences[i] = std::make_pair(correspondences[i].first->getPosition(), correspondences[i].second->getPosition());
00082 }
00083 compute2DPose(pointCorrespondences, transformation);
00084
00085 return verifyHypothesis(reference, data, transformation, correspondences);
00086 }