Upload
takeshi-hasegawa
View
107.272
Download
0
Embed Size (px)
Citation preview
任天堂WiiU用ゲーム「スプラトゥーン」 リアルタイム画像解析ツール
「IkaLog」の裏側 ささみの会 2015/10 Takeshi Hasegawa (@hasegaw) October 17, 2015 (rev.2)
本スライド中に登場するスプラトゥーン関連画像は任天堂株式会社の著作物からの引用です。
@hasegaw is 誰 長谷川 猛 (HASEGAWA Takeshi) twitter: @hasegaw Ø もともと、インフラエンジニア(2004-2011)
SEとしてシステム構築、客先のシステム運用、提案 気付いたらプリセールス~PMを担当するインフラエンジニア (ざっくりデザイン、工数/導入物品見積もり、 構築プロジェクトの管理、保守等の問い合わせ対応)
Ø フラッシュストレージを軸とした、アプリケーション高速化を支援するセールスエンジニア(2011-2014)
Ø ファブレス半導体ベンチャーでコンピュータ関連なんでも
2
著書/寄稿
3
記事紹介(?)
第二特集 サーバの目利きになる方法 前編
第二特集 サーバの目利きになる方法 後編
4
スプラトゥーンとは
5
スプラトゥーンとは
6
(スプラトゥーン界のラグビー)
スプラトゥーンとは
• 第三者視点(TPS)のシューティングゲームの一種
• インクで自分たちのナワバリを広げないと進めない
• シューティングが苦手でも バケツやローラータイプのブキで気軽に楽しめる
• 本気でやってる人たちは怖い
7
IkaLog とは何か • Wii U用ゲーム「スプラトゥーン」支援ソフト – HDMIキャプチャを介して情報を自動取得
– 数値・文字列データとして認識
– お好みの方法で 蓄積、出力
8
IkaLog の画像認識例
9
IkaLog の画像認識例
10
IkaLog の画像認識例
11
IkaLog の画像認識例
12
IkaLog のイメージ
13
HDMIキャプチャ
IkaLog 実行用PC
プラガブルで様々な使い方に対応
14
録画ソフト 自動制御
AmaRecTV
カラーLED連動
Fluentd 転送
スプラトゥーン戦績記録SNS
CSV/JSONファイル保存 スクリーンショット保存
SNS投稿
IkaLog
Embeded IkaLog (ライブラリモード)
• IkaLog 自体が Python モジュールとして実装されている
• Python コードから IkaLog を実行して、情報を受け取れる
• 作ってみたアプリケーションの例
15
アプリケーション 説明 IkaRename.py スプラトゥーンのビデオを分析
ステージ/ルール/勝敗のついた ファイル名にリネームする
IkaClips.py スプラトゥーンのビデオを分析 敵を倒した/倒されたシーンだけクリップし、 “忙しい人”向けのサマリビデオを生成 出力例 https://www.youtube.com/watch?v=w6kqbAPq1Rg
開発開始の経緯と 基本的なしくみ
IkaLog開発の経緯
• スプラトゥーン プレイヤー同士で モツ鍋を食べていたら、戦績の統計の話に
• ゲームには、戦績の統計機能は存在しない
• 手動でExcelを使い戦績を整理している人も
17
スプラトゥーン プレイヤーにとっての 主なメトリック
• どのステージが得意か?苦手か?
• どのルールが得意か?苦手か?
• どのブキが得意か?苦手か?
• どのブキにやられやすいか?
• どれぐらい突進していいのか? 突撃し過ぎなのか?
18
ツールを作ろう(検討編 1)
その晩から、720p 1プレイ分の動画を相手に 検討開始 • 非圧縮 5分 → 20GB
OpenCV のテンプレートマッチングで試行錯誤 • 判ったこと:使えなそう – 誤検出が多い
– マッチングアルゴリズムが遅い 19
ツールを作ろう(検討編 2)
• もっと単純な方法で画像をマッチングする – スプラトゥーンのシステムメッセージは ほとんどが、決まった位置に白色で表示される
– 「文字部分だけが黒く、残りが白い画像」を加算し、 加算した後の画像のヒストグラムで判定する
– 基本的に足し算、引き算で実現できるため 非常に高速に処理できる
– 画面が真っ白なときに誤動作
→もともと白い画像は無視する 20
IkaLogの画像マッチング (第一世代)
21
ソース映像 マスク画像 加算画像
+ = =
正しいマスクを加算すると画像が真っ白になる
違うマスクを加算すると画像が真っ白にならない
IkaLogの画像マッチング (第二・三世代)
• 第二世代 – 「前景が白」だけでは他の場面で誤認識するケースが 増えてきた
– 「背景が黒」「背景が白以外」のどちらかを 指定して、条件以外のドットが多ければ False-Positiveと判断できるように拡張
• 第三世代 – 「前景がオレンジ」「前景が黄色」などを認識したい ケースがでてきた
– 前景・背景ごとにHSV色成分などを指定して、条件通り・ 条件以外のドットを検出できるように拡張
22
入力画像から目的の色だけを取り出す
23
入力画像 黄色のみ
白のみ 黒のみ
RGB色空間とHSV色空間
24
RGB色空間 HSV色空間
引用元 hAps://ja.wikipedia.org/wiki/RGB hAps://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93
©Wapcaplet ©Marc_Mongenet
数字の認識と機械学習
数字の認識 • ゲーム中で使われているフォントは2種類
• 認識対象になる数字フォントは1種類
• フォントが判っているのだから、認識できるはず
• 試行錯誤の末、既存OCRエンジンの利用は断念
• 機械学習ベースの認識エンジンを実装
26
既存OCRでの問題点 • Tesseract OCRを評価
– 認識率が安定しない
– もともと文章を読み取るためのもの – 1~2文字の文字、数字の認識は苦手
– 0, 8, 3 などを間違えることがある
– 今後問題があったときにアルゴリズムに 対して手が出せない
– Python 3.x スクリプト上から利用しづらい
• 既存の文章向けOCRエンジンよりも 単純で目的に適した認識方式を検討
27
文字として 認識されないことも
kNN(K近傍法)の考え方
28
● ● ●
●
■ ■
■ ■
? ▲
▲
▲
▲
?
?
?
?
とてもシンプルな機械学習 標本 の傍にあるサンプルがどれかで分類する。 K=1 の場合は最寄りのサンプルがあるクラスに分類される。 K=3 の場合は近くに3つのサンプルがあるクラスに分類される。
kNNによる図形マッチングのデモ(1/2)
• GitHub にソースあり – https://github.com/hasegaw/opencv_knn_example/
• 三つのパターン ○ △ □ で画像を生成し、 kNNで学習する
• ランダムに ○ △ □ から画像を生成し、その画像の種類を判定する – KNN を用いてそれに近い画像を見つけ出す
– 見つけた画像の種類から、答え(標本の種類)を特定
29
kNNによる図形マッチングのデモ(2/2)
30
問題図形をランダムに生成
K近傍法を用いて、学習済みの 図形から、もっとも近い図形を調べる
仕分ける ○ △ □
○ 学習済み図形
○ △ □
デモ風景
31
32
kNN による数値認識を実装後、はじめての テスト結果。10の位は文字画像の位置ズレで 誤認識が生じているが、1の位は100%認識 できた
数字の認識 1)画面上の数字部分(位置固定)を切り抜き
2)縦・横のヒストグラムを生成し各文字の位置を特定
3)文字を検出用サンプルのサイズ(等幅)にリサイズ、 二値化
4)KNNにより既知の検出用サンプルと照らし合わせて 認識する
33
34
死因の認識
死因の認識
36
死因の認識
• 「数値が認識できているから、 死因もなんとかなるだろう」
• 数字認識との共通点 – 目的の情報が白色なので二値化しやすい
– 文字列の位置を特定し、切り抜きできる
• 数字認識との相違点 – アニメーションにより、常にサイズが変化
37
死因の認識(3) 死因のリスト
38
死因の認識(3) • 基本は数字の認識と一緒
– 1文字単位ではなく文字列を一組として処理
– 文字列は左寄せして処理(したほうがいいのかはよく判っていない)
• 認識率はそれほど高くないが、認識回数で精度を確保 – IkaLogは現在毎秒10フレームほど解析している
– 下記例では、死因のメッセージ合計49fを解析し、 最多頻度は96gal_deco (18f, 36%) だった → 結果的に正解
39
votes={ 'supershot': 6, 'carbon_deco': 1, 'bucketslosher': 1, 'octoshooter_replica': 1, 'splashshield': 1, 'sshooter_collabo': 5, 'hotblaster': 2, 'pablo': 1, 'nzap89': 6, 'sharp_neo': 3, 'hotblaster_custom': 2, '96gal_deco': 18, '52gal': 1, 'hokusai': 1 }
ブキの認識
スプラトゥーンのブキ
• スプラトゥーンでは、50種類を超えるブキから 好きなものを選んで利用できる
• 全体的にバランスが取れているゲームだが 戦略や戦術、ブキの選択で優劣が発生する
• 分析したい -> 画像認識
41
スプラトゥーンのブキ画像リスト
42
スプラトゥーンのブキ 59種類(現時点)
画像判別においてのチャレンジ
• ブキ画像が小さい(47x45ドット・外枠込み)
• 表示条件(背景・被る画像)が変わる
• 誤判定すると後の統計結果に多大な影響が出る
• 一回の判定に使えるのは画像1枚のみ
43
他の装備品が被っている 保護色(まだマシ) 保護色(マジつらい)
スペクトラムによるブキ特徴量の算出
44
(まだバグがあった頃のバージョンの表示なので色がずれているけども) こんなかんじで特徴量を抽出していた → 認識率97%台
ブキ認識テストの様子(かなり初期)
45
ブキ認識の正答率があがらない
• アルゴリズムの改善を繰り返して 認識率97%台に。しかし、その先で伸び悩み – 戦績画面一回あたり、認識対象となるブキが8個登場
– 98%だと12~3ゲームに1回は認識ミスする計算
• モツ鍋を食べながらアルゴリズムの 改善方法を議論 – ラプラシアンフィルタの活用を提案される
– トレーニングデータで.xxガロンの分類が間違っていたのを修正
46
ラプラシアンフィルタを用いた ブキ画像 特徴量の算出
• 新アルゴリズムを導入(@itoooon 作)
• ラプラシアンフィルタを利用し、 最終的に64次元の特徴量を算出
• ブキ1000個の事前学習で11000個以上の分類(正答率99.99%以上)を達成!
47
入力画像 ラプラシアン フィルタ適用 グレースケール 輪郭情報 特徴量画像
(合計64ドット)
@itoooon
新しい特徴量算出方法での分類結果(1)
48
新しい特徴量算出方法での分類結果(2)
49
テストデータは12000弱 正解の一覧は作っていないので目視で確認
多分、分類できている
Webcam サポート
※ ソースコードは GitHub にありますが、現在開発中の 機能であり、一般ユーザー向けには提供していません。
Webcamサポート
• HDMIキャプチャデバイスを持っている人は少ない – ゲーム実況をするニコ生主などなら 持っているが…
– 新たに購入しようとすると、約2万円の投資
• HDMIキャプチャの代わりにWebカメラを利用できないか?
51
Webcam サポート(イメージ)
52
1) TV、ディスプレイに Webcam を向ける 2) WiiU のホーム画面を表示
3) IkaLog で Webcam を介して ワープ キャリブレーション 4) 以後 IkaLog は画面と認識した範囲に対して処理を行う デモムービー hAps://www.youtube.com/watch?v=d91xyyA-‐exA
OpenCVサンプル find_obj.py (1)
53
OpenCVサンプル find_obj.py (2)
54
HDMIキャプチャと間接キャプチャの比較
55
HDMIキャプチャ (H264録画) Webcamによる間接キャプチャ 雑なカラーコレクション適用済み
Webcam経由の入力状況 • 「既知の画像」(WiiU ホーム画面)を 画面上に出して、キャリブレーション
• 720p (1280x720) の画面を ±5pxぐらいの精度で取り込める
• 白色が (255,255,255) にならないため 何らかの対策が必要 – カラーバランス、ガンマ調整 – IkaLog 内の画像検出のスレッショルド変更
• 一般ユーザに使ってもらうためには、 まだ解決すべき課題が多い
56
Webcam 対応の課題点と これまでに得られた知見
• もし、このような「変な使い方」をするときは 自動調整機能をオフにできるWebcamがオススメ – カラーバランスが固定できること
– コントラストが固定できること
– オートフォーカスをオフにできること
• プラズマTVは明るすぎて Webcam の ダイナミックレンジが追いつかない? EL液晶は?
• 新しめのスマートフォンのカメラも非常に優秀
57
よさそうな WebCam の一例
58
Logicool の Webcam はカラーバランス、コントラスト、フォーカスを 固定できるのでこのような用途に向いている(アキヨドで試して購入した)
ただし上記の固定機能は Windows 専用。 Mac では実装されていない(怒
データの活用
IkaLog が出力するデータの複雑化(1)
60
IkaLogの当初のスコープ ・ステージ/ルール検出、勝敗(2択) ・スクリーンショット保存
追加された検出内容 ・目標(ガチホコ/ガチヤグラ)の位置検出 ・プレイヤーの死因(凶器)検出 ・時系列のスコア検出 ・プレイヤーのランク、所持金などの数値検出 ・全プレイヤーの生死ステータスのモニタリング ・ロビー(パブリック/プライベート/タッグ)検出 今後追加する(かもしれない)検出 ・コミュニケーション検出(ナイス/カモン) ・スペシャル蓄積・利用検出 ・目標に対するチームのイベント
IkaLog が出力するデータの複雑化(2)
61
{'time': 1442394550, 'result': 'win', 'rule': 'ガチホコバトル', 'event': 'GameResult', 'map': 'モズク農園'}
{'rank_in_team': 2, 'weapon': 'デュアルスイーパーカスタム', 'result': 'win', 'kills': 1, 'time': 1444491154, 'cash_after': 1820744, 'players': [{'rank_in_team': 1, 'weapon': 'プライムシューター', 'kills': 2, 'deaths': 1, 'udemae_pre': 'B-', 'team': 1}, {'rank_in_team': 2, 'weapon': 'デュアルスイーパーカスタム', 'kills': 1, 'deaths': 0, 'udemae_pre': 'B', 'team': 1}, {'rank_in_team': 3, 'weapon': 'プライムシューター', 'kills': 1, 'deaths': 0, 'udemae_pre': 'C+', 'team': 1}, {'rank_in_team': 4, 'weapon': 'スプラシューターコラボ', 'kills': 1, 'deaths': 0, 'udemae_pre': 'B-', 'team': 1}, {'rank_in_team': 1, 'weapon': 'ジェットスイーパーカスタム', 'kills': 1, 'deaths': 2, 'udemae_pre': 'C', 'team': 2}, {'rank_in_team': 2, 'weapon': '3Kスコープ', 'kills': 0, 'deaths': 1, 'udemae_pre': 'B-', 'team': 2}, {'rank_in_team': 3, 'weapon': 'プロモデラーRG', 'kills': 0, 'deaths': 1, 'udemae_pre': 'B-', 'team': 2}, {'rank_in_team': 4, 'weapon': 'ダイナモローラーテスラ', 'kills': 0, 'deaths': 1, 'udemae_pre': 'B+', 'team': 2}], 'rule': 'ガチホコバトル', 'event': 'GameResult', 'deaths': 0, 'udemae_pre': 'B', 'map': 'アロワナモール', 'team': 1}
GitHub イニシャルカット時の IkaLog が出力した戦績ログ (JSON)
最近の IkaLog が吐く戦績ログ (JSON) ※本当はもっと色々出せる
→ 情報量の増加に伴い分析基盤の構築が必要
stat.ink (戦績SNS)
• IkaLogユーザのひとり @fetus_hina さんが開発、運営する Web サイト
• IkaLog からのプレイデータを受け取り、表示・集計する
62
63
64
stat.ink (全ユーザのプレイ結果からの統計)
65
自分が4回以上死ぬと 試合への勝率が大きく下がる
IkaLog + stat.ink のDAU、処理ゲーム数
0"
5"
10"
15"
20"
25"
30"
0"
100"
200"
300"
400"
500"
600"
700"9/27/15"
9/29/15"
10/1/15"
10/3/15"
10/5/15"
10/7/15"
10/9/15"
10/11/15"
10/13/15"
10/15/15"
66
データソース hAps://twiAer.com/fetus_hina/status/654681918131142657
まとめ
まとめ
68
画像処理のノウハウ • OpenCV 3.0で高速に
マスク処理、スコア算出 • スプラトゥーンの画面は
検出しやすい (ほぼ位置固定・白色文字)
機械学習すごい • K近傍法は簡単に使える • 特徴量の計算方法が ポイントになる
そのほか • 情報の見える化、大事 • 一人では全部できない • スプラトゥーン楽しい
質問タイム?
69
らぴす (2000-‐2014)
マンメンミ! (ありがとうございました)