読者です 読者をやめる 読者になる 読者になる

Raspberry PiとOpenCVでスプラトゥーンの勝敗を自動記録する仕組みを作ってみた

f:id:hogesuke_1:20150802040434p:plain ikashot.net
※ 現在、IEで画像が表示できない不具合があります。お手数ですがIE以外でのアクセスをお願い致します…すみません。

何を作ったか

スプラトゥーンではバトルの履歴を見れないようになっているので、勝率がわかりません。自分の勝率がどの程度なのか知りたいなーと思ったので、勝敗を自動記録する仕組みを作ってみました。

仕組み

以下のような流れで処理しています。

  • Raspberry Piのpicameraで、TV画面をキャプチャする
  • キャプチャ画像のなかにWIN or LOSEの結果が表示されているかOpenCVを使って判定する
  • WIN or LOSEが検出されたら、WebAPIを通して結果画面のイメージと勝敗をアップロードする

f:id:hogesuke_1:20150802131319j:plain:w400
不格好ですが、こんな具合にラズパイをセットしてTV画面をキャプチャしてます。

OpenCVの画像認識について

WIN or LOSEの判定はOpenCVを使用して行っています。
画像認識できるようにするまでの手順はだいたい以下のような感じです。

  • サンプル画像の取得
  • 特徴の抽出
  • 検出器の生成
  • OpenCVの画像認識コードの実装

サンプル画像の取得

まず、検出対象の「WIN」と「LOSE」のポジティブサンプルと、どちらでもないネガティブサンプルを用意する必要があります。
今回はWINサンプルを400、LOSEサンプルを300、またどちらでもないネガティブサンプルを3万用意しました。精度の高い検出をするには、数千単位でサンプルを用意する必要があるみたいですが、そこまでやるのは辛いので妥協しています。
f:id:hogesuke_1:20150715212348j:plain:w180 f:id:hogesuke_1:20150715213014j:plain:w180 f:id:hogesuke_1:20150710195159j:plain:w180
左: WINサンプル 中央: LOSEサンプル 右: ネガティブサンプル

特徴の抽出

特徴抽出っていうのは、ここが目でここが鼻でここが口みたいなのを示してあげることです(たぶん)。

難しいことはよく分からなかったので、今回は結果画面の「WIN」「LOSE」っていうのはここのことだよっていう座標を示しています。
これにはTrainingAssistantというツールを使用しました。 github.com

このツールを使うとブラウザで簡単にポジティブサンプルとネガティブサンプルの分類と、特徴の抽出(検出対象座標の記録)ができます。
f:id:hogesuke_1:20150802143253p:plain:w400
こんな具合です。詳しくは作者さんのブログ記事に記載されています。
OpenCV 2.4.2で分類器を作る - shkh's blog

検出器の生成

ツールを使って生成されたポジティブ、ネガティブの分類と特徴点が示されたテキストファイルをもとに検出器を生成します。 これにはOpenCVのコマンドを使用します。

これもTrainingAssistantの作者さんのブログ記事を参考に実行しました。
OpenCV 2.4.2で分類器を作る - shkh's blog

この工程が一番時間がかかります。Core i5、メモリ16GBのMacBookProで完了まで丸2日かかりました。
ただ今回はネガティブサンプルが3万とポジティブサンプルに比べて多すぎたことが原因かもしれません。減らせばもうちょい速くなりそう。

OpenCVの画像認識コードの実装

生成された検出器を使って実際に画像認識するコードを実装します。 これは検索するとたくさんサンプルコードが出てくるので、それを参考にすると簡単に実装可能です。

自分はこのQiitaの記事を参考に実装しました。
python+OpenCVで顔認識をやってみる - Qiita

f:id:hogesuke_1:20150802145617j:plain f:id:hogesuke_1:20150802145621j:plain f:id:hogesuke_1:20150802174714g:plain
こんな具合に検出してくれます。

一応、検出してくれますが精度は悪いです。部屋が暗いと認識されずらかったり、WINをLOSEと間違えたりします。
この精度の悪さを補うため実際のコードでは、20フレーム中に3フレーム以上認識したら正しい検出として画像をアップロードする、といったようなワークアラウンドを埋め込まんでます。
精度が悪い原因はポジティブサンプル数が少ないことだと思うので、しばらくしてサンプルが集まったら検出器を作りなおそうかと思います。

以上!

以上で、簡単な画像認識を実現できました。ツールやサンプルコードを上げてくれている方がけっこういるので、その恩恵にあずかると割と簡単に実現できますね。ほんとう、みなさんには圧倒的感謝です。

Raspberry Piについて

最近、ラズパイ2がでて性能が飛躍的に上がりましたが、自分は間違って古いモデルを買ってしまいました。

この古いモデルは、CPU1コア、メモリ512MBというスペックで、OpenCVのビルドに6時間、Pythonのビルドに2時間かかります。けっこう厳しいです。picameraでのキャプチャについても5fpsぐらいしか出ていなくて、だいぶカクカクです。
ラズパイを購入する際は、まちがって古いモデルを買わないようにご注意ください…

ラズパイのセットアップについても情報はネットにたくさんあるので、困ることはありませんでした。OSもRaspbianというDebian系のLinuxなのでDebianUbuntuの情報を転用でき、情報がなくて困るということはまずないかなぁという気がしています。

もし使ってみたい方がいたら…

GitHubで検出器を含めてソースコードを公開していますので、自由に使っていただくことが可能です。
github.com github.com

しかながら、インストール手順をまったく書けていません…
もし、使ってみたいという方がいましたら@hogesuke_1までメンションください。まじめにインストール手順を書こうと思います。

ところで

いま、さくらインターネットRapidSSLを1年無料で使えるキャンペーンをやっています。イカショットもこのキャンペーンを利用してhttps化してみました。
さくらのサービスを使っている方は利用されてみてはいかがでしょうか(イカだけに)。 ラピッドSSL提供開始記念キャンペーン! | さくらインターネット