1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > RANSAC算法原理与实现

RANSAC算法原理与实现

时间:2021-09-14 22:56:30

相关推荐

RANSAC算法原理与实现

参考原文:RANSAC算法学习笔记

重点内容:

算法流程:

1、在可以有(也可以没有,主要看应用场景)条件限制(比如选的子集里的点不能过远等)的情况下,随机选取子集,并假设为局内点。子集的大小,主要取决于要拟合模型的复杂度。

2、用局内点拟合一个模型,此模型适应于假设的局内点,所有的未知参数都能从假设的局内点计算得出。

3、 用2中得到的模型去测试整个数据中其他数据,如果某个点适用于估计的模型,认为它也是局内点,将局内点扩充。

4、如果有足够多的点被归类为假设的局内点,那么估计的模型就足够合理。

5、用所有扩充后的局内点去重新估计模型。

6、通过估计局内点与模型的错误率来评估模型。

7、如果当前模型效果比最好模型更好而被选用为最好模型,否则抛弃当前模型。至此完成一个迭代,然后从第1步开始一个新的迭代。

算法对比:

#include <opencv2/opencv.hpp>#include <iostream>#include <opencv2/xfeatures2d.hpp>#include <opencv2/features2d/features2d.hpp>void extracte_orb(cv::Mat input,std::vector<cv::KeyPoint> &keypoint,cv::Mat &descriptor){cv::Ptr<cv::ORB> f2d = cv::ORB::create(500);f2d->detect(input,keypoint);cv::Mat image_with_kp;f2d->compute(input,keypoint,descriptor);cv::drawKeypoints(input, keypoint, image_with_kp, cv::Scalar::all(-1),cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);cv::imwrite("orb"+std::to_string(random())+".png",image_with_kp);}void match_two_image(cv::Mat image1,cv::Mat image2, std::vector<cv::KeyPoint> keypoint1,std::vector<cv::KeyPoint> keypoint2,cv::Mat descriptor1,cv::Mat descriptor2){cv::BFMatcher matcher(cv::NORM_HAMMING);std::vector<cv::DMatch> matches;matcher.match(descriptor1,descriptor2, matches);cv::Mat good_matches_image;cv::drawMatches(image1, keypoint1, image2, keypoint2,matches, good_matches_image, cv::Scalar::all(-1), cv::Scalar::all(-1),std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);cv::imwrite("good_matches_image.png",good_matches_image);{std::vector <cv::KeyPoint> RAN_KP1, RAN_KP2;std::vector<cv::Point2f> keypoints1, keypoints2;for (int i = 0; i < matches.size(); i++) {keypoints1.push_back(keypoint1[matches[i].queryIdx].pt);keypoints2.push_back(keypoint2[matches[i].trainIdx].pt);RAN_KP1.push_back(keypoint1[matches[i].queryIdx]);RAN_KP2.push_back(keypoint2[matches[i].trainIdx]);}std::vector<uchar> RansacStatus;cv::findFundamentalMat(keypoints1, keypoints2, RansacStatus, cv::FM_RANSAC);std::vector <cv::KeyPoint> ransac_keypoints1, ransac_keypoints2;std::vector <cv::DMatch> ransac_matches;int index = 0;for (size_t i = 0; i < matches.size(); i++){if (RansacStatus[i] != 0){ransac_keypoints1.push_back(RAN_KP1[i]);ransac_keypoints2.push_back(RAN_KP2[i]);matches[i].queryIdx = index;matches[i].trainIdx = index;ransac_matches.push_back(matches[i]);index++;}}cv::Mat after_ransac_sift_match;cv::drawMatches(image1, ransac_keypoints1, image2, ransac_keypoints2,ransac_matches, after_ransac_sift_match, cv::Scalar::all(-1), cv::Scalar::all(-1),std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);cv::imwrite("after_ransac_orb_match.png",after_ransac_sift_match);}}int main(int argc, char *argv[]){cv::Mat image1 = cv::imread(argv[1]);cv::Mat image2 = cv::imread(argv[2]);std::vector<cv::KeyPoint> keypoint1,keypoint2;cv::Mat descriptor1, descriptor2;extracte_orb(image1,keypoint1,descriptor1);extracte_orb(image2,keypoint2,descriptor2);match_two_image(image1,image2,keypoint1,keypoint2,descriptor1,descriptor2);return 0;}

总结

从上面的结果来看,经过ransac后的效果还会很好的,剔除了很多错误的匹配结果。

RANSAC的优点是它能鲁棒的估计模型参数。例如,它能从包含大量局外点的数据集中估计出较高精度的参数,较少了离群点对模型结果的影响。

RANSAC的缺点是它计算参数的迭代次数没有上限;如果设置迭代次数的上限,得到的结果可能不是最优的结果,甚至可能得到错误的结果。RANSAC只有一定的概率得到可信的模型,概率与迭代次数成正比。RANSAC的另一个缺点是它要求设置跟问题相关的阀值。RANSAC只能从特定的数据集中估计出一个模型,如果存在两个(或多个)模型,RANSAC不能找到别的模型。

虽然缺点不少,但是我还是不能失去他。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。