opencv筆記--ORB


    ORB detector 使用 FAST detector 和 BRIEF descriptor 基本思路。在介紹 ORB 之前,首先對 FAST 與 BRIEF 進行說明。

 

    1 FAST

       FAST(Featrues from Accelerated Segment Test),其基本思想是比較當前點與周邊點差異,當周邊有連續不少於一半的點均比中間點亮或者暗,則認為該點為一個特征點。其中,亮或暗的定義為:

      1)當  時,周邊點比中間點亮;

      2)當  時,周邊點比中間點暗;

      3)當  時,周邊點與中間點相似;

      使用以上定義,可以迅速找到圖像中候選特征點。

      由於需要滿足不少於一半的連續周邊點亮於或暗於中間點,可以首先檢測水平與垂直方向上四個點,當少於兩個連續點滿足條件,則該點一定不是候選特征點。如此可以提升計算效率。

      當完成候選特征點掃描后,會發現存在許多臨近特征點,可以使用如下評分進行非極大值抑制:

      

       以上即為 FAST 的基本思想,opencv 實現在 cv::FastFeatureDetector 中,參數 threshold 定義了亮或暗,nonmaxSuppression 確定是否排除臨近點。

 

    2 BRIEF

       BRIEF 對特征點生成描述特征向量。在 SIFT 與 SURF 中均使用了塊特征描述方案,使用不同小塊的方向梯度直方圖構成特征向量。BRIEF 使用點特征描述特征點,基本思想為:

       1)在特征點區域內隨機生成 N 個點對,這N個點對生成方式有很多種,但一旦生成,對於所有特征點描述均使用相同的點對模式;

       2)由於需要對孤立點進行比較,所以首先平滑圖像以抑制噪聲;

       3)構造 N 位向量,第 k 個點對生成第 k 位向量,當點對中前一個點大於后一個點,其值為  1,反之為 0;

       opencv 實現在 cv::BriefDescriptorExtractor 中,參數 bytes 確定特征點描述向量長度為 bytes * 8。

       結合 FAST 與 BRIEF,可以實現類似 SIFT 與 SURF 的功能,以下給出簡單使用代碼:

       

 1 cv::FastFeatureDetector detector(20);
 2 std::vector<cv::KeyPoint> keypoints1, keypoints2;
 3 detector.detect(img1, keypoints1);
 4 detector.detect(img2, keypoints2);
 5 
 6 cv::BriefDescriptorExtractor brief;
 7 cv::Mat descriptors1, descriptors2;
 8 brief.compute(img1, keypoints1, descriptors1);
 9 brief.compute(img2, keypoints2, descriptors2);
10 
11 // 不同於SIFT與SURF,這里使用漢明距離
12 cv::BFMatcher matcher(cv::NORM_HAMMING);
13 std::vector<DMatch> matches;
14 matcher.match(descriptors1, descriptors2, matches);

 

      其匹配結果如下:

        

      

   

3 ORB

       ORB 主要思想如下:

       1)使用 FAST 提取候選特征點;

       2)為了克服 FAST 可能產生的邊緣響應,使用 Harris corner measure 保留角點響應,剔除邊緣響應(邊緣響應不利於匹配);

       3)按以上方法在不同層級圖像金字塔上搜索候選特征點;

       4)使用歸一化圖像描述特征點方向 

       5)使用特征點方向生成 BRIEF 特征點描述向量;

       6)使用漢明距離計算特征點之間相似度;

       opencv 提供  cv::ORB 實現特征點提取與描述,其構造函數參數如下:

       nfeatures 表示需要提取的特征點數量;

       scaleFactor,nlevels  為圖像金字塔參數;

       firstLevel 表示從第幾層開始搜索特征點,一般為 0;

       patchSize 確定特征點尺寸,edgeThreshold 應不小於 patchSize,該參數忽略邊界特征點;

       scoreType 確定使用 FAST 評分機制或者 Harris corner 評分機制;

       WTA_K 控制比較點個數,當為 2 時,即為 FAST 對點對比較方式;

       以下給出簡單使用代碼:

       

 1 cv::Mat img1 = cv::imread("a.bmp", cv::IMREAD_GRAYSCALE);
 2 cv::Mat img2 = cv::imread("b.bmp", cv::IMREAD_GRAYSCALE);
 3 
 4 std::vector<cv::KeyPoint> keypoints1, keypoints2;
 5 cv::Mat descriptors1, descriptors2;
 6 
 7 cv::ORB orb(100, 1.5, 4);
 8 orb.operator()(img1, cv::noArray(), keypoints1, descriptors1);
 9     orb.operator()(img2, cv::noArray(), keypoints2, descriptors2);
10 
11 cv::BFMatcher matcher(cv::NORM_HAMMING);
12 std::vector<DMatch> matches;
13 matcher.match(descriptors1, descriptors2, matches);
14 
15 cv::Mat img_matches;
16 cv::drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
17 cv::imwrite("c.jpg", img_matches);
18 
19 double min_dist = 100;
20 
21 for (int i = 0; i < matches.size(); i++)
22 {
23     double dist = matches[i].distance;
24     if (dist < min_dist) min_dist = dist;
25         
26 }
27 
28 // Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
29 // or a small arbitary value ( 0.02 ) 
30 std::vector< DMatch > good_matches;
31 
32 for (int i = 0; i < matches.size(); i++)
33 {
34     if (matches[i].distance <= max(2 * min_dist, 0.02))
35     {
36         good_matches.push_back(matches[i]);
37     }
38 }
39 
40 cv::drawMatches(img1, keypoints1, img2, keypoints2, good_matches, img_matches);
41 cv::imwrite("d.jpg", img_matches)

     其匹配結果如下:

     

     

     

     參考資料 Learning OpenCV 3   Adrian Kaehler & Gary Bradski


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM