日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV实现SIFT特征提取与匹配

發(fā)布時(shí)間:2024/1/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV实现SIFT特征提取与匹配 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

本文介紹如何利用OpenCV從兩幅圖像中提取定位精度較高的尺度不變特征變換(SIFT)特征,并結(jié)合特征匹配方法建立兩幅圖像的特征對應(yīng)關(guān)系。

1. 程序架構(gòu)

利用MFC實(shí)現(xiàn)了簡易的Demo程序以便交互操作,界面如下所示。首先為兩幅待匹配的圖像選擇正確的路徑,再指定擬提取的特征類型(SIFT、SURF、ORB等),以及特征匹配方法(Brute Force、Flann Based等),隨后點(diǎn)擊“顯示匹配點(diǎn)對”,即可呈現(xiàn)兩幅圖像中經(jīng)過精確匹配的SIFT特征對應(yīng)關(guān)系。此外,還可點(diǎn)擊“保存匹配結(jié)果”,將匹配得到的SIFT點(diǎn)對的像素坐標(biāo),以文件形式保存至指定路徑。

2. 特征提取

2.1. 讀取圖像

(1)從MFC EditBrowse Control控件中讀取圖像文件的路徑;

CString selectedPath1, selectedPath2; GetDlgItemText(IDC_MFCEDITBROWSE_Image1, selectedPath1); GetDlgItemText(IDC_MFCEDITBROWSE_Image2, selectedPath2);

(2)將CString類型的文件路徑轉(zhuǎn)為cv::String類型,作為imread函數(shù)的輸入?yún)?shù);

USES_CONVERSION; cv::String cvStr1 = W2A(selectedPath1); cv::String cvStr2 = W2A(selectedPath2); Mat img1 = imread(cvStr1); Mat img2 = imread(cvStr2);

(3)判斷圖像是否讀取成功,并將彩色圖像轉(zhuǎn)為灰度圖像。

if (img1.data == NULL || img2.data == NULL) {MessageBox(_T("Reading error"));return; }if (img1.channels() > 1) {cvtColor(img1, img1, COLOR_BGR2GRAY); }if (img2.channels() > 1) {cvtColor(img2, img2, COLOR_BGR2GRAY); }

2.2. 檢測關(guān)鍵點(diǎn)

利用Opencv提供的SIFT檢測函數(shù),提取兩幅圖像中各自包含的關(guān)鍵點(diǎn);

Ptr<SIFT> sift = SIFT::create(); vector<KeyPoint> keypoints1, keypoints2; sift->detect(img1, keypoints1); sift->detect(img2, keypoints2);

2.3. 計(jì)算描述符

依據(jù)每幅圖像的關(guān)鍵點(diǎn)信息,計(jì)算對應(yīng)的描述符。

Mat descriptors1, descriptors2; sift->compute(img1, keypoints1, descriptors1); sift->compute(img2, keypoints2, descriptors2);

3. 特征匹配

(1)結(jié)合從兩幅圖像中提取的關(guān)鍵點(diǎn)和描述符,尋找粗略匹配的SIFT點(diǎn)對;

Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased"); vector<vector<DMatch> > matchPoints; vector<Mat> trainDesc(1, descriptors1); matcher->add(trainDesc); matcher->train(); matcher->knnMatch(descriptors2, matchPoints, 2);

(2)利用Lowe提出的誤匹配篩選方法,即當(dāng)候選匹配點(diǎn)對的最小距離小于次小距離的0.6倍時(shí),才認(rèn)為它們是正確匹配;

int trainIndex, queryIndex; vector<DMatch> candiMatchPoints; vector<Point2f> candiPts1, candiPts2; vector<KeyPoint> candiKeyPts1, candiKeyPts2; for (int i = 0; i < matchPoints.size(); i++) {if (matchPoints[i][0].distance < 0.6 * matchPoints[i][1].distance){candiMatchPoints.push_back(matchPoints[i][0]);trainIndex = matchPoints[i][0].trainIdx;queryIndex = matchPoints[i][0].queryIdx;candiKeyPts1.push_back(keypoints1[trainIndex]);candiKeyPts2.push_back(keypoints2[queryIndex]);candiPts1.push_back(keypoints1[trainIndex].pt);candiPts2.push_back(keypoints2[queryIndex].pt);} }

(3)采用隨機(jī)抽樣一致方法進(jìn)一步剔除誤匹配點(diǎn)對;

vector<uchar> ransacStatus; Mat funMat = findFundamentalMat(candiPts1, candiPts2, ransacStatus, FM_RANSAC);

(4)記錄最終得到的正確匹配點(diǎn)對,以供顯示和保存。

int index = 0; vector<Point2f> matchPts1, matchPts2; vector<DMatch> goodMatchPoints; vector<KeyPoint> goodKeyPts1, goodKeyPts2; for (int i=0; i<candiMatchPoints.size(); i++) {if (ransacStatus[i] != 0){goodKeyPts1.push_back(candiKeyPts1[i]);goodKeyPts2.push_back(candiKeyPts2[i]);candiMatchPoints[i].queryIdx = index;candiMatchPoints[i].trainIdx = index;goodMatchPoints.push_back(candiMatchPoints[i]);matchPts1.push_back(candiKeyPts1[i].pt);matchPts2.push_back(candiKeyPts2[i].pt);index++;} }

4. 結(jié)果顯示

在兩幅圖像中顯示特征匹配且剔除誤匹配之后的結(jié)果。

Mat img; drawMatches(img1, goodKeyPts1, img2, goodKeyPts2, goodMatchPoints, img); namedWindow("SIFT + Flann Based", 0); resizeWindow("SIFT + Flann Based", 1600, 600); imshow("SIFT + Flann Based", img); waitKey(0);

5. 圖像測試

將手機(jī)從不同角度拍攝的兩張圖像導(dǎo)入程序,得到特征提取和匹配結(jié)果如下所示,可以看到兩種視角下的特征點(diǎn)對應(yīng)關(guān)系比較準(zhǔn)確。
(1)兩幅圖像的特征匹配關(guān)系:


(2)保存特征點(diǎn)對的像素坐標(biāo):

6. 參考資料

[1] D. G. Lowe. Distinctive image features from scale-invariant keypoints. International Journal of Computer Vision, 60: 91-110 (2004).
[2] SIFT原理參考:https://blog.csdn.net/zddblog/article/details/7521424
[3] OpenCV代碼實(shí)現(xiàn)參考:https://blog.csdn.net/hellohake/article/details/104930117

總結(jié)

以上是生活随笔為你收集整理的OpenCV实现SIFT特征提取与匹配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。