RANSAC演算法的簡單理解

2021-08-14 11:31:13 字數 3700 閱讀 6284

影象拼接中看到了特徵匹配的部分,特徵匹配主要是特徵點的匹配。在特徵點匹配的時候,首先進行粗匹配,粗匹配通常是進行一對匹配點進行對比,誤差越小越可能是一對匹配點;精匹配方法中,我們可以用到ransac(random sample consensus 隨機抽樣一致性)演算法。

ransac可以用於的拼接技術

。在多幅影象合成時,事先會在待合成的中提取一些關鍵的特徵點。計算機視覺的研究表明,不同視角下物體往往可以通過乙個透視矩陣(單應矩陣)

(3x3或2x2)

的變換而得到。ransac被用於擬合這個模型的引數(矩陣各行列的值),由此便可識別出不同**中的同一物體。

(選自:

ransac演算法中要用四對特徵點對構建乙個單應矩陣,關於單應矩陣的介紹參考部落格:(

我們可以理解為,粗匹配是從兩幅影象所提取的特徵集中,找到特徵點之間相對應的特徵點對;精匹配是在粗匹配的基礎上,再剔除一些不正確的匹配點對。

ransac演算法步驟:

1.隨機選取四對匹配點,計算出乙個臨時模型引數(單應矩陣)。

2.用該模型引數去測試匹配點對集,統計誤差在允許範圍內的匹配點對數目(即內點數)。

3.當內點數目佔到指定比例時,則認為所選取的匹配點對是合理的。

第一步選取的匹配點對合理:  根據內點資訊重新計算得到最終的模型引數。

第一步選取的匹配點對不合理:重新選取匹配點對,重複進行模型引數計算,直到選取的特徵點對合理。

****以及ransac演算法介紹:

例項**如下:opencv中此功能通過呼叫findhomography函式呼叫

#include #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)

vectorobj_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); //漢明距離做為相似度度量

vectormatches;

matcher.match(obj_descriptors, scene_descriptors, matches);

mat match_img;

drawmatches(obj, obj_keypoints, scene, scene_keypoints, matches, match_img);

imshow("濾除誤匹配前", match_img);

//儲存匹配對序號

vectorqueryidxs(matches.size()), trainidxs(matches.size());

for (size_t i = 0; i < matches.size(); i++)

mat h12; //變換矩陣

vectorpoints1;

keypoint::convert(obj_keypoints, points1, queryidxs);

vectorpoints2;

keypoint::convert(scene_keypoints, points2, trainidxs);

int ransacreprojthreshold = 5; //拒絕閾值

h12 = findhomography(mat(points1), mat(points2), cv_ransac, ransacreprojthreshold);

vectormatchesmask(matches.size(), 0);

mat points1t;

perspectivetransform(mat(points1), points1t, h12);

for (size_t i1 = 0; i1 < points1.size(); i1++) //儲存『內點』 }

mat match_img2; //濾除『外點』後

drawmatches(obj, obj_keypoints, scene, scene_keypoints, matches, match_img2, scalar(0, 0, 255), scalar::all(-1), matchesmask);

//畫出目標位置,場景矩形

std::vectorobj_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::vectorscene_corners(4);

perspectivetransform(obj_corners, scene_corners, h12);

line(match_img2, scene_corners[0] + point2f(static_cast(obj.cols), 0),

scene_corners[1] + point2f(static_cast(obj.cols), 0), scalar(0, 0, 255), 2);

line(match_img2, scene_corners[1] + point2f(static_cast(obj.cols), 0),

scene_corners[2] + point2f(static_cast(obj.cols), 0), scalar(0, 0, 255), 2);

line(match_img2, scene_corners[2] + point2f(static_cast(obj.cols), 0),

scene_corners[3] + point2f(static_cast(obj.cols), 0), scalar(0, 0, 255), 2);

line(match_img2, scene_corners[3] + point2f(static_cast(obj.cols), 0),

scene_corners[0] + point2f(static_cast(obj.cols), 0), scalar(0, 0, 255), 2);

imshow("濾除誤匹配後", match_img2);

waitkey(0);

return 0;

}

**實現的效果:

RANSAC演算法理解

1 最小二乘法法,即,擬合 y ax b中的a和b 2 檢測點是否在直線上,也就是計算點到直線的距離是否小於我們設定的閾值。具體做法,取直線的法向量為 p為待測點到直線上任一點的向量 3 ransac匹配 1 在所有的資料點中隨機取m m 2 個點,使用最小二乘法擬合一條直線 2 在剩餘點中,檢測到...

RANSAC演算法理解與應用

ransac核心思想就是隨機性和假設性,隨機性用於減少計算,迴圈次數是利用正確資料出現的概率。而假設性,就是說隨機抽出來的資料都認為是正確的,並以此去計算其他點,獲得其他滿足變換關係的點,然後利用投票機制,選出獲票最多的那乙個變換。具體的流程 1 在可以有 也可以沒有,主要看應用場景 條件限制 比如...

RANSAC演算法詳解

另參考 給定兩個點p1與p2的座標,確定這兩點所構成的直線,要求對於輸入的任意點p3,都可以判斷它是否在該直線上。初中解析幾何知識告訴我們,判斷乙個點在直線上,只需其與直線上任意兩點點斜率都相同即可。實際操作當中,往往會先根據已知的兩點算出直線的表示式 點斜式 截距式等等 然後通過向量計算即可方便地...