TL;DR : Is there a C++ implementation of RANSAC or other robust correspondence algorithms that is freely usable with arbitrary 2D point sets?
I know that many implem
I was looking for something like that and then I found this.
The code is in c++ at bottom part.
The function below was originaly extracted from this class.
cv::Mat ransacTest(const std::vector& matches, const std::vector& keypoints1,const std::vector& keypoints2, std::vector& outMatches) {
// Convert keypoints into Point2f
std::vector points1, points2;
cv::Mat fundemental;
for (std::vector::const_iterator it= matches.begin(); it!= matches.end(); ++it) {
// Get the position of left keypoints
float x= keypoints1[it->queryIdx].pt.x;
float y= keypoints1[it->queryIdx].pt.y;
points1.push_back(cv::Point2f(x,y));
// Get the position of right keypoints
x= keypoints2[it->trainIdx].pt.x;
y= keypoints2[it->trainIdx].pt.y;
points2.push_back(cv::Point2f(x,y));
}
// Compute F matrix using RANSAC
std::vector inliers(points1.size(),0);
if ( points1.size() > 0 && points2.size() > 0 ){
cv::Mat fundemental= cv::findFundamentalMat(
cv::Mat(points1),cv::Mat(points2), // matching points
inliers, // match status (inlier or outlier)
CV_FM_RANSAC, // RANSAC method
3.0, // distance to epipolar line
0.99); // confidence probability
// extract the surviving (inliers) matches
std::vector::const_iterator itIn= inliers.begin();
std::vector::const_iterator itM= matches.begin();
// for all matches
for ( ;itIn!= inliers.end(); ++itIn, ++itM) {
if (*itIn) { // it is a valid match
outMatches.push_back(*itM);
}
}
// The F matrix will be recomputed with all accepted matches
// Convert keypoints into Point2f for final F computation
points1.clear();
points2.clear();
for (std::vector::const_iterator it= outMatches.begin(); it!=outMatches.end(); ++it) {
// Get the position of left keypoints
float x= keypoints1[it->queryIdx].pt.x;
float y= keypoints1[it->queryIdx].pt.y;
points1.push_back(cv::Point2f(x,y));
// Get the position of right keypoints
x= keypoints2[it->trainIdx].pt.x;
y= keypoints2[it->trainIdx].pt.y;
points2.push_back(cv::Point2f(x,y));
}
// Compute 8-point F from all accepted matches
if( points1.size() > 0 && points2.size() > 0){
fundemental= cv::findFundamentalMat(
cv::Mat(points1),cv::Mat(points2), // matches
CV_FM_8POINT); // 8-point method
}
}
return fundemental;
}