2016年1月1日金曜日

魚へんマッチングコーディング書き初め

先日のシェル芸勉強会で魚へんの漢字を探す問題が出題されました。本当はUnicodeで魚へんの漢字が連続して出てくることを利用して解く問題ですが、それだとなんか面白くないので画像マッチングで解くことにしました。

やったこと

やったことは非常にシンプルで、同一のフォントなら文字が変わっても大体魚へんの部分は一致するだろうという雑な推定を使いました。従って"魚"や"鯊"などの部首の区分では魚かもしれないが見た目が違うものについては対応する気がありません。魚の大きさが全く違うようなデータが来ても全然ダメです。

まあ普通にC++とかで実装すればいいんですが、芸がない (シェル芸という意味ではないですよ) のでC++でCLIのツールの様なものを実装してシェルで動かしたことにしました。

作ったもの

https://github.com/MasWag/image_utils にあります。Arch Linuxで動かしました。おまけで画面をキャプチャするツールも作りました。これはX11じゃないと動かないのでLinuxじゃないと動かないかもしれません。画面をキャプチャしてパターンとマッチした部分をクリックみたいなものを書けて便利です。

動かしかた

画像データは http://www.unicode.org/ から持ってきました。大量に持ってくると怒られそうなのでほどほどにしてください。ローカルに置くと良いと思います。OpenCVではgifは扱えないのでImageMagickなどで事前にpngに変換して下さい。魚へんの部分もImageMagickでcropとかして適当に作ってください。

./imread tachiuo.png gomi.png maguro.png | ./matchTemplate sakanahen.png

を実行すると

0.868365 6 23 0.473221 16 23 0.682904 6 23

みたいな出力がされます。第一フィールドが大きい方が正解っぽいデータです。第二、第三フィールドがマッチした部分の中央の座標です。第一フィールドを見てもわかりますが、今回は6が左側の中心なのでへんらしい場所にマッチしていることがわかります。多分Unicode全部の画像を持ってきてある程度以上マッチしたデータを全部集めると魚へんが残りますが、流石にそんなことはやってません。