ORB 算法學(xué)習(xí)筆記

本博客內(nèi)容來(lái)源于網(wǎng)絡(luò)以及其他書(shū)籍茵臭,結(jié)合自己學(xué)習(xí)的心得進(jìn)行重編輯疫诽,因?yàn)榭戳撕芏辔恼虏槐阋灰粯?biāo)注引用,如圖片文字等侵權(quán)旦委,請(qǐng)告知?jiǎng)h除踊沸。

傳統(tǒng)2D計(jì)算機(jī)視覺(jué)學(xué)習(xí)筆記目錄------->傳送門(mén)
傳統(tǒng)3D計(jì)算機(jī)視覺(jué)學(xué)習(xí)筆記目錄------->傳送門(mén)

前言

休息了一天,雨天去了一次頤和園社证,不幸逼龟,我感冒了。所以追葡,如果本文有任何常識(shí)性問(wèn)題腺律,請(qǐng)不要懷疑作者的知識(shí)水平,而是腦子有點(diǎn)燒糊涂了宜肉。前面我們描述完了sift以及surf算法匀钧,本片我們描述一下orb特征檢測(cè)算法。

今天一看谬返,竟然已經(jīng)寫(xiě)了15篇文章了之斯,也為自己的堅(jiān)持點(diǎn)個(gè)贊 ~ (≧▽≦)/ ~ 。的的確確這段時(shí)間遣铝,對(duì)一些算法的理解也有了更深的層次佑刷,再接再厲莉擒,今晚獎(jiǎng)勵(lì)給我家貓獎(jiǎng)勵(lì)一罐小魚(yú)干。

ORB簡(jiǎn)介

ORB 全稱(chēng):Oriented FAST and Rotated BRIEF瘫絮,是一種快速特征點(diǎn)提取和描述的算法涨冀,發(fā)布于“ORB:An Efficient Alternative to SIFT or SURF” 論文中。從名字中麦萤,我們可以看出是由兩部分構(gòu)成鹿鳖,Oriented FAST 和 Rotated BRIEF,這也以最簡(jiǎn)單的語(yǔ)言描述了ORB算法壮莹。ORB算法分為兩部分翅帜,分別是特征點(diǎn)提取和特征點(diǎn)描述。特征提取是由FAST算法(前面已經(jīng)學(xué)過(guò))發(fā)展來(lái)的命满,特征點(diǎn)描述是根據(jù)BRIEF特征描述算法改進(jìn)的涝滴。

ORB算法最大的特點(diǎn)就是計(jì)算速度快,計(jì)算時(shí)間大概只有SIFT的1%周荐,SURF的10%狭莱,這主要是因?yàn)槭褂昧薋AST來(lái)加速了特征點(diǎn)的提取。再次是使用BRIEF算法計(jì)算描述子概作,該描述子特有的2進(jìn)制串的表現(xiàn)形式不僅節(jié)約了存儲(chǔ)空間腋妙,而且大大縮短了匹配的時(shí)間。

當(dāng)然ORB算法也有一些缺點(diǎn)讯榕,比如尺度變換的應(yīng)對(duì)能力比較低骤素。接下來(lái)我們來(lái)看ORB的流程,來(lái)分析一下ORB特征提取的優(yōu)缺點(diǎn)愚屁。

ORB 算法流程

1. 關(guān)鍵點(diǎn)提取

有關(guān)FAST算法济竹,可以跳轉(zhuǎn)去看另一篇來(lái)詳細(xì)描述FAST特征點(diǎn)的筆記:FAST角點(diǎn)學(xué)習(xí)筆記中查看。本節(jié)主要描述ORB算法中對(duì)FAST算法的改進(jìn)霎槐。

ORB對(duì)FAST的改進(jìn)或者拓展送浊,主要是為其增加了其尺度不變性以及旋轉(zhuǎn)不變性。接下里來(lái)看一看怎么實(shí)現(xiàn)的丘跌。

1. 提取FAST特征點(diǎn)

