こんにちわ。ドローンおじさんです。Drone Champions League (DCL) というヨーロッパ各地でドローンレースを開催しているプロリーグがあります。その DCL から発売されているドローンレースシミュレーター、DCL The Game(Steam、PS4、Xbox 版あり〼)のレース結果を自動的に取得して Slack に投稿するっていう、スーパーニッチなプログラムの解説を書いておきます。
どういうこと?
↓こういうのがレース後に出る。
それが↓みたいに投稿される。
どうやってんの?
- 定期的に画面キャプチャする。
- レース結果画面かどうかを判定する。
- タイムとかパイロット名とかを取得する。
- Slack に投稿する。
1. 定期的に画面キャプチャする。
プログラム全体は Python で書いてるので、画面キャプチャは PIL の ImageGrab で。DirectX フルスクリーンのでも普通にちゃんと取れる。PIL の Image オブジェクトになってるので後処理もやりやすい。
[Python][Windows] Pythonでスクリーンキャプチャを行う
https://qiita.com/koara-local/items/6a98298d793f22cf2e36
2. レース結果画面かどうかを判定する。
ちまちまピクセル解析すんのはダルいので、AutoML Vision の Single-Label Classification で機械学習。
ゲーム内容をビデオキャプチャしたあとに 1 秒ごとにフレーム書き出し小さめにリサイズ。
ffmpeg -i capture.mp4 -vf scale=256:-1 -vcodec png -r 1 images/%05d.png
手動で分類、ラベル付け → Cloud Storage にアップロード → トレーニング、、てかチュートリアル↓まんま。
https://cloud.google.com/vision/automl/docs/edge-quickstart
必要なのは flow-result-complete
ラベルだけなんだけど、他のシーンにもラベルつけてみた。数がだいぶ偏ってる。
トレーニング後。過学習っぽい気がしないでもない🤔(実際のところ問題なし)
モデルをダウンロードして Docker 上で動かす。REST API で画像送れば推論結果が JSON で返ってくる。
https://cloud.google.com/vision/automl/docs/containers-gcs-tutorial
内部的には TensorFlow が動いてるんだけど、ここまでまったく TensorFlow 絡みのコード書いてない。PIL でイメージ読んで HTTP リクエストしてるだけ。精度問題なし。学習時間 2 時間ぐらい。API 利用料 600 円ぐらい。ラクチン!
3. タイムとかパイロット名とかを取得する。
結果画面が取得できたら、あとはそこから必要な情報を抜き出す。画像から文字情報を抜き出すには OCR。Python で OCR なら pytesseract が定番? Vision API には OCR もあってそっちのが精度はいいんだけど今回は読み出す内容がすごくシンプルなので pytesseract で事足りた。
ふつうに全画面を pytesseract に食わせるとわけわからんデータが返ってくるので、必要なとこだけ切り出した画像を食わせる。あと背景白で文字黒のほうが精度高いっぽいので白黒反転させる。
英数字だけならほぼ間違わずに読み取れる。たまにパイロット名に英数字以外つかってる人いると間違う。(しらん人なので無視😅)
ステータスアイコンも読み取る。
人間が足りないときは過去の人間のリプレイがゴーストとして登場。どれがゴーストかは結果画面のアイコンでわかる。これを読み取るのには、アイコン表示位置を切り取ったあと scikit-image の structural_similarity で比較して判定。接続が切れたときのアイコンも判定。
4. Slack に投稿する。
必要な情報が取得できたらあとは整形して投稿。画像つきで投稿するときは chat.postMessage じゃなくて files.upload ね。
何につかうん?
Slack に投稿するだけだとまだイマイチなんだけど、Spreadsheet とかにつっこんでいくようにするといろいろ集計できて、チーム練習が捗るんですよ😉