0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ゲーム画面を画像分析してみた

Posted at

背景

プレイ中のゲーム画面を画像分析させたりできないかなぁと思っていた所、思っていたよりかなり簡単に実装できたので記事にしました。

使用技術

  • Python
  • Pillow(画像を扱うためのライブラリ)
  • OpenCV(画像解析用ライブラリ)

実際の例

今回は例として、テトリスを画像分析してみることにします。

import cv2
import numpy as np
from PIL import Image, ImageGrab
import time

# 1.テトリスブロックのテンプレート画像ファイルのパス
block_templates = ['block_I.png', 'block_J.png', 'block_L.png', 'block_O.png', 'block_S.png', 'block_T.png', 'block_Z.png']

def capture_screen():
    """スクリーンショットを取得してOpenCV形式に変換"""
    screenshot = ImageGrab.grab()
    image_np = np.array(screenshot)
    return cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)

def detect_blocks(frame, templates):
    """画像内のテトリスブロックを検出"""
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    detected_blocks = []

    for template_path in templates:
        template = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE)
        w, h = template.shape[::-1]

        result = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED)
        _, max_val, _, max_loc = cv2.minMaxLoc(result)

        if max_val > 0.8:  # 一致度が高い場合
            detected_blocks.append((template_path, max_loc, (w, h)))

    return detected_blocks

while True:
    # 2.ゲーム画面をキャプチャ
    frame = capture_screen()

    # 3.ブロックを検出
    blocks = detect_blocks(frame, block_templates)
    
    # 4.検出結果を表示
    for block in blocks:
        template_path, (x, y), (w, h) = block
        print(f"Detected {template_path} at position ({x}, {y})")

        # 5.検出したブロックを矩形で囲む
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

    # 6.キャプチャした画像を表示(デバッグ用)
    cv2.imshow('Detected Blocks', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    time.sleep(5)  # 5秒ごとに実行

cv2.destroyAllWindows()

コードの説明

1. テトリスブロックのテンプレート画像ファイルのパス

テトリスの各ブロックの画像を用意します。
画像例:
block_O.png

2. ゲーム画面をキャプチャ

今開いているPCの画面全体のスクリーンショットを取ります。

3. ブロックを検出

テンプレートマッチングにかけ、各ブロックに一致する箇所の一覧を取得します。

4. 検出結果を表示

ブロックが存在した座標をシェルに出力します。

5. 検出したブロックを矩形で囲む

ブロックを色つきの長方形の枠で囲い視覚的に分かるようにします。

6. キャプチャした画像を表示(デバッグ用)

最後に画面上に、画像分析の結果を出力します。
私の環境では、いい感じに表示できなかったので調整は必要です。

感想

難しい部分をライブラリがやってくれているおかげで、かなりシンプルなコードで実現することができました。
応用すれば、結構できそうなことがありそうだなと思いました。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?