通過(guò)FAST算法提取出FAST特征點(diǎn)袭景,過(guò)程不在詳細(xì)描述,這樣我們就找到了一張圖片的基本的關(guān)鍵點(diǎn)闭树。

2. 建立金字塔

ORB實(shí)現(xiàn)尺度不變性耸棒,也是通過(guò)圖像金字塔來(lái)實(shí)現(xiàn)的。ORB論文本身并沒(méi)有解決尺度不變性报辱,而是在opencv實(shí)現(xiàn)中添加了這部分与殃,具體做法為設(shè)置一個(gè)比例因子scale(opencv默認(rèn)取1.2)和金字塔的層數(shù)n(通常取8)。將原圖像按比例因子縮小成n幅圖像》郏縮放后的圖像為:I’= I / scale^k (k=1,2,…, n)米奸。n幅不同比例的圖像提取特征點(diǎn)總和作為這幅圖像的FAST特征點(diǎn)。

當(dāng)然可以通過(guò)采用不同的高斯核進(jìn)行高斯模糊來(lái)建立金字塔衣屏,但是時(shí)間成本就很高了躏升。

3. 定義特征點(diǎn)方向

ORB實(shí)現(xiàn)旋轉(zhuǎn)不變性辩棒,也是通過(guò)確定一個(gè)特征點(diǎn)的方向來(lái)實(shí)現(xiàn)的狼忱,我們來(lái)看看ORB是怎么來(lái)確定特征點(diǎn)的方向的?

ORB的論文中提出了一種利用灰度質(zhì)心法來(lái)解決這個(gè)問(wèn)題一睁,通過(guò)計(jì)算一個(gè)矩來(lái)計(jì)算特征點(diǎn)以r為半徑范圍內(nèi)的質(zhì)心钻弄,特征點(diǎn)坐標(biāo)到質(zhì)心形成一個(gè)向量作為該特征點(diǎn)的方向。我們來(lái)看看具體怎么實(shí)現(xiàn)灰度質(zhì)心法者吁。

一個(gè)圖像塊(比如5x5的圖像塊中)窘俺,對(duì)應(yīng)的2x2的矩的元素表達(dá)為:

x,y分別為坐標(biāo)值复凳,I(x瘤泪,y)為像素值

而該圖像窗口的質(zhì)心就是:

其實(shí)灰度的質(zhì)心就是對(duì)所有的位置進(jìn)行加權(quán),權(quán)重就是像素值在整個(gè)圖像中像素值之和的比例育八。

那么特征點(diǎn)與質(zhì)心的夾角定義為FAST特征點(diǎn)的方向:

也就有了特征點(diǎn)的方向对途,繼而實(shí)現(xiàn)旋轉(zhuǎn)不變性。

通過(guò)上述步驟我們找到了所有的特征點(diǎn)髓棋,并計(jì)算出了特征點(diǎn)的方向实檀,下面就看一下怎么描述這些特征點(diǎn)。

2. 關(guān)鍵點(diǎn)描述

ORB選擇了BRIEF作為特征描述方法按声,并對(duì)其進(jìn)行改進(jìn)使其加上旋轉(zhuǎn)不變性并增加其可區(qū)分性膳犹,首先我們先看看BRIEF描述子。

  • BRIEF描述子

BRIEF算法計(jì)算出來(lái)的是一個(gè)二進(jìn)制串的特征描述符签则。它是在每一個(gè)特征點(diǎn)的鄰域內(nèi)须床,選擇n對(duì)像素點(diǎn)pi、qi(i=1,2,…,n)渐裂。然后比較每個(gè)點(diǎn)對(duì)的灰度值的大小豺旬。如果I(pi)> I(qi),則生成二進(jìn)制串中的1芯义,否則為0哈垢。所有的點(diǎn)對(duì)都進(jìn)行比較,則生成長(zhǎng)度為n的二進(jìn)制串扛拨。一般n取128耘分、256或512,通常取256。

為了增強(qiáng)抗噪性求泰,一般會(huì)先對(duì)圖像進(jìn)行高斯平滑央渣。ORB算子采用5x5的子窗口進(jìn)行平滑。

