OpenCV——SURF特徵檢測與匹配

來源:互聯網
上載者:User

標籤:介紹   lse   表示   五個   wait   相關資訊   mes   mat   最小   

SURF原理詳解:https://wenku.baidu.com/view/2f1e4d8ef705cc1754270945.html

SURF演算法工作原理

 

  1. 選擇映像中的POI(Points of interest) Hessian Matrix

  2. 在不同的尺度空間發現關鍵點,非最大訊號壓制

  3. 發現特徵點方法、旋轉不變性要求

  4. 產生特徵向量

 SURF建構函式介紹

 

C++:  SURF::SURF(

      double hessianThreshold, --閾值檢測器使用Hessian的關鍵點,預設值在

                                                   300-500之間

      int nOctaves=4,                 -- 4表示在四個尺度空間

      int nOctaveLayers=2,        -- 表示每個尺度的層數

      bool extended=false, 

      bool upright=false              --表示計算旋轉不變性,不計算的速度更快

)

 

特徵點繪製

 

特徵點繪製是為了把檢測出來的Surf特徵點在原圖上繪製出來,這一步是為了把特徵點直觀的顯示出來給我們看,跟整個Surf運算元的特徵提取和匹配流程沒關係。

繪製使用drawKeypoints方法:

void drawKeypoints( const Mat& image,

const vector<KeyPoint>& keypoints,

CV_OUT Mat& outImage,
const Scalar& color=Scalar::all(-1),

int flags=DrawMatchesFlags::DEFAULT

);

第一個參數image:原始映像,可以使三通道或單通道映像;

第二個參數keypoints:特徵點向量,向量內每一個元素是一個KeyPoint對象,包含了特徵點的各種屬性資訊;

第三個參數outImage:特徵點繪製的畫布映像,可以是原映像;

第四個參數color:繪製的特徵點的顏色資訊,預設繪製的是隨機彩色;

第五個參數flags:特徵點的繪製模式,其實就是設定特徵點的那些資訊需要繪製,那些不需要繪製,有以下幾種模式可選:

  DEFAULT:只繪製特徵點的座標點,顯示在映像上就是一個個小圓點,每個小圓點的圓心座標都是特徵點的座標。
  DRAW_OVER_OUTIMG:函數不建立輸出的映像,而是直接在輸出映像變數空間繪製,要求本身輸出映像變數就是一個初始化好了的,size與type都是已經初始化好的變數
  NOT_DRAW_SINGLE_POINTS:單點的特徵點不被繪製
  DRAW_RICH_KEYPOINTS:繪製特徵點的時候繪製的是一個個帶有方向的圓,這種方法同時顯示映像的座標,size,和方向,是最能顯示特徵資訊的一種繪製方式。

 

 1 #include <opencv2/opencv.hpp> 2 #include <opencv2/xfeatures2d.hpp> 3 #include <iostream> 4  5 using namespace cv; 6 using namespace cv::xfeatures2d; 7 using namespace std; 8  9 int main(int argc, char** argv) {10     Mat src = imread("test.jpg", IMREAD_GRAYSCALE);11     if (src.empty()) {12         printf("could not load image...\n");13         return -1;14     }15     namedWindow("input image", CV_WINDOW_AUTOSIZE);16     imshow("input image", src);17 18     // SURF特徵點檢測19     int minHessian = 100;20     Ptr<SURF> detector = SURF::create(minHessian);//建立一個surf類對象並初始化21     vector<KeyPoint> keypoints;22     detector->detect(src, keypoints, Mat());//找出關鍵點23 24     // 繪製關鍵點25     Mat keypoint_img;26     drawKeypoints(src, keypoints, keypoint_img, Scalar::all(-1), DrawMatchesFlags::DEFAULT);27     imshow("KeyPoints Image", keypoint_img);28 29     waitKey(0);30     return 0;31 }

繪製匹配點

 

