今回はBRIEFをやってみます。
OpenCV: BRIEF (Binary Robust Independent Elementary Features)
ざっくり理論
BRIEFは画像中の特徴点の特徴量を生成する方式のひとつです。
SIFTやSURFでは、特徴点の特徴量を表すのにそれなりに大きなデータ量(1点あたりSIFTで512byte、SURFで256byte)が必要になりますが、メモリサイズが大きくなるし、特徴点同士の比較演算も重くなる。
チュートリアルサイトの説明を読むと、「平滑化した画像パッチ」というのが書かれていますが、
注目する特徴点近傍の画素の集まり、という解釈でいいのかな。
特徴点近傍画素の中の個の画素ペアについて、ペア内で輝度値を比較、比較結果に0、1を割り当ててビットのビット列を作り、これを特徴量とするようです。
CPUのビットXORとビットカウントの命令を使用すると、この特徴量の比較は高速でできると。
の値はOpenCVでは128、256、512がサポートされていて、1特徴点あたりの特徴量データはそれぞれ16byte、32byte、64byteとなります。
BRIEF自体は特徴点を検出するものではないので、SIFT、SURFなど何らかのアルゴリズムで特徴点を検出したのち、BRIEFで特徴量データを生成する、という流れになります。
ただ、BRIEFでは特徴点検出器としてはCenSurE(およびその派生版のSTAR)というのが推奨されているようです。
実践
今回はどんな特徴量データができるか確認するだけで、特に画像に重畳して表示したりすることはありません。なので、画像1つだけ使います。
import cv2 img1 = cv2.imread('harupan_200317_1.jpg') img1 = cv2.resize(img1, None, fx=0.1, fy=0.1, interpolation=cv2.INTER_AREA)
チュートリアルでは検出器としてSTARを使っています。
SIFTのときはグレースケール化してから検出器に入れていましたが、STARではカラー画像のままでいいよう。
なお、BRIEFを使うにはopencv contribがインストールされている必要があります。
star = cv2.xfeatures2d.StarDetector_create()
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()
img1_kp = star.detect(img1, None)
img1_kp, img1_des = brief.compute(img1, img1_kp)
結果を確認してみます。
>>> type(img1_kp) <class 'list'> >>> len(img1_kp) 382 >>> type(img1_kp[0]) <class 'cv2.KeyPoint'> >>> type(img1_des) <class 'numpy.ndarray'> >>> img1_des.shape (382, 32) >>> img1_des[0,:] array([ 27, 6, 248, 207, 179, 146, 86, 189, 164, 209, 146, 20, 219, 106, 219, 41, 167, 228, 70, 140, 253, 240, 112, 60, 68, 148, 229, 195, 126, 80, 65, 250], dtype=uint8)
- BRIEFでの特徴量データはndarrayとして出てくる
- 特徴量データの形状は(特徴点数, 32)、データ型はuint8となる
- デフォルトではは256なので、1特徴量あたり32byte
以上
特徴点のマッチングをまだやっていないので、今回の結果がどうなのかまだちゃんと評価できず。
次回はチュートリアル通りORBでの特徴点検出、特徴量記述で。