理論
我們看到了一些特征檢測算法,他們很多都不錯(cuò),但是從實(shí)時(shí)應(yīng)用的角度看,他們都不夠快,一個(gè)最好的例子是SLAM(同步定位與地圖創(chuàng)建)移動(dòng)機(jī)器人沒有足夠的計(jì)算能力。
作為解決方案,F(xiàn)AST(加速切片測試特征)算法被提出,Edward Rosten和Tom Drummond 2006年在他們的論文“Machine learning for high-speed corner detection”提出,并在2010年最后修訂,算法的基本大意如下:
使用FAST進(jìn)行特征檢測
1.選擇一個(gè)圖像里的像素p用來識(shí)別是不是一個(gè)興趣點(diǎn),它的強(qiáng)度是Ip
2.選擇一個(gè)合適的閾值t
3.在要測試的像素周圍找16個(gè)像素的圓
4.現(xiàn)在如果存在一個(gè)在圓內(nèi)(16像素的)的n個(gè)連續(xù)像素集合,他們都比Ip + t要亮,或者都比Ip - t 要暗(用白虛線顯示),那p就是角, n取12。
5.用一個(gè)高速測試來排除大量非角。這個(gè)測試只檢查1,9,5和13位置的像素(首先1和9會(huì)測試是否他們太亮或者太暗,如果是,再檢查5和13)。如果p是角,那么至少3個(gè)都比Ip+t要亮或者比Ip-t要暗,如果不是這樣,那么p不可能是角。這個(gè)檢測器展現(xiàn)了高性能,但是有幾個(gè)缺陷:
·當(dāng)n< 12時(shí)不能拒絕很多備選點(diǎn)
·像素的選擇不是可選的,因?yàn)樗男室蕾噯栴}和角的分布。
·高速測試的結(jié)果被丟棄了
·會(huì)檢測出多個(gè)愛挨在一起的特征
機(jī)器學(xué)習(xí)角點(diǎn)檢測
1.選擇一組圖像進(jìn)行訓(xùn)練(最好從目標(biāo)應(yīng)用范圍內(nèi))
2.運(yùn)行FAST算法來對(duì)每個(gè)圖像進(jìn)行特征點(diǎn)查找
3.對(duì)每個(gè)特征點(diǎn),存下周圍的16個(gè)像素作為向量。所有圖像做完以后得到特征向量P。
4.這16個(gè)像素里的每個(gè)像素(設(shè)為x)可以有下面的三個(gè)狀態(tài):
5.根據(jù)這些狀態(tài),特征向量P被分成3個(gè)子集,Pd, Ps, Pb.
6.定義個(gè)新的布爾變量Kp,如果p是角就是真反之為假。
7.使用ID3算法(決策樹分類)來查詢每個(gè)子集,對(duì)于每個(gè)true類用變量Kp,它選擇x來得出一個(gè)備選像素是否是角的信息。
8.對(duì)所有子集迭代直到為0
9.創(chuàng)建的決策樹用來對(duì)其他圖形做fast檢測
非極大值抑制
在臨近位置檢測多個(gè)興趣點(diǎn)是另一個(gè)問題,可以使用非極大值抑制來解決。
1.計(jì)算一個(gè)分?jǐn)?shù)函數(shù),V是所有檢測到的特征點(diǎn),V是p和16個(gè)圍著的像素值得絕對(duì)差。
2.計(jì)算兩個(gè)相鄰關(guān)鍵點(diǎn)的V值
3.丟掉V值低的那個(gè)
總結(jié):
它比其他存在的角點(diǎn)算法要快幾倍
但是它對(duì)高噪點(diǎn)情況來說不健壯,依賴閾值
OpenCV里的FAST特征檢測
它和其他OpenCV里的特征檢測類似,如果你愿意,你可以指定閾值,是否使用非極大值抑制,要用的鄰居等。
對(duì)于鄰居,定義了三個(gè)標(biāo)志位, cv2.FAST_FEATURE_DETECTOR_TYPE_5_8, cv2.FAST_FEATURE_DETECTOR_TYPE_7_12和cv2.FAST_FEATURE_DETECTOR_TYPE_9_16.
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('simple.jpg',0)
# Initiate FAST object with default values
fast = cv2.FastFeatureDetector()# find and draw the keypoints
kp = fast.detect(img,None)
img2 = cv2.drawKeypoints(img, kp, color=(255,0,0))# Print all default params
print "Threshold: ", fast.getInt('threshold')
print "nonmaxSuppression: ", fast.getBool('nonmaxSuppression')
print "neighborhood: ", fast.getInt('type')
print "Total Keypoints with nonmaxSuppression: ", len(kp)cv2.imwrite('fast_true.png',img2)
# Disable nonmaxSuppression
fast.setBool('nonmaxSuppression',0)
kp = fast.detect(img,None)print "Total Keypoints without nonmaxSuppression: ", len(kp)
img3 = cv2.drawKeypoints(img, kp, color=(255,0,0))
cv2.imwrite('fast_false.png',img3)
看結(jié)果,第一個(gè)圖像顯示了使用了非極大值抑制的FAST,第二個(gè)是沒有使用非極大值抑制的。
END