drawMatches( const Mat& img1, const vector<KeyPoint>& keypoints1,                             const Mat& img2, const vector<KeyPoint>& keypoints2,                             const vector<DMatch>& matches1to2, Mat& outImg,                             const Scalar& matchColor=Scalar::all(-1), const Scalar& singlePointColor=Scalar::all(-1),                             const vector<char>& matchesMask=vector<char>(), int flags=DrawMatchesFlags::DEFAULT );

其中參數如下:

* img1 – 源映像1

* keypoints1 –源映像1的特徵點.

* img2 – 源映像2.

* keypoints2 – 源映像2的特徵點

* matches1to2 – 源映像1的特徵點匹配源映像2的特徵點[matches[i]] .

* outImg – 輸出映像具體由flags決定.

* matchColor – 匹配的顏色(特徵點和連線),若matchColor==Scalar::all(-1),顏色隨機.

* singlePointColor – 單個點的顏色,即未配對的特徵點,若matchColor==Scalar::all(-1),顏色隨機.

*matchesMask – Mask決定哪些點將被畫出,若為空白,則畫出所有匹配點. 

*flags—它跟drawKeypoints方法中flags的含義是一樣的。

當僅使用篩選出的最優匹配點進行匹配的時候,意味著會有很多非最優的特徵點不會被匹配,這時候可以設定flags=DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS  

 1 #include <opencv2/opencv.hpp> 2 #include <opencv2/xfeatures2d.hpp> 3 #include <iostream> 4  5 using namespace cv; 6 using namespace cv::xfeatures2d; 7 using namespace std; 8  9 int main(int argc, char** argv) {10     Mat src = imread("數字.jpg", IMREAD_GRAYSCALE);11     Mat temp = imread("2.png", IMREAD_GRAYSCALE);12     if (src.empty()|| temp.empty()) {13         printf("could not load image...\n");14         return -1;15     }16     namedWindow("input image", CV_WINDOW_AUTOSIZE);17     imshow("input image", src);18 19     // SURF特徵點檢測20     int minHessian = 400;21     Ptr<SURF> detector = SURF::create(minHessian,4,3,true,true);//建立一個surf類檢測器對象並初始化22     vector<KeyPoint> keypoints1, keypoints2;23     detector->detect(src, keypoints1, Mat());//找出關鍵點24     detector->detect(temp, keypoints2, Mat());//找出關鍵點25 26     BFMatcher matcher;         //執行個體化一個暴力匹配器27     Mat src_vector, temp_vector;//用來存放特徵點的描述向量28     vector<DMatch> matches;    //DMatch是用來描述匹配好的一對特徵點的類,包含這兩個點之間的相關資訊29                                //比如左圖有個特徵m,它和右圖的特徵點n最匹配,這個DMatch就記錄它倆最匹配,並且還記錄m和n的30                                //特徵向量的距離和其他資訊,這個距離在後面用來做篩選31 32     detector->detectAndCompute(src, Mat(), keypoints1, src_vector);//輸入映像,輸入遮罩,輸入特徵點,輸出Mat,存放所有特徵點的描述向量33     detector->detectAndCompute(temp, Mat(), keypoints2, temp_vector);//這個Mat行數為特徵點的個數,列數為每個特徵向量的尺寸,SURF是64(維)34 35     matcher.match(src_vector, temp_vector, matches);             //匹配,資料來源是特徵向量,結果存放在DMatch類型裡面  36 37                                               //sort函數對資料進行升序排列38     sort(matches.begin(), matches.end());     //篩選匹配點,根據match裡面特徵對的距離從小到大排序39     vector< DMatch > good_matches;40     int ptsPairs = std::min(50, (int)(matches.size() * 0.15));41     cout << ptsPairs << endl;42     for (int i = 0; i < ptsPairs; i++)43     {44         good_matches.push_back(matches[i]);//距離最小的50個壓入新的DMatch45     }46     Mat outimg;                                //drawMatches這個函數直接畫出擺在一起的圖47     drawMatches(src, keypoints1, temp, keypoints2, good_matches, outimg, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);  //繪製匹配點  48     imshow("KeyPoints Image", outimg);       49 50     waitKey(0);51     return 0;52 }

 

OpenCV——SURF特徵檢測與匹配

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.