LoginSignup
1
2

More than 3 years have passed since last update.

特徴点マッチングを用いて、画像からカードのイラストを見つける

Last updated at Posted at 2020-05-01

目的

特徴点マッチングを用いて、画像からカードのイラストを見つける際の備忘録です。

準備

1.カードのイラスト
2.カードのイラストが含まれた画像
3.カードのイラストが含まれた画像から、カードのイラストを見つけるコード

(例)1.カードのイラスト test2.png
引用元:【青眼の白龍(ブルーアイズホワイトドラゴン)の全て】遊戯王最強の称号を持つ伝説のドラゴンの軌跡
blueeyes2.jpg

(例)2.カードのイラストが含まれた画像 test1.png
引用元:あにてれ
blueeyes1.jpg

3.カードのイラストが含まれた画像から、カードのイラストを見つけるコード

特徴点を算出して、画像からカードのイラストを抽出するコード
参考:ミッキーを特徴点マッチングで検出する

特徴点はAKAZEを使用します。

sample.py
import cv2
import numpy as np

fname_img1='test1.png'
fname_img2='test2.png'

img1 = cv2.imread(fname_img1)
img2 = cv2.imread(fname_img2)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
akaze = cv2.AKAZE_create()
kp1, des1 = akaze.detectAndCompute(gray1, None)
kp2, des2 = akaze.detectAndCompute(gray2, None)

#img1_sift = cv2.drawKeypoints(gray1, kp1, None, flags=4)
#img2_sift = cv2.drawKeypoints(gray2, kp2, None, flags=4)
#cv2.imwrite('out1.png', img1_sift)
#cv2.imwrite('out2.png', img2_sift)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key = lambda x:x.distance)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags=2)
cv2.imwrite('out-match.png', img3)

#homography
good_match_rate = 0.15;
good = matches[:int(len(matches) * good_match_rate)]

min_match=10
if len(good) > min_match:
    src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
    dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
    # Find homography
    M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC)
    matchesMask = mask.ravel().tolist()

    print(M)
    print(M[0][2])
    print(M[1][2])

    height = img2.shape[0]
    width = img2.shape[1]
    top_left = (int(M[0][2] +0.5), int(M[1][2] +0.5)); #tx,ty
    bottom_right = (top_left[0] + width, top_left[1] + height)

#result
result = cv2.imread(fname_img1)
cv2.rectangle(result,top_left, bottom_right, (255, 0, 0), 10)
cv2.imwrite("result.png", result)

テスト

実行結果

$ python sample.py
[[ 6.43984577e-01 -4.58173428e-02  1.61203033e+02]
 [ 2.85![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/23ae3f02-409a-6a3a-5e8b-673a20afa502.png)
230902e-02  4.12312421e-01  1.50286636e+02]
 [ 4.54533377e-04 -5.75705548e-04  1.00000000e+00]]
161.2030333928222
150.28663624674783

特徴点を算出してマッチング

out-match.png

枠を検出
※カードのサイズ変化を考慮できておらず、枠が少し大きめになっています

result.png

Webカメラ画像の場合(1枚のカード)

1枚ならば検出できそう。

out-match.png
result.png

枠ズレは要調整(今は固定値)

Webカメラ画像の場合(複数枚のカード)

複数枚は厳しい。

out-match.png
result.png

課題

  • 複数枚のカード対応
  • 動画対応
  • 枠ズレ調整

遊戯王のリモートデュエルに使えるかもしれません。

CodingError対策

特になし

参考

【青眼の白龍(ブルーアイズホワイトドラゴン)の全て】遊戯王最強の称号を持つ伝説のドラゴンの軌跡
あにてれ
ミッキーを特徴点マッチングで検出する
AKAZE

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2