1. 程式人生 > 其它 >OpenCV-Python系列之BRIEF演算法

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的描述符在旋轉的影象下表現很差勁,所以在之後我們將會介紹更加強大的同時速度更快的演算法。

天道酬勤 循序漸進 技壓群雄