RANSAC算法的简单理解
? 圖像拼接中看到了特征匹配的部分,特征匹配主要是特征點(diǎn)的匹配。在特征點(diǎn)匹配的時(shí)候,首先進(jìn)行粗匹配,粗匹配通常是進(jìn)行一對(duì)匹配點(diǎn)進(jìn)行對(duì)比,誤差越小越可能是一對(duì)匹配點(diǎn);精匹配方法中,我們可以用到RANSAC(Random Sample Consensus?隨機(jī)抽樣一致性)算法。
RANSAC可以用于圖片的拼接技術(shù)。在多幅圖像合成時(shí),事先會(huì)在待合成的圖片中提取一些關(guān)鍵的特征點(diǎn)。計(jì)算機(jī)視覺的研究表明,不同視角下物體往往可以通過一個(gè)透視矩陣(單應(yīng)矩陣)(3X3或2X2)的變換而得到。RANSAC被用于擬合這個(gè)模型的參數(shù)(矩陣各行列的值),由此便可識(shí)別出不同照片中的同一物體。
(選自:https://blog.csdn.net/l297969586/article/details/52328884)
Ransac算法中要用四對(duì)特征點(diǎn)對(duì)構(gòu)建一個(gè)單應(yīng)矩陣,關(guān)于單應(yīng)矩陣的介紹參考博客:(https://blog.csdn.net/zhaocj/article/details/78799194)
? 我們可以理解為,粗匹配是從兩幅圖像所提取的特征集中,找到特征點(diǎn)之間相對(duì)應(yīng)的特征點(diǎn)對(duì);精匹配是在粗匹配的基礎(chǔ)上,再剔除一些不正確的匹配點(diǎn)對(duì)。
RANSAC算法步驟:
1.隨機(jī)選取四對(duì)匹配點(diǎn),計(jì)算出一個(gè)臨時(shí)模型參數(shù)(單應(yīng)矩陣)。
2.用該模型參數(shù)去測(cè)試匹配點(diǎn)對(duì)集,統(tǒng)計(jì)誤差在允許范圍內(nèi)的匹配點(diǎn)對(duì)數(shù)目(即內(nèi)點(diǎn)數(shù))。
3.當(dāng)內(nèi)點(diǎn)數(shù)目占到指定比例時(shí),則認(rèn)為所選取的匹配點(diǎn)對(duì)是合理的。
? 第一步選取的匹配點(diǎn)對(duì)合理: ?根據(jù)內(nèi)點(diǎn)信息重新計(jì)算得到最終的模型參數(shù)。
? 第一步選取的匹配點(diǎn)對(duì)不合理:重新選取匹配點(diǎn)對(duì),重復(fù)進(jìn)行模型參數(shù)計(jì)算,直到選取的特征點(diǎn)對(duì)合理。
?
---------------------------------------------------------------------------
?
?
代碼來(lái)源以及Ransac算法介紹:http://blog.csdn.net/luoshixian099/article/details/50217655
?
實(shí)例代碼如下:OpenCV中此功能通過調(diào)用findHomography函數(shù)調(diào)用
?
#include <iostream> #include "opencv2/opencv.hpp" #include "opencv2/core/core.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/highgui/highgui.hpp" using namespace cv; using namespace std;int main(int argc, char** argv) {Mat obj = imread("obj.jpg"); //載入目標(biāo)圖像 Mat scene = imread("scene.jpg"); //載入場(chǎng)景圖像 if (obj.empty() || scene.empty()){cout << "Can't open the picture!\n";return 0;}vector<KeyPoint> obj_keypoints, scene_keypoints;Mat obj_descriptors, scene_descriptors;ORB detector; //采用ORB算法提取特征點(diǎn) detector.detect(obj, obj_keypoints);detector.detect(scene, scene_keypoints);detector.compute(obj, obj_keypoints, obj_descriptors);detector.compute(scene, scene_keypoints, scene_descriptors);BFMatcher matcher(NORM_HAMMING, true); //漢明距離做為相似度度量 vector<DMatch> matches;matcher.match(obj_descriptors, scene_descriptors, matches);Mat match_img;drawMatches(obj, obj_keypoints, scene, scene_keypoints, matches, match_img);imshow("濾除誤匹配前", match_img);//保存匹配對(duì)序號(hào) vector<int> queryIdxs(matches.size()), trainIdxs(matches.size());for (size_t i = 0; i < matches.size(); i++){queryIdxs[i] = matches[i].queryIdx;trainIdxs[i] = matches[i].trainIdx;}Mat H12; //變換矩陣 vector<Point2f> points1; KeyPoint::convert(obj_keypoints, points1, queryIdxs);vector<Point2f> points2; KeyPoint::convert(scene_keypoints, points2, trainIdxs);int ransacReprojThreshold = 5; //拒絕閾值 H12 = findHomography(Mat(points1), Mat(points2), CV_RANSAC, ransacReprojThreshold);vector<char> matchesMask(matches.size(), 0);Mat points1t;perspectiveTransform(Mat(points1), points1t, H12);for (size_t i1 = 0; i1 < points1.size(); i1++) //保存‘內(nèi)點(diǎn)’ {if (norm(points2[i1] - points1t.at<Point2f>((int)i1, 0)) <= ransacReprojThreshold) //給內(nèi)點(diǎn)做標(biāo)記 {matchesMask[i1] = 1;}}Mat match_img2; //濾除‘外點(diǎn)’后 drawMatches(obj, obj_keypoints, scene, scene_keypoints, matches, match_img2, Scalar(0, 0, 255), Scalar::all(-1), matchesMask);//畫出目標(biāo)位置,場(chǎng)景圖片矩形std::vector<Point2f> obj_corners(4);obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(obj.cols, 0);obj_corners[2] = cvPoint(obj.cols, obj.rows); obj_corners[3] = cvPoint(0, obj.rows);std::vector<Point2f> scene_corners(4);perspectiveTransform(obj_corners, scene_corners, H12);line(match_img2, scene_corners[0] + Point2f(static_cast<float>(obj.cols), 0),scene_corners[1] + Point2f(static_cast<float>(obj.cols), 0), Scalar(0, 0, 255), 2);line(match_img2, scene_corners[1] + Point2f(static_cast<float>(obj.cols), 0),scene_corners[2] + Point2f(static_cast<float>(obj.cols), 0), Scalar(0, 0, 255), 2);line(match_img2, scene_corners[2] + Point2f(static_cast<float>(obj.cols), 0),scene_corners[3] + Point2f(static_cast<float>(obj.cols), 0), Scalar(0, 0, 255), 2);line(match_img2, scene_corners[3] + Point2f(static_cast<float>(obj.cols), 0),scene_corners[0] + Point2f(static_cast<float>(obj.cols), 0), Scalar(0, 0, 255), 2);imshow("濾除誤匹配后", match_img2);waitKey(0);return 0; }?
代碼實(shí)現(xiàn)的效果:
?
---。
總結(jié)
以上是生活随笔為你收集整理的RANSAC算法的简单理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++入门1
- 下一篇: Unity(一)Unity脚本程序开发