Python OpenCV3.1 で特徴量マッチング
Python + OpenCV3.1 で 特徴量を検出しての画像マッチングを試してみました。
使用した検出方法は A-KAZE、KNN です。
A-KAZE(ACCELERATED-KAZE)は、有名な SURF や SHIFT と同様の検出アルゴリズムです。
SURF や SHIFT は著作権の関係で OpenCV では contrib ライブラリ行きになってしまっていますが、A-KAZE は core ライブラリから使用できます。
KNN(K-Nearest Neighbor algorithm)は、参考にした記事によると探索空間から最近傍のラベルをK個選択し、多数決でクラスラベルを割り当てるアルゴリズムだそうです。
二通りの探索方法、総当たり法(Brute-Force)と高速近似近傍探索法(FLANN: Fast Library for Approximate Nearest Neighbors)がありますが、今回は BFM で探索しています。
FLANN も試してみたのですが、僕の環境では cv2.error: /tmp/opencv3-20160705-3167-qqbjck/opencv-3.1.0/modules/python/src2/cv2.cpp:163: error: (-215) The data should normally be NULL! in function allocate とでて実行できませんでした。(参考にした記事でも実行できなかったようです…)
下記が今回試したテストコードです。
# coding: utf-8
import cv2
import numpy as np
# 比較元の画像
img1 = cv2.imread("test.jpg")
# A-KAZE検出器の生成
akaze = cv2.AKAZE_create()
# カメラ
cap = cv2.VideoCapture(0)
cap.set(3, 640)
cap.set(4,480)
cap.set(5, 15)
# detect
def detect():
while(cap.isOpened()):
ret, frame = cap.read()
# 特徴量の検出と特徴量ベクトルの計算
kp1, des1 = akaze.detectAndCompute(img1, None)
kp2, des2 = akaze.detectAndCompute(frame, None)
# BFM 生成
bf = cv2.BFMatcher()
# 特徴量ベクトル同士を BFM&KNN でマッチング
matches = bf.knnMatch(des1, des2, k=2)
# 全部だと激重になるのでデータを間引きする
ratio = 0.6
good = []
for m, n in matches:
if m.distance < ratio * n.distance:
good.append([m])
# 特徴点同士を描画してつなぐ
img3 = cv2.drawMatchesKnn(img1, kp1, frame, kp2, good, None, flags=2)
# 画像表示
cv2.imshow('frame', img3)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
detect()
カメラのキャリブレーションから姿勢推定を行って、これを検出に利用するとマーカーレス AR のようなこともできそうですね。(適当w)
今回参考にした記事:http://qiita.com/olympic2020/items/caac014b7ab246faf6b1
記事とはあまり関係ないけど姿勢推定についての自分用メモ:http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_calib3d/py_pose/py_pose.html
