AKAZE特徴量とは
OpenCV3.0.0から追加された新しい特徴量で、OpenCV2.4時代の他の特徴点アルゴリズムよりもよいとの噂を聞きます。
参考 AKAZE特徴量の紹介と他特徴量との比較
SIFTもSURFも商用NGで使えないよ!と思っていたので、AKAZEを試してみました。
python2.7での実装
OpenCV3.0.0のpythonの公式チュートリアル、リファレンスを参考にしても、そんなメソッドねーよとか怒られてしまうので、StackOverFlowの過去の人の質問やC++のコードを参考にしながら書きました。
pythonでOpenCV3.0.0動くサンプルがほとんどなくて苦戦した・・・
以下、標準入力に画像ファイルパスを2つ入れると、特徴点をトラッキングして、結果を画像出力してくれるサンプルです。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import cv2
import sys
img_path = sys.argv[1]
img_path2 = sys.argv[2]
img = cv2.imread(img_path)
img2 = cv2.imread(img_path2)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# 特徴量記述
detector = cv2.AKAZE_create()
kp1, des1 = detector.detectAndCompute(gray, None)
kp2, des2 = detector.detectAndCompute(gray2, None)
# 比較器作成
bf = cv2.BFMatcher(cv2.NORM_HAMMING)
# 画像への特徴点の書き込み
matches = bf.match(des1, des2)
matches = sorted(matches, key = lambda x:x.distance)
# 出力画像作成 表示
h1, w1, c1 = img.shape[:3]
h2, w2, c2 = img2.shape[:3]
height = max([h1,h2])
width = w1 + w2
out = np.zeros((height, width, 3), np.uint8)
cv2.drawMatches(img, kp1, img2, kp2, matches[:50],out, flags=0)
cv2.imshow("name", out)
cv2.waitKey(0)
つまづいたポイント
detectorが変わってる!
公式には、
orb = cv2.ORB()
みたいに、使用するアルゴリズムの名前の大文字で宣言するように書かれてますが、これだと通りません。
detector = cv2.ORB_create()
のように、{アルゴリズム名}_create
としてください。
drawMatchesにoutImgを引数として与えなければいけない
以前および公式には、
python-tutorialには
img3 = cv2.drawMatches(img1,kp1,img2,kp2,matches[:10], flags=2)
といった使い方だったり、
API Referenceでは
Python: cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches1to2[, outImg[, matchColor[, singlePointColor[, matchesMask[, flags]]]]]) → outImg
と書かれているが、実際にこれをやると、
TypeError: Required argument 'outImg' (pos 6) not found
と言われてしまう。
outImgはoptionalのはずなのに、Requiredと言われる。
こちらの問題は、stackoverflowでも議論されていた。
TypeError: Required argument 'outImg' (pos 6) not found
outImgをNoneにするだけでよいそうだが、気づかなかったので、わざわざ2枚の画像の大きさから、outImgを作成した。
# 出力画像作成 表示
h1, w1, c1 = img.shape[:3]
h2, w2, c2 = img2.shape[:3]
height = max([h1,h2])
width = w1 + w2
out = np.zeros((height, width, 3), np.uint8)
最後に
pythonでOpenCV3.0のソースを書こうとすると、リファレンス通りにいかないことがあるみたいなので、気をつけて下さい。この情報もいつまで有効かわかりません。