Bus errorとSegmentation faultに困ったら見るブログ

物理の研究者による日々の研究生活のメモ書きです ( python/emacs/html/Japascript/シェルスクリプト/TeX/Mac/C言語/Linux/git/tmux/R/ポケモンGO)

【python3】少しだけ位置ずれした2枚の画像から特徴点を抽出してずれの大きさを評価したい

opencvでできる

うまくいったサンプルコード

うまくいった例をメモ

■ 参考 : OpenCVをつかった特徴点マッチングについて少しだけ掘り下げる

基本的に↑の記事通りに動かした

■ 参考 : OpenCV3とPython3で特徴点を抽出する(AgastFeature, FAST, GFTT, MSER, AKAZE, BRISK, KAZE, ORB, SimpleBlob, SIFT)

import cv2
from IPython.display import Image
from IPython.display import display
from matplotlib import pyplot as plt

#
# ここで2枚の画像読み込み
#
# (お好きな画像を読み込んでください)

akaze = cv2.AKAZE_create()
kp1, des1 = akaze.detectAndCompute(img1, None)
kp2, des2 = akaze.detectAndCompute(img2, None)

#
# 内容のチェック
#
print('##### 特徴点の数 #####')
print(len(kp1))

print('##### 特徴量記述子 #####')
print(des1)

print('##### 特徴ベクトル #####')
print(des1.shape)

#
# マッチング
#
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)

#
# 特徴点間のハミング距離でソート
#
matches = sorted(matches, key=lambda x: x.distance)

#
# 2画像間のマッチング結果画像を作成
#
img1_2 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:40], None, flags=2)
plt.figure(figsize = (width*2/100, height/100), dpi=100)
plt.imshow(img1_2)
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
plt.savefig("diff_features.png")

その後で、2枚の画像のうち、どことどこが一致しているかを調べた

特徴量のうち、一致度上位n個のみをプロットする
距離が遠いものはNoneとして無視する(これであってるのかわからんが・・・)

import matplotlib as mpl
mpl.rcParams['xtick.labelsize'] = 16
mpl.rcParams['ytick.labelsize'] = 16
mpl.rcParams["axes.labelsize"] = 20
mpl.rcParams["axes.titlesize"] = 20
mpl.rcParams["legend.fontsize"] = 20
mpl.rcParams['axes.linewidth'] = 2
mpl.rcParams['figure.facecolor'] = "white"
mpl.rcParams['mathtext.fontset'] = 'stix'
mpl.rcParams['font.family'] = 'STIXGeneral'

import numpy as np

n=100
x_diff = np.zeros(n)
y_diff = np.zeros(n)
for i in range(n):
x = kp1[matches[i].queryIdx].pt[0] - kp2[matches[i].trainIdx].pt[0]
if abs(x) > 20:
x_diff[i] = None
else:
x_diff[i] = x

x = kp1[matches[i].queryIdx].pt[1] - kp2[matches[i].trainIdx].pt[1]
if abs(x) > 20:
y_diff[i] = None
else:
y_diff[i] = x

fig = plt.figure(figsize=[12, 12])

x_diff = x_diff[~np.isnan(x_diff)]
y_diff = y_diff[~np.isnan(y_diff)]

plt.subplot(2, 1, 1)
plt.title("Comparison %s\nand %s" % (fname1, fname2))
plt.hist(x_diff, bins=20, label="horizontal difference\nmean=%.1f pixel\nstd=%.1f pixel" % (np.mean(x_diff), (np.std(x_diff))))
plt.legend(loc="upper right")
plt.xlabel("horizontal difference on features (x-value)")
plt.grid(linestyle='dotted', linewidth=1)

plt.subplot(2, 1, 2)
plt.hist(y_diff, bins=20, label="vertical difference\nmean=%.1f pixel\nstd=%.1f pixel" % (np.mean(y_diff), (np.std(y_diff))))
plt.legend(loc="upper right")
plt.xlabel("vertical difference on features (y-value)")
plt.grid(linestyle='dotted', linewidth=1)

fig.savefig("hist.png")



matchの前後での特徴量を取り出すには

print(kp1[matches[i].queryIdx].pt)
print(kp2[matches[xi].trainIdx].pt)

ランキング参加中です

↓クリックしていただけると嬉しいです〜