こんにちは!スマブラ64のキャラクターコール、リンクだけ「ヌギー」にしか聞こえないけど実際になんて言ってるのか最近理解してきたひなるひです。この記事はアドベントカレンダー2022、18日目の記事です。
世のなかにはボタンを押す以外にも、画面をタップする、音声入力、ジャイロセンサによる入力等、様々なゲームの入力方法があります。僕は色々あって「文字認識も汎用的な入力になりえるんじゃないか」と考え、ゲームを作ってみることにしました。
結論からいうと、とりあえずゲームは完成したのですが、リアルタイムに文字認識させることができませんでした。まだゲームで実用的な速度が出ず、一回の文字認識で5秒かかってしまっている状況です(openCVによる最適化をあまり行っていない)。
結果作ったゲームが上のようなものです。文字認識1回に5秒というボトルネックを加味して作ったためリアルタイムでのゲーム性は薄いと思いますが、参考になればと思います。上記の文字認識速度を含め、ゲームを作るうえで色々障壁があったので、一個ずつまとめてみました。
ゲームの環境
- Unityバージョン:2021.3.4f1
- 動作環境:Android、GalaxyNote10+
- 使用ARアセット:ARFoundation
目次
- ARM64問題
- 文字認識自体なかなか速度が出なかった
- 対象の文字の種類以外が含まれていると精度が落ちる問題
- どうゲームに盛り込むか
- 今後の展望
1.ARM64問題
まずなんですが、使用したUnityバージョンではAndroidのターゲットにARMv7とARM64があります。まずARFoundationはARM64に対応しています。またUnityで文字認識しようてきな、すでにUnityでtesseractを使用できるように用意してくれているものもネット上に数多くあります。しかしこれらすべてARMv7対応でした。なのでtesseractをARM64向けにビルドし直す必要がありました(有名な有料のUnityアセットを使用すると解決したかもしれなかったのですが、ちょうどめちゃくちゃ円安なタイミングだったので金払いたくなかったです...)。
慣れないAndroid向けビルドでしたが、最終的には、https://github.com/adaptech-cz/Tesseract4Androidを引っ張ってきて、JAVA11を用いてビルドすることでsoファイルのビルドを行うことで解決しました。
ちなみにtesseractと同時にopenCVも入れました。こちらは普通にhttps://opencv.org/ からビルドしました。
2.文字認識自体なかなか速度が出なかった
完全に誤算でした。https://github.com/Neelarghya/tesseract-unity もともとこれをUnityのtesseractとして使用していたのですが、付属しているサンプルを手元のAndroid端末にて動かしたところ、一回の文字認識にかかる時間は0.2秒程度でした。これで大丈夫そうと考えたのがうかつで、実際はカメラからとったものを非圧縮で解析させて、速くて1秒~2秒でした。CPUの調子が悪い時なら5秒平気でかかってしまいます。処理自体がCPUに結構負荷がかかることも加味すると、より速い処理、より安定したフレームレートで動かすのにはまだまだ課題が多そうです。一種の解決方法としてはopenCVにて画像サイズの圧縮をまだ試みてないので、そこでの最適化はまだまだ改善の余地がありそうです。誰か精度ゴミでいいからくそ速い文字認識作ってくれねーかなー
また今回に限って言うと、辞書から文字認識してたこともあり、取得してくる文字数がめちゃくちゃ多かったために遅かったことも問題です。(なので、逆に少ない文字列のみでやるゲームなら作れるかもしれない...?)
3.対象の文字の種類以外が含まれていると精度が落ちる問題
世界には英語や日本語以外にも様々言語、記号があり、tesseractはそれらの言語を手動で一文字単位で設定することができます(例えば英語とフランス語の文字は読み取れるようにしてほしいとか、英語と数字だけど「0」と「O」は読み取らないようにしてほしいとか)。今回作成したゲームはアルファベットのみを読み取って行いますので、最初はアルファベット以外はすべてtesseractにて読み取らない設定で行っていました。
しかしこれを行うと明らかに文字認識の精度が落ちました。結局のところtesseract側では英語、数字、記号をはじかずに読み取り、その文字列を自前のコードによって必要文字種以外をはじくコードを生成しました。
もちろん、これらの要因から読み取られる文字にはある程度誤差があります。今回「答えとなる単語を文字認識で読み込めればクリア」というルールなので、簡易的なレーベンシュタイン距離などのアルゴリズムを用いて「大体読み込めてたら正解にする」という感じにしていて、いまのところ次の章の「本の溝の部分の文字が読み込めない」以外において、適切な操作をしたうえで読み込めないトラブルはほぼ起きてないです。
4.どうゲームに盛り込むか
「アプリ内にて今写ってるのをキャプチャする→そのままtesseractに流す→文字を取得」この流れにて文字を取得しました。リアルタイムで文字認識できると仮定して果たして上記の流れを用いてどんなゲームが作れるか問題があります。今回は「辞書を使う」というところに落とし込んだのですが、ここでも障壁がかなりあります。「辞書使いながらスマホ持つの辛くない?」等の物理的な問題も数多く存在しましたが、それらを除いた技術的な問題だけでもこれだけありました。
- 読み取った画像の判別が基本できない
- 本の溝の部分の文字が読み込めない
「読み取った画像の判別が基本できない」に関しては、例えば「見出し語だけを認識したい」の場合、プログラムで「見出し語ってどういう特徴の画像なのか」を設定しなければなりません。今回の目標が「文字認識も汎用的な入力になりえるんじゃないか」を突き詰めること、持っている英和辞典がおそらく全員ばらばらなことを考えると、統一基準なんて考えるのは無謀です(なんなら上の動画で使用した辞書は見出し語の特徴がただ大きく書いていて、横にアスタリスクが何個かついているだけ...もしかしたらアスタリスクで判別できたかもしれないがこれだけでも困難です)。また読み取った辞書の箇所が過去に一回以上読み取った場所かという判別もこのままではほぼ無理です(今写している場所があまり動いていない、またはさっきと写している場所が変更された判定なら)。
「本の溝の部分の文字が読み込めない」に関しては、本の左側と右側のページの間のことを指します。このあたりでは文字が横方向に縮小してしまってるのですが、見出し語ですらうまく読み取れないです。実際何人かにゲームを体験していただいたのですが、せっかく答えがわかっても読み取りができなくてもどかしそうにしてたのが少し申し訳なかったです。本に限らず変形した文字での読み取り精度はあまりよくないので、例えばスマホの傾きからopenCVによる変形を行う等もありかもしれません。
5.今後の展望
まだ人類には「文字認識をリアルタイムなゲームの入力機構にする」は早かったなって痛感しました。しかしいつかめちゃくちゃ精度いいエンジンが出れば...とか思っているのですが、現時点でも色々どうにかできそうな機運はあります。
- 一回で読み取る文字数や文字種、画像サイズが小さいようなゲームにする(例えばせっかくARなので、商店街とかショッピングモールの地図とかの文字を読み取るとか...)
- openCVによる最適化
- tesseractとかに代わる、精度等が落ちる代わりに速度が十分速いゲーム用文字認識エンジンを作る
いや作ってくれだれか...もしかして俺でもがんばれば作れる?
これらをやるかどうかは皆さんにお任せします。今は役立たないかもしれませんが、今後速度的に文字認識がゲームの入力機構として十分視野に入りそうならきっと役に立ちます。
僕の話は以上です。明日は@d_etteiu838、@YHz_ikiriさんの記事です。それではまた!