那么這n個(gè)點(diǎn)對(duì)如何選取呢?
在點(diǎn)周?chē)x取點(diǎn)對(duì)(p,q)的方法有以下5種:

  1. 在圖像塊內(nèi)平均采樣渴频;
  2. p和q都符合(0,S2/25)的高斯分布芽丹;
  3. p符合(0,S2/25)的高斯分布,而q符合(0,S2/100)的高斯分布卜朗;
  4. 在空間量化極坐標(biāo)下的離散位置隨機(jī)采樣拔第;
  5. 把p固定為(0,0),q在周?chē)骄蓸印?/li>

BRIEF作者采用的是第二種场钉。而ORB作者沒(méi)有選擇以上任意方式蚊俺,而是一種新的方式,我們?cè)谙旅嬖僬f(shuō)逛万。

BRIEF流程簡(jiǎn)單實(shí)時(shí)性較好泳猬,論文中生成512個(gè)描述子用時(shí)8.18ms,并且其描述子是二進(jìn)制碼宇植,其匹配也比較快得封。但是,當(dāng)BRIEF對(duì)于旋轉(zhuǎn)過(guò)大時(shí)指郁,比如超過(guò)30度時(shí)忙上,匹配正確率迅速下降直到45度時(shí)為0。所以需要增加其描述子的旋轉(zhuǎn)不變性坡氯。

  • BRIEF算法改進(jìn)

在描述基礎(chǔ)BRIEF算法時(shí)晨横,我們提出了兩個(gè)問(wèn)題,一個(gè)是增加其旋轉(zhuǎn)不變性箫柳,一個(gè)是選點(diǎn)方式手形。

  • steered BRIEF 增加其旋轉(zhuǎn)不變性

所謂steered BRIEF 就是對(duì)挑選出的點(diǎn)對(duì)加上一個(gè)旋轉(zhuǎn)角度θ。對(duì)于任何一個(gè)特征點(diǎn)來(lái)說(shuō)悯恍,它的BRIEF描述子是一個(gè)長(zhǎng)度為??的二值碼串库糠,這個(gè)二值碼串是由特征點(diǎn)鄰域??個(gè)點(diǎn)對(duì)生成的,我們現(xiàn)在講這2??個(gè)點(diǎn)(????,????),??=1,2,.....,2??組成一個(gè)矩陣??:

使用鄰域方向??和對(duì)應(yīng)的旋轉(zhuǎn)矩陣????涮毫,構(gòu)建??的一個(gè)校正版本????:

其中

即我們把坐標(biāo)軸旋轉(zhuǎn)]?????????瞬欧,計(jì)算以主方向?yàn)樽鴺?biāo)系的匹配點(diǎn)對(duì),如下圖:

steered BRIEF加入了旋轉(zhuǎn)不變性罢防,但同時(shí)特征描述量的可區(qū)分行就下降了,所以就有了ORB作者提出的rBRIEF艘虎。

  • rBRIEF 增加其可區(qū)分性

我們?cè)谏线呎f(shuō)過(guò)ORB沒(méi)有使用BRIEF 5種選取點(diǎn)對(duì)方法中的任意一種,那么ORB用的是什么方式咒吐?
ORB使用統(tǒng)計(jì)學(xué)習(xí)的方法來(lái)重新選擇點(diǎn)對(duì)集合野建,目的是增大其特征描述量的可區(qū)分行属划。這里我們先不解釋其具體的實(shí)驗(yàn)流程(主要是我還沒(méi)有完全理解),但是通過(guò)其實(shí)驗(yàn)候生,選出來(lái)的點(diǎn)對(duì)對(duì)特征點(diǎn)描述的區(qū)分度變高了同眯。

至此ORB算法計(jì)算完畢。

OpenCV ORB特征效果展示[代碼]

