1. 程式人生 > >ORB原理與Opencv原始碼解析

ORB原理與Opencv原始碼解析

   Ethan Rublee等人2011年在《ORB:An Efficient Alternative to SIFT or SURF》文章中提出了ORB演算法。結合Fast與Brief演算法,並給Fast特徵點增加了方向性,使得特徵點具有旋轉不變性,並提出了構造金字塔方法,解決尺度不變性,但文章中沒有具體詳述。實驗證明,ORB遠優於之前的SIFT與SURF演算法。

-------------------------------------------------------------------------------------------------------------------------------

論文核心內容概述:

1.構造金字塔,在每層金字塔上採用Fast演算法提取特徵點,採用Harris角點響應函式,按角點響應值排序,選取前N個特徵點。

2. oFast:計算每個特徵點的主方向,灰度質心法,計算特徵點半徑為r的圓形鄰域範圍內的灰度質心位置。從中心位置到質心位置的向量,定義為該特 徵點的主方向。

  定義矩的計算公式,x,y∈[-r,r]:

                                 

             質心位置:

                               

               主方向:

                                  

3.rBrief:為了解決旋轉不變性,把特徵點的Patch旋轉到主方向上(steered Brief)。通過實驗得到,描述子在各個維度上的均值比較離散(偏離0.5),同時維度間相關性很強,說明特徵點描述子區分性不好,影響匹配的效果。論文中提出採取學習的方法,採用300K個訓練樣本點。每一個特徵點,選取Patch大小為wp=31,Patch內每對點都採用wt=5大小的子視窗灰度均值做比較,子視窗的個數即為N=(wp-wt)*(wp-wt),從N個視窗中隨機選兩個做比較即構成描述子的一個bit,論文中採用M=205590種可能的情況:

       ---------------------------------------------------------------------------------

        1.對所有樣本點,做M種測試,構成M維的描述子,每個維度上非1即0;

        2.按均值對M個維度排序(以0.5為中心),組成向量T;

        3.貪婪搜尋:把向量T中第一個元素移動到R中,然後繼續取T的第二個元素,與R中的所有元素做相關性比較,如果相關性大於指定的閾值Threshold,           拋棄T的這個元素,否則加入到R中;

        4.重複第3個步驟,直到R中有256個元素,若檢測完畢,少於256個元素,則降低閾值,重複上述步驟;

       ----------------------------------------------------------------------------------

rBrief:通過上面的步驟取到的256對點,構成的描述子各維度間相關性很低,區分性好;

                                        

                                              訓練前                                            訓練後

---------------------------------------------------------------------------------------------------------------------------------

ORB演算法步驟,參考opencv原始碼:

1.首先構造尺度金字塔;

   金字塔共n層,與SIFT不同,每層僅有一副影象;

   第s層的尺度為,Fator初始尺度(預設為1.2),原圖在第0層;

   第s層影象大小:

                              

2.在不同尺度上採用Fast檢測特徵點;在每一層上按公式計算需要提取的特徵點數n,在本層上按Fast角點響應值排序,提取前2n個特徵點,然後根據Harris   角點響應值排序, 取前n個特徵點,作為本層的特徵點;

3.計算每個特徵點的主方向(質心法);

4.旋轉每個特徵點的Patch到主方向,採用上述步驟3的選取的最優的256對特徵點做τ測試,構成256維描述子,佔32個位元組;

                   ,,n=256

4.採用漢明距離做特徵點匹配;

----------OpenCV原始碼解析-------------------------------------------------------

ORB類定義:位置..\features2d.hpp

nfeatures:需要的特徵點總數;

scaleFactor:尺度因子;

nlevels:金字塔層數;

edgeThreshold:邊界閾值;

firstLevel:起始層;

 WTA_K:描述子形成方法,WTA_K=2表示,採用兩兩比較;

 scoreType:角點響應函式,可以選擇Harris或者Fast的方法;

 patchSize:特徵點鄰域大小;

