更新時間:2021-07-27 來源:黑馬程序員 瀏覽量:
我們前面已經(jīng)介紹過幾個特征檢測器,它們的效果都很好,特別是SIFT和SURF算法,但是從實時處理的角度來看,效率還是太低了。為了解決這個問題,Edward Rosten和Tom Drummond在2006年提出了FAST算法,并在2010年對其進行了修正。
FAST (全稱Features from accelerated segment test)是一種用于角點檢測的算法,該算法的原理是取圖像中檢測點,以該點為圓心的周圍鄰域內(nèi)像素點判斷檢測點是否為角點,通俗的講就是若一個像素周圍有一定數(shù)量的像素與該點像素值不同,則認為其為角點。
在圖像中選取一個像素點 p,來判斷它是不是關(guān)鍵點。$$I_p$$等于像素點 p的灰度值。
以r為半徑畫圓,覆蓋p點周圍的M個像素,通常情狂下,設(shè)置 r=3,則 M=16,如下圖所示:
設(shè)置一個閾值t,如果在這 16 個像素點中存在 n 個連續(xù)像素點的灰度值都高于$$I_p + t$$,或者低于$$I_p - t$$,那么像素點 p 就被認為是一個角點。如上圖中的虛線所示,n 一般取值為 12。
由于在檢測特征點時是需要對圖像中所有的像素點進行檢測,然而圖像中的絕大多數(shù)點都不是特征點,如果對每個像素點都進行上述的檢測過程,那顯然會浪費許多時間,因此采用一種進行非特征點判別的方法:首先對候選點的周圍每個 90 度的點:1,9,5,13 進行測試(先測試 1 和 19, 如果它們符合閾值要求再測試 5 和 13)。如果 p 是角點,那么這四個點中至少有 3 個要符合閾值要求,否則直接剔除。對保留下來的點再繼續(xù)進行測試(是否有 12 的點符合閾值要求)。
雖然這個檢測器的效率很高,但它有以下幾條缺點:
·獲得的候選點比較多
·特征點的選取不是最優(yōu)的,因為它的效果取決與要解決的問題和角點的分布情況。
·進行非特征點判別時大量的點被丟棄
·檢測到的很多特征點都是相鄰的
前 3 個問題可以通過機器學(xué)習(xí)的方法解決,最后一個問題可以使用非最大值抑制的方法解決。
選擇一組訓(xùn)練圖片(最好是跟最后應(yīng)用相關(guān)的圖片)
使用 FAST 算法找出每幅圖像的特征點,對圖像中的每一個特征點,將其周圍的 16 個像素存儲構(gòu)成一個向量P。
每一個特征點的 16 像素點都屬于下列三類中的一種
根據(jù)這些像素點的分類,特征向量 P 也被分為 3 個子集:Pd ,Ps ,Pb,
定義一個新的布爾變量$$K_p$$,如果 p 是角點就設(shè)置為 Ture,如果不是就設(shè)置為 False。
利用特征值向量p,目標(biāo)值是$K_p$,訓(xùn)練ID3 樹(決策樹分類器)。
將構(gòu)建好的決策樹運用于其他圖像的快速的檢測。
在篩選出來的候選角點中有很多是緊挨在一起的,需要通過非極大值抑制來消除這種影響。
為所有的候選角點都確定一個打分函數(shù)$$V $$ , $$V $$的值可這樣計算:先分別計算$$I_p$$與圓上16個點的像素值差值,取絕對值,再將這16個絕對值相加,就得到了$$V $$的值
最后比較毗鄰候選角點的 V 值,把V值較小的候選角點pass掉。
FAST算法的思想與我們對角點的直觀認識非常接近,化繁為簡。FAST算法比其它角點的檢測算法快,但是在噪聲較高時不夠穩(wěn)定,這需要設(shè)置合適的閾值。
OpenCV中的FAST檢測算法是用傳統(tǒng)方法實現(xiàn)的,
1.實例化fast
fast = =cv.FastFeatureDetector_create( threshold, nonmaxSuppression)
參數(shù):
·threshold:閾值t,有默認值10
·nonmaxSuppression:是否進行非極大值抑制,默認值True
返回:
Fast:創(chuàng)建的FastFeatureDetector對象
2.利用fast.detect檢測關(guān)鍵點,沒有對應(yīng)的關(guān)鍵點描述
kp = fast.detect(grayImg, None)
參數(shù):
gray: 進行關(guān)鍵點檢測的圖像,注意是灰度圖像
返回:
kp: 關(guān)鍵點信息,包括位置,尺度,方向信息
3.將關(guān)鍵點檢測結(jié)果繪制在圖像上,與在sift中是一樣的
cv.drawKeypoints(image, keypoints, outputimage, color, flags)
示例:
import numpy as np import cv2 as cv from matplotlib import pyplot as plt # 1 讀取圖像 img = cv.imread('./image/tv.jpg') # 2 Fast角點檢測 # 2.1 創(chuàng)建一個Fast對象,傳入閾值,注意:可以處理彩色空間圖像 fast = cv.FastFeatureDetector_create(threshold=30) # 2.2 檢測圖像上的關(guān)鍵點 kp = fast.detect(img,None) # 2.3 在圖像上繪制關(guān)鍵點 img2 = cv.drawKeypoints(img, kp, None, color=(0,0,255)) # 2.4 輸出默認參數(shù) print( "Threshold: {}".format(fast.getThreshold()) ) print( "nonmaxSuppression:{}".format(fast.getNonmaxSuppression()) ) print( "neighborhood: {}".format(fast.getType()) ) print( "Total Keypoints with nonmaxSuppression: {}".format(len(kp)) ) # 2.5 關(guān)閉非極大值抑制 fast.setNonmaxSuppression(0) kp = fast.detect(img,None) print( "Total Keypoints without nonmaxSuppression: {}".format(len(kp)) ) # 2.6 繪制為進行非極大值抑制的結(jié)果 img3 = cv.drawKeypoints(img, kp, None, color=(0,0,255)) # 3 繪制圖像 fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100) axes[0].imshow(img2[:,:,::-1]) axes[0].set_title("加入非極大值抑制") axes[1].imshow(img3[:,:,::-1]) axes[1].set_title("未加入非極大值抑制") plt.show()
結(jié)果:
《圖像處理OpenCV入門教程》課程導(dǎo)讀
加QQ:2217622915,獲取《圖像處理OpenCV入門教程》全套視頻教程+筆記+源碼。
猜你喜歡: