前言
1.在目標檢測、識別,匹配的應用中,特征點的提取是不可缺少的部分的步驟,在之前博文我演示了HOG特性提取與使用HOG與SVM訓練自己的樣本進行行人檢測。
2.我的編程環境是Windows 7 64位,IDE是VS2015,配置了OpenCV3.3與OpenCV_Contrib,Boost 1.66,其中Boost是用來操作文件和目錄用的,是于如果配置以上的環境,可以看我之前寫的博文。
一、SURF概述
1.SIFT、SURF、ORB、HOG、LBP等都是特征點檢測及匹配基本算法,所謂特征檢測,就是不管所檢測的目標如何旋轉,圖像中所體現出的目標不管遠近,特征都是是變,這就是特征檢測的兩個特性,就是旋轉不變性與尺度不變性。
2.SIFT是目前應用最為的廣泛的特征提取及匹配的算法,SIFT具有旋轉、尺度、平移、視角及光照不變性;SIFT特征對參數調整魯棒性比較好,在進行特征描述時,可以根據場景需要可調整適宜的特征點數量,以便進行特征分析。但SITF這個算法有個缺點,就是是如果不借助硬件加速或專門的圖像處理器很難達到實時的效果。
3.2006年在ECCV大會Herbert Bay等人提出,對SIFT的改進,就是SURF,SURF算法對物體的旋轉、光照等情況有較好的魯棒性,且比SIFT算法而言計算速度更快。SURF算法使用海森矩陣(Hessian)的行列式值作特征點響應偵測并用積分圖加速運算;SURF 的描述子基于 2D 離散小波變換響應Harr小波并且有效地利用了積分圖,這大大的加速了程序的運行時間。SURF算法不僅保持了SIFT算法的尺度不變和旋轉不變的特性,而且對光照變化和放射變化同樣具有很強的魯棒性。
4.通過SURF算法檢測到的特征點其描述符包含了這個點的位置和尺度信息,故對兩幅圖片進行匹配時可以通過兩幅圖中特征點匹配對進行匹配。即使物體位置和光照的改變也能夠有良好的匹配效果。
二、SURF 演示
1.關于SURF構建的流程,可以查看一些相關的論文和介紹博客,我這里只寫主要的步驟,因為OpenCV官方已經封裝相關的類,我們拿出來應用就可以,是于低層的實現,參考OpenCV官方源碼。
(1).構建Hessian(黑塞矩陣),計算特征值α ,生成所有的興趣點,用于特征的提取。
(2).構建尺度空間.
(3)特征點定位
(4) 特征點主方向分配
(5) 生成特征點描述子
(6). 特征點匹配
2.代碼演示
SURF特征點提取與匹配代碼
#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)
{//圖像絕對路徑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 << "讀取圖片出錯!" << 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;//檢測特征關鍵點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);//畫出特征點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);//顯示所畫的特征點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 << "最長距離:" << 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.運行結果
(1)原始圖與關鍵點
(2)匹配的效果
結語
1.以上只是SURF特征提取和匹配的演示,如果想了解SURF在項目中的應用,可以看我另一個博文,使用SURF、SVM、BOW來對圖像進行分類。
2.關于工程的源碼,運行程序時的bug,都可以加這個群(487350510)互相討論學習。
總結
以上是生活随笔為你收集整理的OpneCV3特征提取及匹配SURF算法(一)——SURF概述与代码演示的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。