FLANN Based Matching(近似最近傍探索) AKAZEに適用

V3.0.0
In [10]:
# -*- coding: utf-8 -*-
import cv2

#Ipythonで表示用の設定
import matplotlib.pyplot as plt
%matplotlib inline

#画像読込(テスト用画像:img1)
img1 = cv2.imread("lena.jpg")

#回転画像生成(テスト画像:img2)
h,w,ch = img1.shape                         # 画像のサイズ(縦、横)、チャンネル数を取得
M = cv2.getRotationMatrix2D((w/2,h/2),-30,1)# 画像中心を軸に30度回転の回転行列
img2 = cv2.warpAffine(img1,M,(w,h))         # アフィン変換で画像を回転

# AKAZE検出器の生成
akaze = cv2.AKAZE_create()                                

# 特徴点の検出
kp1 = akaze.detect(img1,None)                        
kp2 = akaze.detect(img2,None)                        

# 特徴量の計算と記述
kp1, des1 = akaze.compute(img1, kp1)
kp2, des2 = akaze.compute(img2, kp2)

# FLANN parameters
FLANN_INDEX_LSH = 6
index_params= dict(algorithm         = FLANN_INDEX_LSH,
                   table_number      = 6,  
                   key_size          = 12,     
                   multi_probe_level = 1) 
search_params = dict(checks = 50)

# ANNで近傍2位までを出力
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k = 2)

# 良好な対応点のみ表示するためのマスク準備
matchesMask = [[0,0] for i in xrange(len(matches))]

# 得られた近傍1、2位の距離を比較(一定割合以下(差が大)をアンマスクにする(表示フラグ設定))
for i,(m,n) in enumerate(matches):
    if m.distance < 0.8*n.distance:
        matchesMask[i]=[1,0]

#対応点を描画
draw_params = dict(matchColor       = (0,255,0),
                   singlePointColor = (255,0,0),
                   matchesMask      = matchesMask,
                   flags            = 0)
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params)

#OpenCVがBGRなのでRGBに変換
disp_out_img = cv2.cvtColor(img3, cv2.COLOR_BGR2RGB)

#画像表示
plt.figure(figsize=(12,6))
plt.imshow(disp_out_img)
Out[10]:
<matplotlib.image.AxesImage at 0xa3cfa10>
inserted by FC2 system