섀도바의 승패를 화상 인식으로 판정한다
TechConnect!는 마음대로 시작하는 어드벤트 캘린더로서 engineer.hanzomon이라는 마음대로 만든 그룹에 의해 릴레이됩니다.
(링크 정보 시스템의 Facebook은 여기에서)
테마가 자유였기 때문에 자유로운 기사가 됩니다. (사용 기술은 진지합니다.)
튜토리얼을 구사해, 열심히 화상 인식을 했습니다.
할 수있는 것
Shadowverse(Steam판)의 Win/Lose 판정을 실시하는 프로그램이 생겼습니다.
(gif의 화면은 Lose 판정을 확인하기 위해 묘화하고 있습니다. 판정은 묘화 하지 않아도 가능합니다.)
보시다시피, Win/Lose 이미지와 캡처 화면을 비교하여 판정하고 있기 때문에,
"특정 어플리케이션의 캡처에, 지정 화상이 출현하고 있는지를 실시간으로 판정한다"
하고 싶은 사람의 참고가 될까 생각합니다.
사용한 것
도입 방법은 후술하는 참고 기사를 참조해 주세요.
한쪽 끝에서 pip로 설치하는 것만으로 할 수 있었으므로 특히 막힌 곳은 없었습니다.
방법
게임 화면을 화면 캡처
아래 기사를 참고하여 PIL을 사용하여 캡처를 수행했습니다.
[Python] [Windows] Python으로 화면 캡처하기
from PIL import ImageGrab
import numpy as np
TARGET_NAME = 'Shadowverse'
handle = win32gui.FindWindow(None, TARGET_NAME)
while True:
rect = win32gui.GetWindowRect(handle)
img = ImageGrab.grab(rect)
ocv_im = np.asarray(img)
#OpenCV用に色変換
ocv_im = cv2.cvtColor(ocv_im, cv2.COLOR_BGR2RGB)
#画面に描画(確認用)
cv2.imshow("images", ocv_im, )
#適当な方法でWaitをかける(描画時間の確保)
cv2.waitKey(10)
캡처한 이미지와 Win/Lose 이미지를 비교
(미리 Win/Lose 이미지는 스크린샷에서 잘라 둡니다.)
이하의 기사를 참고로, AKAZE로 특징량 매칭을 실시합니다.
OpenCV 3와 Python 3에서 특징량 매칭 (A-KAZE, KNN)
def MatchResultCheck(ocv_img):
win_img = cv2.imread(WIN_IMAGE_PATH)
lose_img = cv2.imread(LOSE_IMAGE_PATH)
akaze = cv2.AKAZE_create()
kp2, des2 = akaze.detectAndCompute(ocv_img, None)
kp1_l, des1_l = akaze.detectAndCompute(lose_img, None)
kp1_w, des1_w = akaze.detectAndCompute(win_img, None)
is_win = False
is_lose = False
bf = cv2.BFMatcher()
if not des2 is None :
#Lose画像とキャプチャ画像で特徴量マッチング
matches_l = bf.knnMatch(des1_l,des2, k=2)
#Win画像とキャプチャ画像で特徴量マッチング
matches_w = bf.knnMatch(des1_w,des2, k=2)
#Lose判定
good_l = []
for match1, match2 in matches_l:
if match1.distance < 0.75*match2.distance:
good_l.append([match1])
#Win判定
good_w = []
for match1, match2 in matches_w:
if match1.distance < 0.75*match2.distance:
good_w.append([match1])
#確認用の画像を作成
akaze_matches = cv2.drawMatchesKnn(lose_img,kp1_l,ocv_img,kp2,good_l,None,flags=2)
#画面に描画(確認用)
cv2.imshow("match", akaze_matches, )
if len(good_l) > 20 :
print("is lose")
is_lose = True
if len(good_w) > 20 :
print("is win")
is_win = True
return is_win, is_lose
Win/Lose 판정
매칭 결과에는 Distance(얼마나 매치하고 있는지)가 저장되어 있으므로, Distance로 발판을 실시합니다.
#Lose判定
good_l = []
for match1, match2 in matches_l:
#Distanceが一定以上の特徴点だけを抜き出す
if match1.distance < 0.75*match2.distance:
good_l.append([match1])
족절 후, 일정 이상 특징점이 남아 있으면, Win/Lose 화상이 존재하고 있다고 판단합니다.
if len(good_l) > 20 :
print("is lose")
is_lose = True
Win 화면/Lose 화면 판정
오검지를 억제하기 위해서, 일정 회수 이상 연속으로 Win/Lose 화상이라고 판단한 경우에만 Win/Lose 화면으로 판정합니다.
(python 사용하고 있기 때문에 더 간단하게 쓸 수 있을 것 같아…
is_win, is_lose = MatchResultCheck(ocv_im)
if is_lose :
cnt_lose_match += 1
if cnt_lose_match >= 4:
print("is lose match")
cnt_lose_match = 0
cv2.waitKey(1000)
else :
cnt_lose_match = 0
할 수 없었던 일
마찬가지로 선공/후공도 판정하자! 라고 생각하면 잘 할 수 없었습니다…
Win/Lose와 달리 판정 이미지가 너무 작다고 한자인 것이 괴로울까 생각합니다.
계속 정진해 나갈 것입니다.
요약
화면 캡처에 특정 이미지가 있는지 확인할 수 있습니다.
판정 결과를 실시간으로 그릴 수 있으면 재미있네요.
다음 번은 @rysk001씨입니다.
Reference
이 문제에 관하여(섀도바의 승패를 화상 인식으로 판정한다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/modest/items/6bf4e65d2482cd40ab5f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
화면 캡처에 특정 이미지가 있는지 확인할 수 있습니다.
판정 결과를 실시간으로 그릴 수 있으면 재미있네요.
다음 번은 @rysk001씨입니다.
Reference
이 문제에 관하여(섀도바의 승패를 화상 인식으로 판정한다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/modest/items/6bf4e65d2482cd40ab5f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)