RANSAC算法的简单理解
? 圖像拼接中看到了特征匹配的部分,特征匹配主要是特征點的匹配。在特征點匹配的時候,首先進行粗匹配,粗匹配通常是進行一對匹配點進行對比,誤差越小越可能是一對匹配點;精匹配方法中,我們可以用到RANSAC(Random Sample Consensus?隨機抽樣一致性)算法。
RANSAC可以用于圖片的拼接技術。在多幅圖像合成時,事先會在待合成的圖片中提取一些關鍵的特征點。計算機視覺的研究表明,不同視角下物體往往可以通過一個透視矩陣(單應矩陣)(3X3或2X2)的變換而得到。RANSAC被用于擬合這個模型的參數(矩陣各行列的值),由此便可識別出不同照片中的同一物體。
(選自:https://blog.csdn.net/l297969586/article/details/52328884)
Ransac算法中要用四對特征點對構建一個單應矩陣,關于單應矩陣的介紹參考博客:(https://blog.csdn.net/zhaocj/article/details/78799194)
? 我們可以理解為,粗匹配是從兩幅圖像所提取的特征集中,找到特征點之間相對應的特征點對;精匹配是在粗匹配的基礎上,再剔除一些不正確的匹配點對。
RANSAC算法步驟:
1.隨機選取四對匹配點,計算出一個臨時模型參數(單應矩陣)。
2.用該模型參數去測試匹配點對集,統(tǒng)計誤差在允許范圍內的匹配點對數目(即內點數)。
3.當內點數目占到指定比例時,則認為所選取的匹配點對是合理的。
? 第一步選取的匹配點對合理: ?根據內點信息重新計算得到最終的模型參數。
? 第一步選取的匹配點對不合理:重新選取匹配點對,重復進行模型參數計算,直到選取的特征點對合理。
?
---------------------------------------------------------------------------
?
?
代碼來源以及Ransac算法介紹:http://blog.csdn.net/luoshixian099/article/details/50217655
?
實例代碼如下:OpenCV中此功能通過調用findHomography函數調用
?
#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"); //載入目標圖像 Mat scene = imread("scene.jpg"); //載入場景圖像 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算法提取特征點 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);//保存匹配對序號 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++) //保存‘內點’ {if (norm(points2[i1] - points1t.at<Point2f>((int)i1, 0)) <= ransacReprojThreshold) //給內點做標記 {matchesMask[i1] = 1;}}Mat match_img2; //濾除‘外點’后 drawMatches(obj, obj_keypoints, scene, scene_keypoints, matches, match_img2, Scalar(0, 0, 255), Scalar::all(-1), matchesMask);//畫出目標位置,場景圖片矩形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; }?
代碼實現的效果:
?
---。
總結
以上是生活随笔為你收集整理的RANSAC算法的简单理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++入门1
- 下一篇: Unity(一)Unity脚本程序开发