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