#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/features2d/features2d.hpp>
void extracte_orb(cv::Mat input,std::vector<cv::KeyPoint> &keypoint,cv::Mat &descriptor){
    cv::Ptr<cv::ORB> f2d = cv::ORB::create(500);
    f2d->detect(input,keypoint);
    cv::Mat image_with_kp;
    f2d->compute(input,keypoint,descriptor);
    cv::drawKeypoints(input, keypoint, image_with_kp, cv::Scalar::all(-1),cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    cv::imwrite("orb"+std::to_string(random())+".png",image_with_kp);
}

void match_two_image(cv::Mat image1,cv::Mat image2, std::vector<cv::KeyPoint> keypoint1,std::vector<cv::KeyPoint> keypoint2,cv::Mat descriptor1,cv::Mat descriptor2){
    cv::BFMatcher matcher(cv::NORM_HAMMING);
    std::vector<cv::DMatch> matches;
    matcher.match(descriptor1,descriptor2, matches);
    cv::Mat good_matches_image;
    cv::drawMatches(image1, keypoint1, image2, keypoint2,
                    matches, good_matches_image, cv::Scalar::all(-1), cv::Scalar::all(-1),
                    std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    cv::imwrite("good_matches_image.png",good_matches_image);
    {
        std::vector <cv::KeyPoint> RAN_KP1, RAN_KP2;
        std::vector<cv::Point2f> keypoints1, keypoints2;
        for (int i = 0; i < matches.size(); i++) {
            keypoints1.push_back(keypoint1[matches[i].queryIdx].pt);
            keypoints2.push_back(keypoint2[matches[i].trainIdx].pt);
            RAN_KP1.push_back(keypoint1[matches[i].queryIdx]);
            RAN_KP2.push_back(keypoint2[matches[i].trainIdx]);
        }

        std::vector<uchar> RansacStatus;
        cv::findFundamentalMat(keypoints1, keypoints2, RansacStatus, cv::FM_RANSAC);
        std::vector <cv::KeyPoint> ransac_keypoints1, ransac_keypoints2;
        std::vector <cv::DMatch> ransac_matches;
        int index = 0;
        for (size_t i = 0; i < matches.size(); i++)
        {
            if (RansacStatus[i] != 0)
            {
                ransac_keypoints1.push_back(RAN_KP1[i]);
                ransac_keypoints2.push_back(RAN_KP2[i]);
                matches[i].queryIdx = index;
                matches[i].trainIdx = index;
                ransac_matches.push_back(matches[i]);
                index++;
            }
        }
        cv::Mat after_ransac_sift_match;
        cv::drawMatches(image1, ransac_keypoints1, image2, ransac_keypoints2,
                        ransac_matches, after_ransac_sift_match, cv::Scalar::all(-1), cv::Scalar::all(-1),
                        std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
        cv::imwrite("after_ransac_orb_match.png",after_ransac_sift_match);
    }
}

int main(int argc, char *argv[])
{
    cv::Mat image1 = cv::imread(argv[1]);
    cv::Mat image2 = cv::imread(argv[2]);
    std::vector<cv::KeyPoint> keypoint1,keypoint2;
    cv::Mat descriptor1, descriptor2;
    extracte_orb(image1,keypoint1,descriptor1);
    extracte_orb(image2,keypoint2,descriptor2);
    match_two_image(image1,image2,keypoint1,keypoint2,descriptor1,descriptor2);
    return 0;
}

因?yàn)閛rb難以應(yīng)對(duì)我們類(lèi)似SIFT或surf那么大的仿射變換唯鸭,所以不得不換了仿射變換小的照片

原圖1 orb識(shí)別效果 原圖2 orb識(shí)別效果
初步匹配效果 ransac后匹配效果

總結(jié)

總體來(lái)說(shuō)ORB在上述實(shí)驗(yàn)實(shí)例中的效果還是很好的须蜗。我們已經(jīng)講完SIFT,SURF還有ORB目溉,我們來(lái)對(duì)比一下這三個(gè)算法明肮。
計(jì)算速度: ORB>>SURF>>SIFT(各差一個(gè)量級(jí))
旋轉(zhuǎn)魯棒性: SURF>ORB~SIFT(~表示差不多)
模糊魯棒性: SURF>ORB~SIFT
尺度變換魯棒性: SURF>SIFT>ORB(ORB尺度變換性很弱)
在日常應(yīng)用中,有SURF基本就不用考慮SIFT停做,SURF基本就是SIFT的全面升級(jí)版晤愧,當(dāng)然也有其他SIFT的改進(jìn)版比如Affine SIFT的效果就要比SUFR要好更多大莫,但是計(jì)算時(shí)間也有延長(zhǎng)蛉腌,而ORB的強(qiáng)點(diǎn)在于計(jì)算時(shí)間。ORB主要還是在VSLAM中應(yīng)用較多只厘,場(chǎng)景變化不明顯烙丛,但是需要高速的計(jì)算時(shí)間,這正好符合ORB羔味。

特征點(diǎn)到此結(jié)束河咽,繼續(xù)加油

重要的事情說(shuō)三遍:

如果我的文章對(duì)您有所幫助,那就點(diǎn)贊加個(gè)關(guān)注唄 ( * ^ __ ^ * )

如果我的文章對(duì)您有所幫助赋元,那就點(diǎn)贊加個(gè)關(guān)注唄 ( * ^ __ ^ * )

如果我的文章對(duì)您有所幫助忘蟹,那就點(diǎn)贊加個(gè)關(guān)注唄 ( * ^ __ ^ * )

傳統(tǒng)2D計(jì)算機(jī)視覺(jué)學(xué)習(xí)筆記目錄------->傳送門(mén)
傳統(tǒng)3D計(jì)算機(jī)視覺(jué)學(xué)習(xí)筆記目錄------->傳送門(mén)

任何人或團(tuán)體、機(jī)構(gòu)全部轉(zhuǎn)載或者部分轉(zhuǎn)載搁凸、摘錄媚值,請(qǐng)保留本博客鏈接或標(biāo)注來(lái)源。博客地址:開(kāi)飛機(jī)的喬巴

作者簡(jiǎn)介:開(kāi)飛機(jī)的喬巴(WeChat:zhangzheng-thu)护糖,現(xiàn)主要從事機(jī)器人抓取視覺(jué)系統(tǒng)以及三維重建等3D視覺(jué)相關(guān)方面褥芒,另外對(duì)slam以及深度學(xué)習(xí)技術(shù)也頗感興趣,歡迎加我微信或留言交流相關(guān)工作嫡良。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锰扶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子寝受,更是在濱河造成了極大的恐慌坷牛,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件很澄,死亡現(xiàn)場(chǎng)離奇詭異京闰,居然都是意外死亡锨亏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)忙干,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)器予,“玉大人,你說(shuō)我怎么就攤上這事捐迫∏瑁” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵施戴,是天一觀的道長(zhǎng)反浓。 經(jīng)常有香客問(wèn)我,道長(zhǎng)赞哗,這世上最難降的妖魔是什么雷则? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮肪笋,結(jié)果婚禮上月劈,老公的妹妹穿的比我還像新娘。我一直安慰自己藤乙,他們只是感情好猜揪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著坛梁,像睡著了一般而姐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上划咐,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天拴念,我揣著相機(jī)與錄音,去河邊找鬼褐缠。 笑死政鼠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的送丰。 我是一名探鬼主播缔俄,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼器躏!你這毒婦竟也來(lái)了俐载?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤登失,失蹤者是張志新(化名)和其女友劉穎遏佣,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體揽浙,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡状婶,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年意敛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膛虫。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡草姻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出稍刀,到底是詐尸還是另有隱情撩独,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布账月,位于F島的核電站综膀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏局齿。R本人自食惡果不足惜剧劝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抓歼。 院中可真熱鬧讥此,春花似錦、人聲如沸锭部。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拌禾。三九已至,卻和暖如春展哭,著一層夾襖步出監(jiān)牢的瞬間湃窍,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工匪傍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留您市,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓役衡,卻偏偏與公主長(zhǎng)得像茵休,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子手蝎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容