勉強しないとな~blog

ちゃんと勉強せねば…な電気設計エンジニアです。

OpenCVやってみる-17. BRIEF

今回はBRIEFをやってみます。

OpenCV: BRIEF (Binary Robust Independent Elementary Features)

ざっくり理論

BRIEFは画像中の特徴点の特徴量を生成する方式のひとつです。

SIFTやSURFでは、特徴点の特徴量を表すのにそれなりに大きなデータ量(1点あたりSIFTで512byte、SURFで256byte)が必要になりますが、メモリサイズが大きくなるし、特徴点同士の比較演算も重くなる。

チュートリアルサイトの説明を読むと、「平滑化した画像パッチ」というのが書かれていますが、 注目する特徴点近傍の画素の集まり、という解釈でいいのかな。
特徴点近傍画素の中のn_d個の画素ペアについて、ペア内で輝度値を比較、比較結果に0、1を割り当ててn_dビットのビット列を作り、これを特徴量とするようです。

CPUのビットXORとビットカウントの命令を使用すると、この特徴量の比較は高速でできると。

n_dの値は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となる
    • デフォルトではn_dは256なので、1特徴量あたり32byte

以上

特徴点のマッチングをまだやっていないので、今回の結果がどうなのかまだちゃんと評価できず。

次回はチュートリアル通りORBでの特徴点検出、特徴量記述で。