OpenCV-Python系列之BRIEF演算法
之前討論過的SIFT演算法以及SURF演算法由於受到了專利的保護,在高版本的OpenCV中是沒法使用的,這就有些強人所難了,但今天我們介紹一種演算法,不僅更加簡單,而且是免費使用的。
原理
在SIFT演算法使用128維的描述符,因為使用float型別描述,所以需要512位元組的記憶體。
在SURF演算法中,以64維描述符來計算,至少需要256位元組的記憶體。
在建立一個含有數千個特徵的向量會消耗大量的記憶體,這種情況在資源的有限的裝置上不實用,尤其是嵌入式裝置。 此外,它們計算時間也非常漫長。
但是在實際的匹配過程中,不是所有的維數都需要。我們可以使用一些方法來對維數進行壓縮,例如PCA(主成分分析)演算法,和LDA(線性判別式分析)演算法等等。甚至使用LSH(區域性敏感雜湊)演算法,把SIFT的描述符從浮點數型別轉化成二進位制字串,然後對這些字串使用漢明距離來進行匹配。由於韓明距離的計算方法只需要使用亦或位運算和位計數,在帶有SSE指令的現代的CPU上計算速度很快。
BRIEF演算法由此產生,該演算法提供了一個很簡介的手段在不尋找描述符的情況下,去尋找二進位制字串。
大致過程如下:
1、為減少噪聲干擾,先對影象進行高斯濾波(方差為2,高斯視窗為9x9)
2、以特徵點為中心,取SxS的鄰域大視窗。在大視窗中隨機選取一對(兩個)5x5的子視窗,比較子視窗內的畫素和(可用積分影象完成),進行二進位制賦值.(一般S=31)
其中,p(x),p(y)分別隨機點x=(u1,v1),y=(u2,v2)所在5x5子視窗的畫素和.
3、在大視窗中隨機選取N對子視窗,重複步驟2的二進位制賦值,形成一個二進位制編碼,這個編碼就是對特徵點的描述,即特徵描述子.(一般N=256)
非常重要的一點是:BRIEF 是一種特徵描述符,它不提供查詢特徵的方法。所以我們不得不使用其他特徵檢測器,比如 SIFT 和 SURF 等。原始文獻推薦使用 CenSurE 特徵檢測器,這種演算法很快。而且 BRIEF 演算法對 CenSurE關鍵點的描述效果要比 SURF 關鍵點的描述更好。
簡單來說 BRIEF 是一種對特徵點描述符計算和匹配的快速方法。這種演算法可以實現很高的識別率,除非出現平面內的大旋轉。
接下來我們來進行程式碼演示,使用示例圖片:
首先建立BRIEF描述符:
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create(, bytes, use_orientation)
bytes:描述符中的值,用位元組表示可取16, 32 (default) or 64,代表的值為 128,256,512
use_orientation:使用特徵點方向的示例模式,預設情況下禁用。
建立 CenSurE 特徵檢測器(在OpenCV中稱為STAR檢測器):
star = cv2.xfeatures2d.StarDetector_create(, maxSize, responseThreshold, lineThresholdProjected, lineThresholdBinarized, suppressNonmaxSize)
maxSize:最大尺寸,預設45
responseThreshold:響應閾值,預設30
lineThresholdProjected:線性投影閾值,預設10
lineThresholdBinarized:線性二值化閾值,預設8
suppressNonmaxSize:非極大抑制引數,預設5
計算在影象中檢測到的一組特徵點的描述符:
kp, des = brief.compute(img, kp)
image:輸入影象
kp:輸入特徵點集合。無法計算描述符的特徵點將被刪除。有時可以新增新的特徵點,例如:SIFT具有多個主導方向的重複特徵點(對於每個方向)。
des:輸出計算後的描述符,是一個矩陣。
def BRIEF(img): # Initiate FAST detector star = cv2.xfeatures2d.StarDetector_create() # Initiate BRIEF extractor brief = cv2.xfeatures2d.BriefDescriptorExtractor_create() # find the keypoints with STAR kp = star.detect(img, None) # compute the descriptors with BRIEF kp, des = brief.compute(img, kp) print(brief.descriptorSize()) print(des.shape) # draw only keypoints location,not size and orientation img2 = cv2.drawKeypoints(img, kp, None, color=(0, 255, 0), flags=0) plt.imshow(img2), plt.show()
結果:
進而看輸出結果:
事實上,BRIEF雖然免費,不過由於其本身並不具有特徵檢測的功能,並且BRIEF的描述符在旋轉的影象下表現很差勁,所以在之後我們將會介紹更加強大的同時速度更快的演算法。
天道酬勤 循序漸進 技壓群雄