『 Flash + OpenCV 』
2010 年 8 月 10 日
AIR2.0の新機能でOpenCVと連携してみました。AIRアプリを起動してTwitterID入力 → Webカメラを選択すると、カメラ映像から顔領域を検出してアイコンが顔を隠します。TwitterIDを空欄にすると笑い男が出現します。俺の目を盗みやがったなという具合に。
・Iキー ・・・ アイコンの表示/非表示を切り替えます。
・Rキー ・・・ 検出された全顔領域の表示/非表示を切り替えます。
実行にはWindows環境であることと、OpenCV 2.1が必要です。また、ネイティブアプリケーション側とAIR側から同じWebカメラに同時にアクセスするので、複数アプケーションからのWebカメラへの同時アクセスをサポートする環境が必要です。
» OpenCV
» ひとつのWebカメラを複数のアプリケーションから同時に使う
ビルドにはさらにDirectX SDK、Platform SDK(Windows SDKに統合されたっぽい)が必要です。もしこれらのライブラリだけでは足りなかったよーという場合は教えてもらえるとうれしいです。
» Platform SDK → Windows SDK
» DirectX SDK
やりたかったこと
AIR2.0から、ネイティブアプリケーション(exeやappなど)と標準入力・標準出力を介して通信できるようになったので、裏方を全部ネイティブアプリケーションにやらせて結果だけFlashで描画するという試みです。要は一から画像処理系をASで組んでやるよりも、高速に動作するネイティブ言語に元々実装されている資産を使った方が効率いいじゃんっていうことです。今回はC++でOpenCVを使って顔検出するネイティブアプリケーションを実装し、その結果をFlashでリアルタイムに描画するプログラムを組んでみました。
AIRの起動から終了までの流れ
- ユーザがAIRを起動する
- AIRがネイティブアプリケーションを起動する
- ネイティブアプリケーションが毎フレーム顔検出をして、結果をFlashに送る
- AIRが検出結果に基づいて描画をおこなう(3に戻る)
- ユーザがAIRを終了すると、AIRがネイティブアプリケーションを終了する
こんな感じです。ネイティブアプリケーションは基本的に表に出しません。エンジン部分はネイティブアプリケーション、表示部分はAIRという風に完全に切り分けることにします。
AIRとネイティブアプリケーションの通信
以下の形式の文字列で通信することにしました。間に改行は挟むことができず、最後は必ず改行で終了する必要があります(改行はデータの終端を意味します)。
顔1のx座標,顔1のy座標,顔1の幅,顔1の高さ;顔2のx座標,顔2のy座標,顔2の幅,顔2の高さ;顔3の・・・\n
このルールに沿った文字列をネイティブアプリケーションから標準出力し、AIR側の標準入力で受け取りパースします。
ちなみに似たような内容を先日のSparkProject勉強会で発表してきました。AIRからのネイティブアプリケーション起動、通信部分、終了に関するそれぞれのコードは発表資料に書いてあります。発表時にはWebCam Splitterのようなソフトウェアの存在を知らなかったために、AIRの透過ウィンドウをネイティブアプリケーションの上に重ねる方式になっています。
» SparkProject勉強会 発表資料
OpenCVでの顔検出にはcvHaarDetectObjects関数を用いました。画像から顔検出をする流れは以下のサイトがわかりやすかったです。各種SDKのインストールについても詳細に書いてあるので環境構築の参考にもなります。
» OpenCVを使って顔認識プログラムを作ってみた
今回のサンプルを作るにあたり、笑い男マークとTwitterアイコンを取得するAPIを以下のサイトからお借りしました。
» antina工作室
» tweetimag.es
感想
ネイティブアプリケーションとAIRの通信は思った以上に簡単でした。かつネイティブアプリケーションの強力なパワーを実感できて満足です。配布時にはネイティブアプリケーション自身やdllを、AIRのインストーラに含めることができるので、ユーザが実行環境を用意する手間もかなり省くことができます(今回はファイルサイズが大きくなるのでdllは含んでいません)。
OpenGLやDirectXで描画までおこなうものに比べれば非力ですが、うまく使えばFlashのメリットである描画やインターフェース構築の簡単さ、ネイティブアプリケーションのメリットである高速演算、それぞれをうまく引き出すことができると思います。
追記 10.08.10
デフォルトで使うOpenCVのバージョンを2.1に変更しました。OpenCV 1.0を使う場合は以下の記事の追記部分を参考にソースコードの一部およびパスを書き換えてください。
» C++とOpenCVでWebカメラを簡単に扱う
7月 30th, 2011 at 7:21 PM
[...] というすごい例が。 http://blog.alumican.net/2010/08/10_040647 [...]
1月 14th, 2012 at 6:46 PM
[...] 思い起こせば表参道での奥田さんとか、blogでのsaqooshaさんとか、F-siteでの山田さんとか。 [...]