生活随笔
收集整理的這篇文章主要介紹了
OpneCV3特征提取及匹配SURF算法(一)——SURF概述与代码演示
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
前言
1.在目標(biāo)檢測(cè)、識(shí)別,匹配的應(yīng)用中,特征點(diǎn)的提取是不可缺少的部分的步驟,在之前博文我演示了HOG特性提取與使用HOG與SVM訓(xùn)練自己的樣本進(jìn)行行人檢測(cè)。
2.我的編程環(huán)境是Windows 7 64位,IDE是VS2015,配置了OpenCV3.3與OpenCV_Contrib,Boost 1.66,其中Boost是用來(lái)操作文件和目錄用的,是于如果配置以上的環(huán)境,可以看我之前寫的博文。
一、SURF概述
1.SIFT、SURF、ORB、HOG、LBP等都是特征點(diǎn)檢測(cè)及匹配基本算法,所謂特征檢測(cè),就是不管所檢測(cè)的目標(biāo)如何旋轉(zhuǎn),圖像中所體現(xiàn)出的目標(biāo)不管遠(yuǎn)近,特征都是是變,這就是特征檢測(cè)的兩個(gè)特性,就是旋轉(zhuǎn)不變性與尺度不變性。
2.SIFT是目前應(yīng)用最為的廣泛的特征提取及匹配的算法,SIFT具有旋轉(zhuǎn)、尺度、平移、視角及光照不變性;SIFT特征對(duì)參數(shù)調(diào)整魯棒性比較好,在進(jìn)行特征描述時(shí),可以根據(jù)場(chǎng)景需要可調(diào)整適宜的特征點(diǎn)數(shù)量,以便進(jìn)行特征分析。但SITF這個(gè)算法有個(gè)缺點(diǎn),就是是如果不借助硬件加速或?qū)iT的圖像處理器很難達(dá)到實(shí)時(shí)的效果。
3.2006年在ECCV大會(huì)Herbert Bay等人提出,對(duì)SIFT的改進(jìn),就是SURF,SURF算法對(duì)物體的旋轉(zhuǎn)、光照等情況有較好的魯棒性,且比SIFT算法而言計(jì)算速度更快。SURF算法使用海森矩陣(Hessian)的行列式值作特征點(diǎn)響應(yīng)偵測(cè)并用積分圖加速運(yùn)算;SURF 的描述子基于 2D 離散小波變換響應(yīng)Harr小波并且有效地利用了積分圖,這大大的加速了程序的運(yùn)行時(shí)間。SURF算法不僅保持了SIFT算法的尺度不變和旋轉(zhuǎn)不變的特性,而且對(duì)光照變化和放射變化同樣具有很強(qiáng)的魯棒性。
4.通過(guò)SURF算法檢測(cè)到的特征點(diǎn)其描述符包含了這個(gè)點(diǎn)的位置和尺度信息,故對(duì)兩幅圖片進(jìn)行匹配時(shí)可以通過(guò)兩幅圖中特征點(diǎn)匹配對(duì)進(jìn)行匹配。即使物體位置和光照的改變也能夠有良好的匹配效果。
二、SURF 演示
1.關(guān)于SURF構(gòu)建的流程,可以查看一些相關(guān)的論文和介紹博客,我這里只寫主要的步驟,因?yàn)镺penCV官方已經(jīng)封裝相關(guān)的類,我們拿出來(lái)應(yīng)用就可以,是于低層的實(shí)現(xiàn),參考OpenCV官方源碼。
(1).構(gòu)建Hessian(黑塞矩陣),計(jì)算特征值α ,生成所有的興趣點(diǎn),用于特征的提取。
(2).構(gòu)建尺度空間.
(3)特征點(diǎn)定位
(4) 特征點(diǎn)主方向分配
(5) 生成特征點(diǎn)描述子
(6). 特征點(diǎn)匹配
2.代碼演示
SURF特征點(diǎn)提取與匹配代碼
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\xfeatures2d\nonfree.hpp>
#include <opencv2\xfeatures2d.hpp>
#include <opencv2\ml\ml.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\features2d.hpp>
#include <opencv2\opencv.hpp>using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
using namespace ml;int main(void)
{//圖像絕對(duì)路徑string image1_path = "C:/Users/matt/Desktop/face/4.jpg";string image2_path = "C:/Users/matt/Desktop/face/5.jpg";//讀取圖像Mat src_image1 = imread(image1_path, 1);Mat src_image2 = imread(image2_path, 1);//判斷是否為空if (src_image1.empty() || src_image2.empty()){std::cerr << "讀取圖片出錯(cuò)!" << endl;return -1;}namedWindow("srcImage1", WINDOW_NORMAL);namedWindow("srcImage2", WINDOW_NORMAL);imshow("srcImage1", src_image1);imshow("srcImage2", src_image2);int minHessian = 100;Ptr<SURF> detector = SURF::create(minHessian);vector<KeyPoint> key_points_1, key_points_2;Mat dst_image1, dst_image2;//檢測(cè)特征關(guān)鍵點(diǎn)detector->detectAndCompute(src_image1, Mat(), key_points_1, dst_image1);detector->detectAndCompute(src_image2, Mat(), key_points_2, dst_image2);namedWindow("keyPoint1", WINDOW_NORMAL);namedWindow("keyPoint2", WINDOW_NORMAL);//畫出特征點(diǎn)Mat img_keypoints_1, img_keypoints_2;drawKeypoints(src_image1, key_points_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);drawKeypoints(src_image2, key_points_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT);//顯示所畫的特征點(diǎn)imshow("keyPoint1", img_keypoints_1);imshow("keyPoint2", img_keypoints_2);Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");vector<DMatch>mach;matcher->match(dst_image1, dst_image2, mach);double Max_dist = 0;double Min_dist = 100;for (size_t i = 0; i < dst_image1.rows; i++){double dist = mach[i].distance;if (dist < Min_dist){Min_dist = dist;}else if (dist > Max_dist){Max_dist = dist;}}std::cout << "最短距離:" << Min_dist << endl;std::cout << "最長(zhǎng)距離:" << Max_dist << endl;vector<DMatch>goodmaches;for (size_t i = 0; i < dst_image1.rows; i++){if (mach[i].distance < 2 * Min_dist){goodmaches.push_back(mach[i]);}}Mat img_maches;drawMatches(src_image1, key_points_1, src_image2, key_points_2, goodmaches, img_maches);for (int i = 0; i < goodmaches.size(); i++){std::cout << "符合條件的匹配:" << goodmaches[i].queryIdx << "--" << goodmaches[i].trainIdx << endl;}namedWindow("matching", WINDOW_NORMAL);imshow("matching", img_maches);waitKey(0);system("pause");return 0;
}
3.運(yùn)行結(jié)果
(1)原始圖與關(guān)鍵點(diǎn)
(2)匹配的效果
結(jié)語(yǔ)
1.以上只是SURF特征提取和匹配的演示,如果想了解SURF在項(xiàng)目中的應(yīng)用,可以看我另一個(gè)博文,使用SURF、SVM、BOW來(lái)對(duì)圖像進(jìn)行分類。
2.關(guān)于工程的源碼,運(yùn)行程序時(shí)的bug,都可以加這個(gè)群(487350510)互相討論學(xué)習(xí)。
總結(jié)
以上是生活随笔為你收集整理的OpneCV3特征提取及匹配SURF算法(一)——SURF概述与代码演示的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。