Swell Foopでマスを検知してみる

前回までは主に環境面での内容について触れてきました。今回は実践編として、実際のゲーム画面を取り込んでみようと思います。今回使うのはLinuxでプレイできるSwell Foopというゲームで、いわゆる鮫亀のクローンです。題材としてはもう少しメジャーなゲームでも良かったのかもしれませんが、ゲームそのもののルールが単純そうだったのと、何よりこのゲームが面白いのでコンピューターにプレイさせたらどうなるんだろうという好奇心からです。

# Canny法で各マスを検出する

Swell Foopを検知した

デスクトップの画面を画像として取り込めるようになったので、早速取り込んでみました。プログラムはimutilsというPythonのツールセットが公開されていたので、そのサンプルファイルを参考にしてみました。imutilsにはauto_cannyという関数があり、Canny法というアルゴリズムで白黒に変換した画像から輪郭を抽出するまでを簡単に行うことができるようです。

あとはfindContourという関数で線画の部分を抽出しました。デスクトップの画面をそのままキャプチャしているのですが、前回出てきたxwininfoというコマンドを使ってみた限りだとデスクトップの背景が混ざってしまい、検知してみると画面に関係ない図形がたくさん含まれてしまうので背景を真っ黒にしました。そうすると100%ではないものの、ほぼ意図したとおり画像を取り込むことができました。

# 矩形以外は除外する

平滑化処理をした場合

続いてRamer–Douglas–Peuckerアルゴリズムというものを用いて取り込んだ画像のContour(輪郭)を平滑化することができます。それぞれarcLengthapproxPolyDPという関数を使います。その結果画像を出力してみると余分なマスは除外できるようになったのですが、ウインドウの境界にある最初の段がうまく検出できませんでした。

# 近似値からマスを取得する

Canny値を変更した画像

boundingRectという関数を使うことでマスを含むすべての輪郭の座標が取得できるようです。この関数でだいたいマスの大きさはこのウインドウサイズだと96ピクセルくらいだとわかったので、あとは単純に高さと幅が90ピクセルから100ピクセルに収まるもの以外を除外するようにしました。また、auto_cannyのパラメータを変更するとマス以外の余計な線を検出しなくなりました。その結果が上記の画像ですが、意図したとおりに300マス分の位置と場所がわかるようになりました。