[cpp] view plain copy  print?
  1. /*! 
  2.  ORB implementation. 
  3. */
  4. class CV_EXPORTS_W ORB : public Feature2D  
  5. {  
  6. public:  
  7.     // the size of the signature in bytes
  8.     enum { kBytes = 32, HARRIS_SCORE=0, FAST_SCORE=1 };  
  9.     CV_WRAP explicit ORB(int nfeatures = 500, float scaleFactor = 1.2f, int nlevels = 8, int edgeThreshold = 31,//建構函式
  10.         int firstLevel = 0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31 );  
  11.     // returns the descriptor size in bytes
  12.     int descriptorSize() const;   //描述子佔用的位元組數,預設32位元組
  13.     // returns the descriptor type
  14.     int descriptorType() const;//描述子型別,8位整形數
  15.     // Compute the ORB features and descriptors on an image
  16.     void operator()(InputArray image, InputArray mask, vector<KeyPoint>& keypoints) const;  
  17.     // Compute the ORB features and descriptors on an image
  18.     void operator()( InputArray image, InputArray mask, vector<KeyPoint>& keypoints,    //提取特徵點與形成描述子
  19.                      OutputArray descriptors, bool useProvidedKeypoints=false ) const;  
  20.     AlgorithmInfo* info() const;  
  21. protected:  
  22.     void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;//計算描述子
  23.     void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;//檢測特徵點
  24.     CV_PROP_RW int nfeatures;//特徵點總數
  25.     CV_PROP_RW double scaleFactor;//尺度因子
  26.     CV_PROP_RW int nlevels;//金字塔內層數
  27.     CV_PROP_RW int edgeThreshold;//邊界閾值
  28.     CV_PROP_RW int firstLevel;//開始層數
  29.     CV_PROP_RW int WTA_K;//描述子形成方法,預設WTA_K=2,兩兩比較
  30.     CV_PROP_RW int scoreType;//角點響應函式
  31.     CV_PROP_RW int patchSize;//鄰域Patch大小
  32. };  

特徵提取及形成描述子:通過這個函式對影象提取Fast特徵點或者計算特徵描述子

_image:輸入影象;

_mask:掩碼影象;

_keypoints:輸入角點;

_descriptors:如果為空,只尋找特徵點,不計算特徵描述子;

_useProvidedKeypoints:如果為true,函式只計算特徵描述子;

