Opencv 之ORB特征提取與匹配API簡介及使用例程

Opencv 之ORB特征提取與匹配API簡介及使用例程

  • ORB因其速度較快常被用于視覺SLAM中的位姿估計、視覺里程、圖像處理中的特征提取與匹配及圖像拼接等領域
  • 本文將詳細給出使用例程及實現效果展示

1. API 簡介

  • 創建
static Ptr<ORB> cv::ORB::create	(int nfeatures = 500,                                   //nfeatures 最終輸出最大特征點數目float scaleFactor = 1.2f,                            // scaleFactor 金字塔上采樣比率int nlevels = 8,                                            // nlevels 金字塔層數int edgeThreshold = 31,                                // edgeThreshold 邊緣閾值int firstLevel = 0,int WTA_K = 2,                                                // WTA_K這個是跟BRIEF描述子用的ORB::ScoreType 	scoreType = ORB::HARRIS_SCORE,        //  scoreType 對所有的特征點進行排名用的方法int patchSize = 31,int fastThreshold = 20 
)
  • 檢測
void cv::Feature2D::detect	(	InputArray 	image,   //輸入圖像std::vector< KeyPoint > & 	keypoints,    //待搜索特征點InputArray 	mask = noArray()    //操作掩碼)	
  • 計算
void cv::Feature2D::compute	(	InputArrayOfArrays 	images,    //輸入圖像std::vector< std::vector< KeyPoint > > & 	keypoints,OutputArrayOfArrays 	descriptors   //描述子)	
  • 檢測與計算
 void cv::Feature2D::detectAndCompute	(	InputArray 	image,InputArray 	mask,std::vector< KeyPoint > & 	keypoints,OutputArray 	descriptors,bool 	useProvidedKeypoints = false )	
  • 繪制特征點
void cv::drawMatches	(	InputArray 	img1,const std::vector< KeyPoint > & 	keypoints1,InputArray 	img2,const std::vector< KeyPoint > & 	keypoints2,const std::vector< DMatch > & 	matches1to2,InputOutputArray 	outImg,const Scalar & 	matchColor = Scalar::all(-1),const Scalar & 	singlePointColor = Scalar::all(-1),const std::vector< char > & 	matchesMask = std::vector< char >(),DrawMatchesFlags 	flags = DrawMatchesFlags::DEFAULT )	
  • 繪制匹配點對
void cv::drawMatches	(	InputArray 	img1,const std::vector< KeyPoint > & 	keypoints1,InputArray 	img2,const std::vector< KeyPoint > & 	keypoints2,const std::vector< DMatch > & 	matches1to2,InputOutputArray 	outImg,const Scalar & 	matchColor = Scalar::all(-1),const Scalar & 	singlePointColor = Scalar::all(-1),const std::vector< char > & 	matchesMask = std::vector< char >(),DrawMatchesFlags 	flags = DrawMatchesFlags::DEFAULT )	

2. 特征提取

  • 講述特征點提取與描述子計算,實現如下:
int main()
{Mat img = imread("./data/test3/lena.png");if (!img.data || img.empty()){cout << "圖像讀取錯誤!" << endl;return -1;}//創建ORB關鍵點Ptr<ORB> orb = ORB::create(500, 1.2f);double t1 = getTickCount();vector<KeyPoint>Keypoints;Mat descriptions;
#if 0//計算ORB關鍵點orb->detect(img, Keypoints);//計算ORB描述子orb->compute(img, Keypoints, descriptions);
#elseorb->detectAndCompute(img, cv::Mat(), Keypoints, descriptions);
#endif // 0double t2 = (getTickCount() - t1) / getTickFrequency() * 1000;cout << "img.size = " << img.size() << " , cost time = " << t2 << "ms\n";//繪制特征點Mat imgAngle;img.copyTo(imgAngle);//繪制不含角度和大小的結果drawKeypoints(img, Keypoints, img, Scalar(255, 255, 255));//繪制含有角度和大小的結果drawKeypoints(img, Keypoints, imgAngle, Scalar(255, 255, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);//顯示結果string wname1 = "不含角度和大小的結果", wname2 = "含角度和大小的結果";namedWindow(wname1, WINDOW_NORMAL);namedWindow(wname2, 0);imshow(wname1, img);imshow(wname2, imgAngle);waitKey(0);return 1;
}

在這里插入圖片描述

3. 特征匹配

  • 暴力匹配實現:
#include<iostream>
#include<opencv2/opencv.hpp>
#include<vector>using namespace std;
using namespace cv;int main()
{//灰度格式讀取Mat img1, img2;img1 = imread("./data/test3/1.jpg",IMREAD_GRAYSCALE);img2 = imread("./data/test3/2.jpg",0);if (img1.empty() || img2.empty()){cout << "img.empty!!!\n";return -1;}//提取orb特征點vector<KeyPoint>Keypoints1, Keypoints2;Mat descriptions1, descriptions2;//計算特征點orb_features(img1, Keypoints1, descriptions1);orb_features(img2, Keypoints2, descriptions2);//特征點匹配vector<DMatch>matches; BFMatcher matcher(NORM_HAMMING); //定義特征點匹配的類,使用漢明距離matcher.match(descriptions1, descriptions2, matches);cout << "matches = " << matches.size() << endl;//通過漢明距離篩選匹配結果double min_dist = 10000, max_dist = 0;for (int i = 0; i < matches.size(); ++i){double dist = matches[i].distance;min_dist = min_dist < dist ? min_dist : dist;max_dist = max_dist > dist ? max_dist : dist;}//輸出計算的最大、最小距離cout << "min_dist = " << min_dist << endl;cout << "max_dist = " << max_dist << endl;//通過距離提出誤差大的點vector<DMatch>goodmatches;for (int i = 0; i < matches.size(); ++i){if (matches[i].distance <= MAX(1.8 * min_dist, 30)) //需調參{goodmatches.push_back(matches[i]);}}cout << "good_min = " << goodmatches.size() << endl;//繪制結果Mat outimg, outimg1;drawMatches(img1, Keypoints1, img2, Keypoints2, matches, outimg);drawMatches(img1, Keypoints1, img2, Keypoints2, goodmatches, outimg1);string wname1 = "未篩選結果", wname2 = "最小漢明距離篩選";namedWindow(wname1, WINDOW_NORMAL);namedWindow(wname2, 0);imshow(wname1, outimg);imshow(wname2, outimg1);waitKey(0);return 1;
}

其效果如下:

在這里插入圖片描述

在這里插入圖片描述

  • 最近鄰匹配實現如下:
if (descriptions1.type() != CV_32F){descriptions1.convertTo(descriptions1, CV_32F);descriptions2.convertTo(descriptions2, CV_32F);}//特征點匹配vector<DMatch>matches;FlannBasedMatcher matcher; //定義特征點匹配的類,使用漢明距離matcher.match(descriptions1, descriptions2, matches);cout << "matches = " << matches.size() << endl;//通過漢明距離篩選匹配結果double min_dist = 10000, max_dist = 0;for (int i = 0; i < matches.size(); ++i){double dist = matches[i].distance;min_dist = min_dist < dist ? min_dist : dist;max_dist = max_dist > dist ? max_dist : dist;}//輸出計算的最大、最小距離cout << "min_dist = " << min_dist << endl;cout << "max_dist = " << max_dist << endl;//通過距離提出誤差大的點vector<DMatch>goodmatches;for (int i = 0; i < matches.size(); ++i){if (matches[i].distance <= 0.6 * max_dist) //需調參{goodmatches.push_back(matches[i]);}}cout << "good_min = " << goodmatches.size() << endl;

其效果如下:
在這里插入圖片描述
在這里插入圖片描述

  • RANSAC優化匹配
void ransac(vector<DMatch>matches, vector<KeyPoint>queryKeyPoint,vector<KeyPoint>trainKeyPoint, vector<DMatch>& matches_ransac)
{//定義保存匹配點對坐標vector<Point2f>srcPoints(matches.size()), dstPoints(matches.size());//保存從關鍵點中提取到的匹配點對坐標for (int i = 0; i < matches.size(); ++i){srcPoints[i] = queryKeyPoint[matches[i].queryIdx].pt;dstPoints[i] = trainKeyPoint[matches[i].trainIdx].pt;}//匹配點對RANSAC過濾vector<int>inlierMask(srcPoints.size());findHomography(srcPoints, dstPoints, RANSAC, 5, inlierMask);//手動保留RANSAC過濾后的匹配點對for (int i = 0; i < inlierMask.size(); ++i){if (inlierMask[i])matches_ransac.push_back(matches[i]);}
}//*************************RANSAC*******************************************
//main函數中放在暴力匹配代碼后://特征點匹配vector<DMatch>matches; BFMatcher matcher(NORM_HAMMING); //定義特征點匹配的類,使用漢明距離matcher.match(descriptions1, descriptions2, matches);cout << "matches = " << matches.size() << endl;//通過漢明距離篩選匹配結果double min_dist = 10000, max_dist = 0;for (int i = 0; i < matches.size(); ++i){double dist = matches[i].distance;min_dist = min_dist < dist ? min_dist : dist;max_dist = max_dist > dist ? max_dist : dist;}//輸出計算的最大、最小距離cout << "min_dist = " << min_dist << endl;cout << "max_dist = " << max_dist << endl;//通過距離提出誤差大的點vector<DMatch>goodmatches;for (int i = 0; i < matches.size(); ++i){if (matches[i].distance <= MAX(1.8 * min_dist, 30)) //需調參{goodmatches.push_back(matches[i]);}}cout << "good_min = " << goodmatches.size() << endl;//RANSAC優化:vector<DMatch>good_ransac;ransac(goodmatches, Keypoints1, Keypoints2, good_ransac);cout << "good_ransac = " << good_ransac.size() << endl;Mat output_;drawMatches(img1, Keypoints1, img2, Keypoints2, good_ransac, output_);namedWindow("ransac", 0);imshow("ransac", output_);

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/41749.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/41749.shtml
英文地址,請注明出處:http://en.pswp.cn/news/41749.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

無涯教程-Perl - use函數

描述 此函數將MODULE導出的所有功能(或僅LIST引用的功能)導入當前包的名稱空間。有效等效于- BEGIN { require "Module.pm"; Module->import(); }也用于在當前腳本上強加編譯器指令(編譯指示),盡管從本質上講它們只是模塊。 請注意,use語句在編譯時進行判斷。在…

springcloud3 hystrix實現服務熔斷的案例配置3

一 hystrix的熔斷原理 1.1 hystrix的熔斷原理 在springcloud的框架里&#xff0c;熔斷機制是通過hystrix實現&#xff0c;hystrix會監控服務之間的調用。當失敗調用達到一定的閾值&#xff0c;默認是5s內失敗20次&#xff0c;就會啟用hystrix的熔斷機制&#xff0c;使用命Hy…

神經網絡基礎-神經網絡補充概念-44-minibatch梯度下降法

概念 小批量梯度下降法&#xff08;Mini-Batch Gradient Descent&#xff09;是梯度下降法的一種變體&#xff0c;它結合了批量梯度下降&#xff08;Batch Gradient Descent&#xff09;和隨機梯度下降&#xff08;Stochastic Gradient Descent&#xff09;的優點。在小批量梯…

Apache Doris大規模數據使用指南

目錄 發展歷史 架構介紹 彈性MPP架構-極簡架構 邏輯架構 基本訪問架構 分區 創建單分區表

【C++ 記憶站】缺省參數

文章目錄 缺省參數的概念缺省參數的分類1、全缺省參數2、半缺省參數 缺省參數實際應用場景 缺省參數的概念 缺省參數是聲明或定義函數時為函數的參數指定一個缺省值。在調用該函數時&#xff0c;如果沒有指定實參則采用該形參的缺省值&#xff0c;否則使用指定的實參 正常調用一…

音頻解碼及如何在Java實現

本人并不干這個&#xff0c;但是被迫下水了解了一下這個&#xff0c;稍微做了一下整理。再就是感覺現在網上以及ChatGPT在這方面給出的答案太水了&#xff0c;在此開辟一篇。無意放出代碼&#xff0c;這里只介紹一些可能重要的點。 本來以為有了ChatGPT寫這些就沒有必要了&…

Docker部署ES服務,canal全量同步的時候內存爆炸,ES/Canal Adapter自動關閉,CPU100%

文章目錄 問題解決方案1. 對ES的限制2. 對Canal-Adapter的限制 問題 使用canal-adapter全量同步&#xff08;參考Canal Adapter1.1.5版本API操作服務&#xff0c;手動同步數據&#xff08;4&#xff09;&#xff09;的時候 小批量數據可以正常運行&#xff08;幾千條&#xf…

Llama 2免費托管及API提供

Llama 2 是 Meta 最新的文本生成模型&#xff0c;目前其性能優于所有開源替代方案。 推薦&#xff1a;用 NSDT編輯器 快速搭建可編程3D場景 1、強大的Llama 2 它擊敗了 Falcon-40B&#xff08;之前最好的開源基礎模型&#xff09;&#xff0c;與 GPT-3.5 相當&#xff0c;僅低…

【uni-app】 .sync修飾符與$emit(update:xxx)實現數據雙向綁定

最近在看uni-app文檔&#xff0c;看到.sync修飾符的時候&#xff0c;覺得很有必要記錄一下 其實uni-app是一個基于Vue.js和微信小程序開發框架的跨平臺開發工具 所以經常會聽到這樣的說法&#xff0c;只要你會vue&#xff0c;uni-app就不難上手 在看文檔的過程中&#xff0c;發…

.netcore grpc客戶端工廠及依賴注入使用

一、客戶端工廠概述 gRPC 與 HttpClientFactory 的集成提供了一種創建 gRPC 客戶端的集中方式。可以通過依賴包Grpc.Net.ClientFactory中的AddGrpcClient進行gRPC客戶端依賴注入AddGrpcClient函數提供了許多配置項用于處理一些其他事項&#xff1b;例如AOP、重試策略等 二、案…

miniExcel 生成excel

一、nuget dotnet add package MiniExcel --version 1.31.2 二、新建表及數據 ExampleProducts 三、這里我用了Dapper.Query方法 讀取excel public virtual async Task<IActionResult> Anonymous(){try{//using (var connection _dbContext.GetDbConnection())//{//…

linux中的ifconfig和ip addr

在linux操作系統中ifconfig和ip addr都是顯示網卡配置信息的命令&#xff0c;好多人有疑惑它們有什么區別呢 區別1&#xff1a;對于linux發行的版本不一樣 ip addr是對新發行版本的linux使用會比較多&#xff1b;而ifconfig是老版本遇到使用的會比較多。 區別2&#xff1a;顯…

神經網絡基礎-神經網絡補充概念-32-神經網絡與大腦

概念 神經網絡&#xff08;Neural Networks&#xff09;是受到生物神經系統啟發而設計的機器學習模型&#xff0c;用于處理和學習復雜的數據模式。盡管神經網絡的設計和工作原理與大腦有一些相似之處&#xff0c;但它們并不完全相同&#xff0c;以下是神經網絡和大腦之間的一些…

基于 KubeSphere 的應用容器化在智能網聯汽車領域的實踐

公司簡介 某國家級智能網聯汽車研究中心成立于 2018 年&#xff0c;是擔當產業發展咨詢與建議、共性技術研發中心、創新成果轉化的國家級創新平臺&#xff0c;旨在提高我國在智能網聯汽車及相關產業在全球價值鏈中的地位。 目前著力建設基于大數據與云計算的智能汽車云端運營…

RestTemplate

RestTemplate介紹 RestTemplate是Spring提供的用于訪問RESTful服務的客戶端&#xff0c;RestTemplate提供了多種便捷訪問遠程Http服務的方法,能夠大大提高客戶端的編寫效率。RestTemplate默認依賴JDK提供http連接的能力&#xff08;HttpURLConnection&#xff09;&#xff0c;…

js拼接字符串

在js中&#xff0c;你可以使用字符串拼接的方式創建新的字符串。 下面是一些常用的方法&#xff1a; 1、使用運算符&#xff1a; var str1 "Hello"; var str2 "World"; var result str1 " " str2; console.log(result); // 輸出&#xf…

【數據結構】鏈表常見題目

文章目錄 鏈表合并兩個有序鏈表反轉鏈表復制帶隨機指針的鏈表環形鏈表環形鏈表II相交鏈表移除鏈表元素鏈表中倒數第k個節點鏈表分割鏈表的回文結構鏈表的中間節點旋轉鏈表鏈表排序鏈表求和 (逆序求)鏈表求和II (正序求)重排鏈表奇偶鏈表反轉鏈表II <==> 鏈表內指定區間反…

(二)掌握最基本的Linux服務器用法——Linux下簡單的C/C++ 程序、項目編譯

1、靜態庫與動態庫 靜態庫(Static Library)&#xff1a;靜態庫是編譯后的庫文件&#xff0c;其中的代碼在編譯時被鏈接到程序中&#xff0c;因此它會與程序一起形成一個獨立的可執行文件。每個使用靜態庫的程序都會有自己的庫的副本&#xff0c;這可能會導致內存浪費。常用后綴…

opencv簡單使用

cv2庫安裝&#xff0c; conda install opencv-python注意cv2使用時&#xff0c;路徑不能有中文。&#xff08;不然會一直’None’ _ update # 處理中文路徑問題 def cv_imread(file_path): #使用之前需要導入numpy、cv2庫&#xff0c;file_path為包含中文的路徑return cv2.imd…

idea入門與maven配置的一些介紹

idea入門與maven配置的一些介紹 1.確保Java和Maven已安裝2.創建一個新的Maven項目3.導航到要創建項目的目錄配置Maven4.配置項目的pom.xml文件5.配置其他Tomcat和設置jdk6.構建和運行項目 關于idea入門基礎配置 步驟1&#xff1a;安裝IntelliJ IDEA 首先&#xff0c;從IntelliJ…