AR拡張現実の最適なアルゴリズムとプログラム方法について


「augmented reality」拡張現実って何よ。
augmentは増大、realityは現実ですから「現実を増大する」なんでしょうが、拡張現実と訳しているようです。通称「AR」と呼ばれています。

この技術はカメラで撮った映像とバーチャルなCG等を合成して表示することで、
付加情報をより分かりやすく伝達する仕組みです。CGと写真の合成は昔からありますが、
ARはリアルタイム合成というところがミソになります。

「FLARToolKit」を利用するのはあまりにもバカチョン過ぎて面白みがないので、とりあえず自前プログラムで色々と遊んでいます。

画像認識の第一歩としては、複雑な画像を貧弱非力なパソコンでも処理できるようにシンプル化する必要があります。つまり二値化処理で一般的には白黒の画像に変換します。


二値化は「threshold」メソッドを使えば簡単に出来ますが、ある意味この処理がその後の認識率に大きく左右するところでもあります。
どういう環境で何を認識したいかによりって強調するターゲットが違ってきます。

ノイズ処理やターゲットのカラーなど、単にお絵かき処理として白黒になれば良いというものでは無いのです。
認識処理の前処理として識別二値化をすると考えるべきかと思います。
といことで今後のこともあるので「threshold」は使っていません。

二値化処理されたデータを使って次にラベリングという処理を行います。
これは二値化された領域の区分け処理のようなものです。
これを行うことで画像を各部品単位に認識できるようになります。


しかし、これをまともに処理をするととんでもなく時間がかかります。
ここは昔のBasic時代のテクニックで「floodFill」を使って塗りつぶし作戦です。

二値化画像を走査線でサーチして、白黒判定して白があればラベリングのカウンター値で塗りつぶしてしまうという方法です。
カウンター値はカラーではありませんが、最終的にはBitmapDataを単純なメモリー配列として利用するだけなので問題は無いわけです。
この方法だとラベリング処理はかなり高速になります。


ラベリング処理の後は領域認識です。

実は簡単です。
ラベリングの終わったBitmapDataデータを走査線でサーチして、各ラベル番号単位に最大最小値を配列保管するだけです。
結果を視覚化して確認するとこんな感じです。


んーなんだかターミネーターの画面モニターみたいでカッコイイです。(笑)
ここまで来ると通常のビデオ画面とは異なり空間認識っぽい世界に入ってきます。

ターゲットマークも正確に捉えているようです。
この時点では毎フレーム最大200個程度のターゲットを捕らえているようです。

ただ、求めるマークは単純なものなので、大きさから判断して殆どのものは切り捨てることが出来るかと思います。
この時点で認識データを絞り込めば後の処理がグッと軽くなります。


大前提ですが、パソコンレベルでの動体認識は所詮大したことはできないわけで、
目的別に最適化することが重要です。

たとえば特定の色をX,Y座標上で認識するレベルであれば、数行のプログラムで可能です。
形ではなく色だけの判定なので簡単なのです。

今回の認識対象は以下のとおりです。

「奥行きのある空間の中で板状に描かれた特定のマークを探し、距離と向きと傾きを判断する」
ただし、認識のターゲットには以下の条件があります。

1.図形は8×8cmの大きさの正方形である。
2.図形内には向きを判断するマーク(白地)がある。
3.図形は黒色で、周りに白色の淵(白地)がある。


大体今流行っているマーク式のAR認識対象はこんなもんです。
実はこの条件には認識を簡単にするカラクリが隠されています。

まず、元々の図形の大きさが事前に分かっていることです。
このことによりカメラに映る大きさから大体の奥行き(カメラからの距離)が判断できます。
また、カメラに映る図形の大きさも大体想定できるので、大き過ぎるものや小さ過ぎるものは判断対象から簡単に除外できます。

判断する図形が正方形であるというのもポイントで、画像の特徴点座標から四角形かそうではないかという切り分けが容易になります。
また各辺の長さの最大・最小を判断することで、どの辺が手前でどれが奥なのか容易に判断でき、傾きも分かります。
さらに図形内のマーク(白地)と合わせて判断すると図形の向き(回転)も分かるわけです。

もう一つ重要なポイントは図形の周りの白地です。
この縁取りのおかげで、周りの風景はどうであれ二値化処理を行うことで確実にターゲットが背景から切り離されて映ります。

まるでインチキ手品のタネあかしのようですが、実はそういうカラクリがあるからこそパソコンでもある程度リアルタイムな認識処理ができているわけです。

もう一つ大きな条件は認識する環境です。
大抵の場合は閉鎖的な室内の人工的で極単純な空間を想定しています。
もちろんパソコンとWEBカメラを設置出来る環境はそんなものでしょうが・・・

しかし、もしこれが太陽の直射日光が当たる自然の森の中だったら大変です。
人工的な単純な物体が並ぶ室内とは違って自然空間は複雑怪奇です。

さらに強烈な太陽光で反射や屈折も考えられます。
そうなると単純な画像認レベルでは大変なのわけです。



超簡単な図形認識方法が閃きました。
かなり手抜きな方法ですが、見事にターゲットだけ認識しました。


通常のアルゴリズムでは領域認識の後、後輪郭線処理や特徴点処理、線分判断など相当重い処理を山のようするようです。
しかし、今回の方法はほんの数十行書き足すだけで出来ます。


閃いたのは領域認識の処理で同時に四角形の4つの頂点も見つけてしまう方法です。
ヒントは写真の通り、大抵の場合は領域を囲む四角形の辺に4つの頂点が接するということです。

つまり領域を判断した最小最大値の座標が同時にターゲットマークの頂点である可能性が極めて高いという理屈です。
この方法だと1回のスキャンでラベルの領域を調べつつ頂点処理も終了するわけです。

左を1、下を2、右を3、上を4と頂点固定すると結線ソートも要りません。
究極の手抜き処理ですね。

その上で大き過ぎるもの、小さ過ぎるものは除外します。
さらに領域線が画面の端に接するものは不定なものとして除外します。

もちろんこれらの理屈が当てはまらない場合もあります。
しかし全体的な認識率からしても、ここで頑張っても五十歩百歩で時間の無駄と判断しました。

トータル的な費用対効果からすれば十分実用的な方法じゃないかと思うわけです。
利用用途を限定すればアリだと思います。

もう少し認識率を上げるにはターゲットマークを工夫して、少し色を付けるなどすれば完璧じゃないでしょうか?
ターゲットは黒でないとダメというわけじゃないでしょうから・・・


図形認識だけではつまらないので、テクスチャーを貼ってみました。
書き足したのはたった4行です。


Flash Player10から「beginBitmapFill」と「drawTriangles」を使えば簡単にテクスチャー貼りが出来ます。bitmapDataを新たに用意するのが面倒なのでカメラの映像をそのまま貼り付けています。

少し書き足せばマーカーにビデオストリームを流したり出来そうです。
あまり意味はなさそうですが・・・

テストプログラムを下記に置きます。

ARCam.swf
http://www6.plala.or.jp/TimeTripper/flash/f007.html