影象拼接中看到了特徵匹配的部分,特徵匹配主要是特徵點的匹配。在特徵點匹配的時候,首先進行粗匹配,粗匹配通常是進行一對匹配點進行對比,誤差越小越可能是一對匹配點;精匹配方法中,我們可以用到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,都可以判斷它是否在該直線上。初中解析幾何知識告訴我們,判斷乙個點在直線上,只需其與直線上任意兩點點斜率都相同即可。實際操作當中,往往會先根據已知的兩點算出直線的表示式 點斜式 截距式等等 然後通過向量計算即可方便地...