勉強しないとな~blog

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

OpenCVやってみる-16. FASTアルゴリズムによる特徴点検出

前回の続き、FASTアルゴリズムを試します。

コーナー検出のためのFASTアルゴリズム — OpenCV-Python Tutorials 1 documentation

ざっくり理論

画像の各画素について、これを中心として周長16ピクセルになる円周(半径およそ3ピクセル) 上の画素を調べ、決まった数以上の連続した画素で中心輝度を上回っている、または下回っている、という状況であれば、そこをコーナーと判定するようです。

限られた計算資源でも高速にコーナー検出ができる、というのがメリットのよう。

高速テストというのがあり、まず円周上の4画素を調べて、コーナーの可能性がなければ 他の画素のチェックはしない、ということもやるようです。

機械学習(決定木)も使うように書かれていますが、OpenCVのライブラリでもやっているのか?
学習済みのものを使っているのか?

実践

前回までと同じ画像で試します。 f:id:nokixa:20210706090007p:plain

やってみたところ、SIFTのときと同様にcv2.FastFeatureDetector()ではなくcv2.FastFeatureDetector_create()を使わないといけませんでした。
ドキュメントのOpenCVのバージョンとは違いがあるのかと。 今見ているドキュメント自体も古くなっているようなので、次回からは更新されているチュートリアルも見ながら進めていこうかと思います。

OpenCV: OpenCV Tutorials

※8/15追記
上のチュートリアルはちょっと違う内容ですが、同じ内容のチュートリアルが別でちゃんとありました。

OpenCV: OpenCV-Python Tutorials

>>> fast = cv2.FastFeatureDetector()
>>> kp1 = fast.detect(img1, None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
cv2.error: Unknown C++ exception from OpenCV code
>>> fast = cv2.FastFeatureDetector_create()
>>> kp1 = fast.detect(img1, None)
>>> 

一応SIFTのときと同様に結果を一部確認。

>>> type(kp1)
<class 'list'>
>>> len(kp1)
3381
>>> type(kp1[0])
<class 'cv2.KeyPoint'>
>>> type(kp1[0].pt)
<class 'tuple'>
>>> kp1[0].pt
(75.0, 3.0)
>>> kp1[0].size
7.0
>>> kp1[0].angle
-1.0

特徴点について角度の情報はないということのよう。

特徴点を描画します。

img1_kp = cv2.drawKeypoints(img1, kp1, None, color=(255,0,0))
cv2.imshow('FAST Keypoints1', img1_kp)

f:id:nokixa:20210813082922p:plain

シールの境界が特徴点として認識されています。コーナー検出をするのが目的のアルゴリズムのようですが、この緩いカーブもコーナーとして認識されたということでいいのかな。

一応他の画像でもやっておきます。

kp2 = fast.detect(img2, None)
kp3 = fast.detect(img3, None)
img2_kp = cv2.drawKeypoints(img2, kp2, None, color=(255,0,0))
img3_kp = cv2.drawKeypoints(img3, kp3, None, color=(255,0,0))
import numpy as np
img123_kp = np.hstack((img1_kp, img2_kp, img3_kp))
cv2.imshow('FAST Keypoints', img123_kp)

f:id:nokixa:20210814005005p:plain

およそ同じような傾向。

以上

次はどうしようかな。