OpenCVのインストール
sudo pip install opencv-python
画像を用意
(例)1.カードのイラスト blueeyes2.jpg
引用元:【青眼の白龍(ブルーアイズホワイトドラゴン)の全て】遊戯王最強の称号を持つ伝説のドラゴンの軌跡
(例)2.カードのイラストが含まれた画像 blueeyes1.jpg
引用元:あにてれ
画像の左上に文字列を書き込む
OpenCV putTxtを用いる
左上に表示する場合
sample.py
import PIL
from PIL import Image
from PIL import ExifTags
import cv2 as cv
import numpy as np
def write_text(image_path ,x ,y):
str = "ATK:3000, DEF:2500"
str_height = 25
str_width = 340
img = cv.imread(image_path)
# 黒塗りの背景を加える
cv.rectangle(img, (x, y), (x+str_width, y-str_height), (0, 0, 0), cv.FILLED, cv.LINE_AA)
# 線を加える
cv.rectangle(img, (x, y), (x+str_width, y-str_height), (0, 0, 0), 2, cv.LINE_AA)
# 文字を加える
cv.putText(img, str, (x, y),
cv.FONT_HERSHEY_PLAIN, 2.0,
(255, 255, 255), 2, cv.LINE_AA)
cv.imwrite(image_path + '.new.jpg', img)
if __name__ == '__main__':
write_text('blueeyes1.jpg', 10, 30)
実行
python sample.py
パターンマッチングを組み合わせる場合
以下のコードと組み合わせる
sample.py
import cv2
import numpy as np
fname_img1='blueeyes1.jpg'
fname_img2='blueeyes2.jpg'
img1 = cv2.imread(fname_img1)
img2 = cv2.imread(fname_img2)
def write_text(img ,x ,y):
str = "ATK:3000, DEF:2500"
str_height = 25
str_width = 340
# 黒塗りの背景を加える
cv2.rectangle(img, (x, y), (x+str_width, y-str_height), (0, 0, 0), cv2.FILLED, cv2.LINE_AA)
# 線を加える
cv2.rectangle(img, (x, y), (x+str_width, y-str_height), (0, 0, 0), 2, cv2.LINE_AA)
# 文字を加える
cv2.putText(img, str, (x, y),
cv2.FONT_HERSHEY_PLAIN, 2.0,
(255, 255, 255), 2, cv2.LINE_AA)
cv2.imwrite(fname_img1 + '.new.jpg', img)
def detect(img1, 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)
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)
write_text(img1 ,top_left[0] ,top_left[1])
detect(img1, img2)
実行
$ $ python sample.py
[[ 6.43984577e-01 -4.58173428e-02 1.61203033e+02]
[ 2.85230902e-02 4.12312421e-01 1.50286636e+02]
[ 4.54533377e-04 -5.75705548e-04 1.00000000e+00]]
161.2030333928222
150.28663624674783
Webカメラ画像の場合

割と見やすくなる。
課題
- 他のカードでもマッチングできるようにする
- 文字列をDB等から取得する
- ATK/DEF以外も表示する
遊戯王のリモートデュエルに使えるかもしれません。
参考
opencv.jp cv::putText
OpenCVで顔認証やってみた(Part2 : 認証編)
画像にテキストを書き込む方法
特徴点マッチングを用いて、画像からカードのイラストを見つける