Programming

UnityでOpenCV その2

Programming
スポンサーリンク

どうもー、Reveです。
先月は全然ブログを更新できなかったので、今月はちょくちょく記事を上げていきたいですね。
とりあえずUnityでOpenCVの続きです。
目指せ月2桁更新!!
【前回のおさらい】
この記事を参照。
前回は、画像をグレースケールに変換する手法を書いてました。
・グレースケールのMatを用意
・テクスチャ素材をグレースケールにしてコピー

【二値化処理】
今回は、前の記事で行った処理を元に、「二値化処理」というのを施してみましょう。
この二値化処理とは、濃淡のある画像を、一つの閾値を境目に白と黒の階調、つまりモノクロ画像に置き換える処理のことです。大体、元の画像をいったんグレースケール(灰色で濃淡だけを表した画像)にしてからこの処理が施されます。
(参照)
http://ipr20.cs.ehime-u.ac.jp/column/gazo_syori/chapter4.html
さて、なぜ二値化処理をしてモノクロ画像を取得するのかというと、輪郭の抽出や文字の判定処理など後の画像処理が容易になるからです。処理する対象とそれ以外の部分を切り離すのに使われるオーソドックスな処理と言えるでしょう。
(この辺りは、電子回路のアナログとデジタルの話にも繋がる気がします。ちなみに、白黒をどちらにするかという話は正論理か負論理かと考えると、電子回路に詳しい方はわかりやすいかも)
この処理で重要なのは、やはり白黒を分ける閾値の設定で、
様々な研究が行われていろいろな手法が提案されてはいますが、OpenCVでは理論や数式を完璧には覚えてなくてもこれらの手法が使えるよう便利なメソッドが用意されています。
【二値化処理を試そう】
Unityプロジェクトは、前回の記事で作成したものを使います。
まず前回作ったシーンを開き、シーン内にあるGlayScaleというオブジェクトを複製して隣に移動させましょう。
その際は複製したオブジェクトを別名にするとよいでしょう。
(オブジェクトは「Ctrl + D」キーで複製すると便利です)
OpenCVUnity_binarythres1.png
そこで複製したオブジェクトにつけられたGlayScaleScript.csをいったんはずし、新しいC#スクリプトを作ります。
オブジェクトのインスペクタ(Inspector)のボタン「Add Component」で「BinaryThresholdScript」と名前を入力して、新しいスクリプトの生成画面に入るので、「C Sharp」スクリプトにして生成します。
続けて、スクリプトの編集に入ります。
スクリプトの中身は以下の通りです。

御覧のように、前回のようなグレースケール化処理の後に二値化処理を加えていることがわかります。
今回の二値化処理をするには、Imgproc.thresholdメソッドを使います

そして、実行してみると下の画像のように、処理前の画像と処理後(グレースケール化)の画像が並べられます。
インスペクタから「Thres Binary」のスライダーを調整すると、処理結果が変わります(実行前に設定すること)。
OpenCVUnity_binarythres2.png
また、勘の良い方ならお気づきかもしれませんが、今回作ったスクリプトは適応的閾値処理にも対応しています。
適応的閾値処理は簡単に言うと、画像のピクセルごとに明るいか暗いかを判別して、それぞれに適した閾値を取ることで抽出したい部分を綺麗に二値化する手法を指します。一定の閾値だと明るい部分や暗い部分などの差異を無視してしまい望ましい結果にならない場合も多いため、この手法が生まれました。
技術的な部分など詳細を知りたい方はこちらを参照。
(参照)
http://schima.hatenablog.com/entry/2013/10/19/085019
では、Unityのプロジェクトをもう一度操作します。
二値化処理用のオブジェクトをもう一つ複製して、今度はThresBinaryの値を最大(256)にしてみましょう。
オブジェクトを横に並べて、再びゲームを実行すると下のような結果になります。
OpenCVUnity_binarythres3.png
やはり手動で二値化を設定する場合と比べて、絵の輪郭がわかりやすくなっています。
ただ、こちらの手法も内部のパラメータ調整は必須なので、場合によっては単純な二値化でもよいかもしれません。
状況に応じて使い分けるとよいでしょう。
ちなみに、UnityとOpenCVでこんなものを作ってみたので、ご覧いただけるとうれしい限りです。

コメント

タイトルとURLをコピーしました