デュエルディスクを作りたい【カード認識編】
- fulline
- 2016年6月30日
- 読了時間: 6分
DuelDisk作成計画の第1弾は、絵の部分からカードを認識させるプログラムの作成です。
なによりも、一番簡単に手を出せそうだったので、これにしました。
一昔前に稼働していた「デュエルターミナル」では、カードの認識をカード背面の中心部分に書かれたQRコードを読み込んで識別していました。
しかしこれでは、QRコードがプリントされたデュエルターミナル専用のカードでしか使うことが出来なかったので、自分がこれまで作り続けていたデッキを使えないという残念なパターンでした。全てのカードに対してQRコード付きを再販しても、製作コストと時間を浪費するだけになってしまいます。
それを克服したWiiで発売された「デュエルトランサー」で使われている「デュエルスキャナー」なるものが出ていたのですが、専用にスキャナを用意するのもアレなので、最高の環境でスマホ撮影した画像からカードを認識するプログラムを作っていきます。
今回認識するために使う手法は「Average Hash」です。
詳しくはリンクを見てもらえば十分理解できると思います。
ザックリ言うと、入力画像を白黒(0か1)に変換して、0と1が違う個数で似ているかどうかを判断するという手法です。
とてもシンプルな手法なので、そこそこの認識速度と認識精度が得られますし、今回は撮影環境が一定という条件(スマホの画面いっぱいにカード全体が入るように撮影する)で行おうと思うので、十分な結果が得られると考えています。
=必要なモノ=
PIL:pythonで画像データを色々イジる為のライブラリ。
YgoPro(ADS):有志で作られた遊戯王ができるPCゲーム。カードの画像やスクリプトがとても綺麗に作られていて、新規カードの更新もすぐに行われるため、認識用のデータベースとして活用させてもらいます。スクリプト名や画像名などは全てカードID(カードの左下の番号)で管理されているので、とても利用しやすいです。
-cards.cdb:カード情報が格納されているデータベース
-pics/〇〇.jpg:picsフォルダ内にカード画像が保管されています。認識用画像とします。
画像のサイズは平均177x255になります。
-decks/〇〇.ydk:構築済みのデッキ情報が書かれている。
…といっても、カードIDが入っているだけです。
認識するカードはデッキに含まれているカードのどれかなので
認識速度を上げるために検索範囲を絞るのが良いと考えました。
=実装=
・認識用画像の編集(PIL)
まずは、認識用及び入力画像の状態を統一する必要があります。
遊戯王のカードは、期が変わるごとにカードのデザインが少しづつ変わっているので、絵を囲む枠よりも少し小さくなるように画像を抜き出します。
最終的な切り取った画像の大きさは、元画像の1/4の大きさである56x56にしています。
抜き出す範囲例

認証用画像例
元画像 グレースケール 2値化
入力用画像(撮影画像)
事前に各認証用画像を全て0,1の数値列(56x56=3136桁)に変換し、テキストファイルにカードIDと共に保存しておきます。
ここまでで以下のような感じです。

・《os.listdir(ディレクトリ名)》:指定ディレクトリ内のファイルをリスト型で取得
・《.crop()》:画像の切り取り
・《.convert()》:カラー、グレースケール("L")、2値("1")の画像のいずれかに変換
・《avhash()》:上記リンク参照
ここまで事前に準備ができていれば、あとは認識したい画像と認識用の画像を比較するだけです。紹介リンクでは、認識したいデータと認識用の各データとのハミング距離を調べて、その数値が低い(つまり、数字列の違いが小さい)データが類似画像としています。今回は同じくハミング距離を利用します。しかし、この方法だと、2つの数字列の同じ位置のビットとしか比較していないため、少しの画像位置のズレにさえ対応できない可能性があります。
-余談-
もし、画像の位置のズレもうまく吸収したいのであれば、「編集距離(レーベンシュタイン距離)」という比較方法を利用するのが良いと思います。この方法は、あるデータが追加・変更・削除を何回行なえば、比較相手のデータになるかを表す数値になります。
例えば、「123234」と「121323」の2つの数字列の類似度をそれぞれの方法で表現すると
ハミング距離での数値は「4」:「121323」
編集距離での数値は「2」:「1213234」(削除と追加)
となります。
今回は、処理速度を考慮したかったので、ハミング距離でやっていますが、認識率の向上を考える時には、編集距離の計算に書き換えてみようと思います。
それよりも、より認識率と速度を簡単に確実に向上させる方法があります。
「デッキ内のカードのどれかを判別すれば良いじゃない」
...結局、デュエルする時はデッキという事前に決闘者によって絞られた検索範囲(最大種類:60枚)で十分なので、無駄に数千枚の中から選ばなくても良いよねということです。
数千枚→max60枚は、相当な削減量ですね。
《邪神アバター》と《閃光弾》を両方入れたデッキとか使っちゃうともしかしたら良くないかもしれないけど、基本的には大丈夫じゃないかと思ってます。

・《.hamming(比較用画像データ,認識したい画像データ)》:上記リンク参照
=出力結果=
今回は、上の画像にある《沈黙の魔術師-サイレント・マジシャン》を使って認識を行いました。類似度5位までのカードも出てくるようになっています。また、《.cdb》からカード名とカード効果を取得出来るようにしています。
>全カードデータから認識をした結果
類似度(カード番号:異なったビット数)
41175645:603
7052:804
91831066:980
35631584:1034
74701381:1067
カード番号:
41175645
カード名:
Silent Magician
カード効果:
Cannot be Normal Summoned/Set. Must be Special Summoned (from your hand) by Tributing 1 Spellcaster-Type monster, and cannot be Special Summoned by other ways. This card gains 500 ATK for each card in your hand. Once per turn, during either player's turn, when a Spell Card is activated: You can negate the activation. If this card is destroyed by battle, or if this card in its owner's control is destroyed by an opponent's card effect: You can Special Summon 1 "Silent Magician" monster from your hand or Deck, except "Silent Magician", ignoring its Summoning conditions.
elapsed_time:28.6617748737[sec]
>デッキ【沈黙する墓守】内のカードで認識をした結果
類似度(カード番号:異なったビット数
41175645:603
94380860:1313
423585:1358
43898403:1359
46772449:1359
カード番号:
41175645
カード名:
Silent Magician
カード効果:
Cannot be Normal Summoned/Set. Must be Special Summoned (from your hand) by Tributing 1 Spellcaster-Type monster, and cannot be Special Summoned by other ways. This card gains 500 ATK for each card in your hand. Once per turn, during either player's turn, when a Spell Card is activated: You can negate the activation. If this card is destroyed by battle, or if this card in its owner's control is destroyed by an opponent's card effect: You can Special Summon 1 "Silent Magician" monster from your hand or Deck, except "Silent Magician", ignoring its Summoning conditions.
elapsed_time:0.769603967667[sec]
デッキ内で絞った方が明らかに処理が早くなっているのが分かりますね。
カードを出すたびに30秒ほど待たされるのはたまったもんじゃないです。
ただ、結果を見る上では全カードから見た方が面白いですね。
今回の場合、上から光が入ってきて、下の方に影が生まれているといった感じの絵が選ばれていることが分かります。また、現物が出てくる前に作成された画像データが残っているためか、二番目にも《沈黙の魔術師-サイレント・マジシャン》が選ばれていますね。
左上と右下にレアを表現する加工が入っていますが、それでもしっかり選ばれているので、多少の違いがあっても認識される可能性が高いことが分かります。
この認識率であれば、十分デュエルディスクの利用は有りなのではないでしょうか??
댓글