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?- /*!
- ORB implementation.
- */
- class CV_EXPORTS_W ORB : public Feature2D
- {
- public:
- // the size of the signature in bytes
- enum { kBytes = 32, HARRIS_SCORE=0, FAST_SCORE=1 };
- CV_WRAP explicit ORB(int nfeatures = 500, float scaleFactor = 1.2f, int nlevels = 8, int edgeThreshold = 31,//建構函式
- int firstLevel = 0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31 );
- // returns the descriptor size in bytes
- int descriptorSize() const; //描述子佔用的位元組數,預設32位元組
- // returns the descriptor type
- int descriptorType() const;//描述子型別,8位整形數
- // Compute the ORB features and descriptors on an image
- void operator()(InputArray image, InputArray mask, vector<KeyPoint>& keypoints) const;
- // Compute the ORB features and descriptors on an image
- void operator()( InputArray image, InputArray mask, vector<KeyPoint>& keypoints, //提取特徵點與形成描述子
- OutputArray descriptors, bool useProvidedKeypoints=false ) const;
- AlgorithmInfo* info() const;
- protected:
- void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;//計算描述子
- void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;//檢測特徵點
- CV_PROP_RW int nfeatures;//特徵點總數
- CV_PROP_RW double scaleFactor;//尺度因子
- CV_PROP_RW int nlevels;//金字塔內層數
- CV_PROP_RW int edgeThreshold;//邊界閾值
- CV_PROP_RW int firstLevel;//開始層數
- CV_PROP_RW int WTA_K;//描述子形成方法,預設WTA_K=2,兩兩比較
- CV_PROP_RW int scoreType;//角點響應函式
- CV_PROP_RW int patchSize;//鄰域Patch大小
- };
特徵提取及形成描述子:通過這個函式對影象提取Fast特徵點或者計算特徵描述子
_image:輸入影象;
_mask:掩碼影象;
_keypoints:輸入角點;
_descriptors:如果為空,只尋找特徵點,不計算特徵描述子;
_useProvidedKeypoints:如果為true,函式只計算特徵描述子;
[cpp] view plain copy print?- /** Compute the ORB features and descriptors on an image
- * @param img the image to compute the features and descriptors on
- * @param mask the mask to apply
- * @param keypoints the resulting keypoints
- * @param descriptors the resulting descriptors
- * @param do_keypoints if true, the keypoints are computed, otherwise used as an input
- * @param do_descriptors if true, also computes the descriptors
- */
- void ORB::operator()( InputArray _image, InputArray _mask, vector<KeyPoint>& _keypoints,
- OutputArray _descriptors, bool useProvidedKeypoints) const
- {
- CV_Assert(patchSize >= 2);
- bool do_keypoints = !useProvidedKeypoints;
- bool do_descriptors = _descriptors.needed();
- if( (!do_keypoints && !do_descriptors) || _image.empty() )
- return;
- //ROI handling
- constint HARRIS_BLOCK_SIZE = 9;//Harris角點響應需要的邊界大小
- int halfPatchSize = patchSize / 2;.//鄰域半徑
- int border = std::max(edgeThreshold, std::max(halfPatchSize, HARRIS_BLOCK_SIZE/2))+1;//採用最大的邊界
- Mat image = _image.getMat(), mask = _mask.getMat();
- if( image.type() != CV_8UC1 )
- cvtColor(_image, image, CV_BGR2GRAY);//轉灰度圖
- int levelsNum = this->nlevels;//金字塔層數
- if( !do_keypoints ) //不做特徵點檢測
- {
- // if we have pre-computed keypoints, they may use more levels than it is set in parameters
- // !!!TODO!!! implement more correct method, independent from the used keypoint detector.
- // Namely, the detector should provide correct size of each keypoint. Based on the keypoint size
- // and the algorithm used (i.e. BRIEF, running on 31x31 patches) we should compute the approximate
- // scale-factor that we need to apply. Then we should cluster all the computed scale-factors and
- // for each cluster compute the corresponding image.
-
相關推薦
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 演算法原理與原始碼分析(二)非線性尺度空間構