[cpp] view plain copy  print?
  1. /** Compute the ORB features and descriptors on an image 
  2.  * @param img the image to compute the features and descriptors on 
  3.  * @param mask the mask to apply 
  4.  * @param keypoints the resulting keypoints 
  5.  * @param descriptors the resulting descriptors 
  6.  * @param do_keypoints if true, the keypoints are computed, otherwise used as an input 
  7.  * @param do_descriptors if true, also computes the descriptors 
  8.  */
  9. void ORB::operator()( InputArray _image, InputArray _mask, vector<KeyPoint>& _keypoints,  
  10.                       OutputArray _descriptors, bool useProvidedKeypoints) const
  11. {  
  12.     CV_Assert(patchSize >= 2);  
  13.     bool do_keypoints = !useProvidedKeypoints;  
  14.     bool do_descriptors = _descriptors.needed();  
  15.     if( (!do_keypoints && !do_descriptors) || _image.empty() )  
  16.         return;  
  17.     //ROI handling
  18.     constint HARRIS_BLOCK_SIZE = 9;//Harris角點響應需要的邊界大小
  19.     int halfPatchSize = patchSize / 2;.//鄰域半徑
  20.     int border = std::max(edgeThreshold, std::max(halfPatchSize, HARRIS_BLOCK_SIZE/2))+1;//採用最大的邊界
  21.     Mat image = _image.getMat(), mask = _mask.getMat();  
  22.     if( image.type() != CV_8UC1 )  
  23.         cvtColor(_image, image, CV_BGR2GRAY);//轉灰度圖
  24.     int levelsNum = this->nlevels;//金字塔層數
  25.     if( !do_keypoints )   //不做特徵點檢測
  26.     {  
  27.         // if we have pre-computed keypoints, they may use more levels than it is set in parameters
  28.         // !!!TODO!!! implement more correct method, independent from the used keypoint detector.
  29.         // Namely, the detector should provide correct size of each keypoint. Based on the keypoint size
  30.         // and the algorithm used (i.e. BRIEF, running on 31x31 patches) we should compute the approximate
  31.         // scale-factor that we need to apply. Then we should cluster all the computed scale-factors and
  32.         // for each cluster compute the corresponding image.
  33. 相關推薦

    ORB原理Opencv原始碼解析

       Ethan Rublee等人2011年在《ORB:An Efficient Alternative to SIFT or SURF》文章中提出了ORB演算法。結合Fast與Brief演算法,並給Fast特徵點增加了方向性,使得特徵點具有旋轉不變性,並提出了構造金字塔方法,解決尺度不變性,但文章中

    【特徵匹配】ORB原理原始碼解析

    相關 : CSDN-勿在浮沙築高臺   為了滿足實時性的要求,前面文章中介紹過快速提取特徵點演算法Fast,以及特徵描述子Brief。本篇文章介紹的ORB演算法結合了Fast和Brief的速度優勢,並做了改進,且ORB是免費。 Ethan Rublee等人2011年

    HOG原理OpenCV實現

    方向梯度直方圖(Histogram of Oriented Gradient, HOG)於2005年提出,是一種常用的特徵提取方法,HOG+SVM在行人檢測中有著優異的效果。 HOG特徵提取演算法原理 在一幅影象中,梯度或邊緣的方向密度分佈能夠很好地描述區域性目標區域

    springmvc工作原理(無原始碼解析

    前言 對springmvc的工作方式一直有一些興趣,查閱了一些五花八門的資料,自己也嘗試著去看原始碼,但無奈原始碼太長,時間價效比太低,遂簡述基本的工作方式,如有錯誤,歡迎指出 SpringMvc工作原理圖 各元件功能: HandleMapping:根據URI

    springmvc工作原理(無原始碼解析)

    前言 對springmvc的工作方式一直有一些興趣,查閱了一些五花八門的資料,自己也嘗試著去看原始碼,但無奈原始碼太長,時間價效比太低,遂簡述基本的工作方式,如有錯誤,歡迎指出 SpringMvc工作原理圖 各元件功能: HandleMapping:根據URI

    OpenCV原始碼解析:目標檢測trainCascade演算法剖析之LBP基礎

    目標檢測,也叫目標提取,是一種基於目標幾何和統計特徵的影象分割。用級聯分類器實現目標檢測在AI人工智慧識別中應用十分廣泛。 正樣本的選取原則 正樣本的尺寸不是必須一致的,從原始碼可以看到,這個是可以在輸入圖片檔案的尺寸時設定大小從而實現在CreateSamples中進

    registerReceiver 動態註冊 sendBroadcast 原始碼解析

        廣播的註冊分為動態註冊和靜態註冊,靜態註冊主要在開機後PackageManagerService 利用 AndroidManifest 掃描 安裝的apk 獲取AndroidManifest內註冊的 廣播 所以 忽略 靜態註冊。今天主要介紹 動態廣播的註冊。  

    7 二分搜尋樹的原理Java原始碼實現

    1 折半查詢法 瞭解二叉查詢樹之前,先來看看折半查詢法,也叫二分查詢法 在一個有序的整數陣列中(假如是從小到大排序的),如果查詢某個元素,返回元素的索引。 如下: int[] arr = new int[]{1,3,4,6,8,9}; 在 arr 陣列中查詢6這個元素,查到返回對應的索引,沒有找到就返回-

    delayQueue原理理解之原始碼解析

    http://www.jianshu.com/p/e0bcc9eae0ae 內部結構 可重入鎖 用於根據delay時間排序的優先順序佇列 用於優化阻塞通知的執行緒元素leader 用於實現阻塞和通知的Condition物件 delayed和PriorityQueue 在

    Harris角點檢測原理opencv(python)實現

    在學習時主要參考了1.http://blog.csdn.net/xiaowei_cqu/article/details/7805206和opencv-python官方的關於harris的文件(http://opencv-python-tutroals.readthedocs

    【直播預告】:Java Spring Boot開發實戰系列課程【第11講】:訊息中介軟體 RabbitMQ api原始碼解析

    內容概要:mq訊息中介軟體在高併發系統架構中扮演關鍵角色,阿里雙11高併發使用了mq技術。本次課程一起學習最新Java Spring Boot 2.0、RabbitMQ中介軟體的最新特性與實戰應用,同樣會分析核心api原始碼。主講人:徐雷(阿里雲棲特邀Java專家)直播時間:2019年1月8日 週二 今晚20

    Spring基於註解形式的 AOP的原理流程及原始碼解析(一)

    在Spring的配置類上添加註解@EnableAspectJAutoProxy: @Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) public class MvcContextCo

    OpenCV原始碼解析之findContours

    說明:openCv的contours是分級的,其尋邊理論依據(方式)參考suzuki的論文《Topological structural analysis of digitized binary images by border following》。   Contour 的尋邊模

    OpenCV原始碼解析之在圖片中找四邊形-FindSquares

    這個FindSquares算是比較典型的綜合技能專案吧,用到的小技巧還不少,我們先看一下幾個函式吧, 函式static double angle的作用是求角度 根據餘弦定理: 在平面座標中 通過計算變換,最後可以得到: 嗯,函式中直接用了這個結果。 其餘函式的說明 1.函

    OpenCV入門教程之七】 玩轉OpenCV原始碼:生成OpenCV工程解決方案OpenCV原始碼編譯

    毛星雲,網路ID「淺墨」,90後,熱愛遊戲開發、遊戲引擎、計算機圖形、實時渲染等技術,就職於騰訊互娛。 微軟最有價值專家 著作《Windows遊戲程式設計之從零開始》、《OpenCV3程式設計入門》 碩士就讀於南京航空航天大學航天學院(2013級碩士研究生),已於2016年三月畢業。本科

    【特徵匹配】SIFT原理C原始碼剖析

         SIFT的原理已經有很多大牛的部落格上做了解析,本文重點將以Rob Hess等人用C實現的程式碼做解析,結合程式碼SIFT原理會更容易理解。一些難理解點的用了☆標註。       歡迎大家批評指正! 轉載請註明出處:http://blog.csdn.net/l

    Spring基於註解形式的 AOP的原理流程及原始碼解析(三)

    此篇部落格主要講解Spring如何驗證將要例項化的Bean是否應該被代理,生成代理物件的時機問題。 在第二篇部落格中,Spring對容器內所有的標識了@Aspect註解的的類的切面方法(標識了@Around, @Before, @After, @AfterRe

    週期性執行緒池主要原始碼解析

    之前學習ThreadPool的使用以及原始碼剖析,並且從面試的角度去介紹知識點的解答。今天小強帶來週期性執行緒池的使用和重點原始碼剖析。 ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor:用來處理延時任務或定時任務 定時執行緒池類的類結構圖

    OpenCV學習筆記(31)KAZE 演算法原理原始碼分析(五)KAZE的原始碼優化及SIFT的比較

      KAZE系列筆記: 1.  OpenCV學習筆記(27)KAZE 演算法原理與原始碼分析(一)非線性擴散濾波 2.  OpenCV學習筆記(28)KAZE 演算法原理與原始碼分析(二)非線性尺度空間構建 3.  Op

    OpenCV學習筆記(30)KAZE 演算法原理原始碼分析(四)KAZE特徵的效能分析比較

          KAZE系列筆記: 1.  OpenCV學習筆記(27)KAZE 演算法原理與原始碼分析(一)非線性擴散濾波 2.  OpenCV學習筆記(28)KAZE 演算法原理與原始碼分析(二)非線性尺度空間構