Marilenaでアイドル(1)

080625.jpg

先日参加したてらこで発表をしてきました。

その解説をしたいと思います。

ほとんどがライブラリをいじっただけ、ですし、そのライブラリの内容もあまりよくわかってなかったりしますが、
気が向いているので詳しく解説してみたいと思います。

概要

今回のてらこのテーマは「アイドル」でした。

先に言ってしまうと、元ネタは「100チアガール」です。
(サイトはもう落ちてしまっているようですね、、。残念)
このサイトの動画のサムネイル部分がなんかエロくて、これを真似してみました。
百聞は一見に如かず、実際に作ったものです。

100アイドル

※注意!!!!※
とてつもなく重いです。
スペックの高くないPCだとブラウザが落ちることがあります。
(うちのMacBookも唸りを上げています)
また、最低でも表示されるまでに数分はかかると思います。

どうしても表示されない、そんなに待てるか!、等の方は、読み込む枚数を減らしたバージョンをどうぞ。
100アイドルMIni

顔の部分を半分見えなくすることでエロさを醸し出しているわけですね。

さて、一体何をやっているのかを簡単に説明しますと、
Flickrで、「idol」で検索した画像を取得 → その画像から顔の部分を検出 → その顔の位置から適当な範囲にマスクをかけ、エロい画像を作成
と、いった感じです。

今日はその顔認識の部分について解説したいと思います。

顔認識はどうするのか

顔認識をいかにして実現するかがこの作品のキーポイントだったわけですが、
そんな時にCUPPYの人が顔認識のライブラリを公開されました。
ですので、顔認識にはこのMarilena Object Detection in AS3(以下Marilena)を使用しました。

他にも顔認識のサービスで、顔ラボというAPIもあるのですが、
Flashで使えるかわからないし、APIにも回数制限があったりしましたし、
Flash内で完結できるならそっちのほうがいいだろう、ということで、使ってみました。

準備

まずはSpark projectよりMarilenaをダウンロード
ダウンロードはSVNで落としてくるのが楽です。
(リンク先はwin環境の場合です。macの場合は以前に簡単に説明しましたので、参考にどうぞ)

とりあえずコンパイル

Flexの使い方はわからん(持ってないし)ので、Flash CS3でのコンパイルの仕方を説明します。
まず、trunk/src/以下にパスを通します。

新しいフォルダを作り、trunk/samples/の中にある、「face.zip」と、「013.jpg」のファイルと、
trunk/src/の中にある、「FaceDetector.as」の3ファイルをコピーします。
trunk/src/の中の「FaceDetector.as」は削除します。

で、新規にAS3ドキュメントを作り、プロパティにある、ドキュメントクラスに、FaceDetectorを指定します。
marilena01.jpg
(フレームレートはいくつでもいいです)

で、FaceDetector.as等をコピーしたフォルダに適当な名前で保存します。
あとは「ムービーのプレビュー」をしてみましょう。
めでたくサンプルと同じものが出来上がったはずです。

よくわからないけど中を見る

さてさて、とりあえず動きました。
しかし、今の状態だと、帽子をかぶった女の人しか出てきません。アイドルは出てきません。
ですので、とりあえず、写真を変えてみることにします。

もちろん、013.jpgの名前で違う写真を上書きすれば変更することが出来ます。
写真を変更すると、その写真に対して顔認識をしてくれるので、それで色んな写真を試してみるだけでも面白いです。

FaceDetector.asの中を見ていきます。
30行目あたりにある、コンストラクタの部分で画像のURLが指定されています。

ACTIONSCRIPT:
  1. public function FaceDetector() {
  2. initUI();
  3. initDetector();
  4. faceImage.load( new URLRequest("<b>013.jpg</b>") );
  5. }

この部分を変更すると画像を変更できます。
これは画像のURLなんで、ここにFlickrから取ってきた画像のURLを入れればそれが表示されるはず!ということがわかります。

読み込まれた画像を解析し終わると、64行目にある、

ACTIONSCRIPT:
  1. detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE,function( e :ObjectDetectorEvent ):void{

の中が実行されます。
元ファイルでは一行でまとめて書かれていますが、これを、

ACTIONSCRIPT:
  1. detector.addEventListener(ObjectDetectorEvent.DETECTION_COMPLETE, onDetectionComplete);<br><br>function onDetectionComplete(e :ObjectDetectorEvent ):void{<br>  //処理<br>}

と分けてやることも可能です。

(余談ですが、イベントの発生時に引数を渡す方法がここに載っていました。)

で、この処理の中の、69行目あたりの、

ACTIONSCRIPT:
  1. if( e.rects ){
  2. var g :Graphics = faceRectContainer.graphics;
  3. g.clear();
  4. g.lineStyle( 2 );   // black 2pix
  5. e.rects.forEach( function( r :Rectangle, idx :int, arr :Array ) :void {
  6. g.drawRect( r.x, r.y, r.width, r.height );
  7. });
  8. }

の、部分で、顔と認識されたエリアに枠線をつけています。
ここを見ていると、顔のエリアは、Rectangleで表されるようです。
これで顔のエリアの値を取得する方法がわかりましたので、ここから適当に足し引きすれば、目的のエリアの値を取得できそうです。

その他はよくわからない事もあって、特に触っていません。
あと、てらこで同じMarilenaを使って発表されてたみのんさんによると、
97行目にある、

ACTIONSCRIPT:
  1. options.min_size  = 50;

が、どれだけの小ささの顔を検知させるか、を表しているようです。
(小さくすれば精度は上がるが、パフォーマンスがわるくなります)

で。

Marilenaは、OpenCVのObjectDetectionの部分を、AS3に移植にしたもの、みたいです。
本家のOpenCV版では顔だけでなく、様々なものを認識できるようです。

このAS3版でも、同じフォルダに入れている、face.zipが、顔を認識させるためのファイル(パターンファイル)のようで、
これを違うパターンファイルに変更すれば色々なものが認識できるようですが、、、、誰か試して下さい、、。

このパターンファイルですが、

認識に使うxmlは一度zipに圧縮した後、Adler32 checksumというのを付加するスクリプト(tools/fzip-prepare.py)を通してください。そのアウトプットを読み込むようになってます。

Marilena - Spark Projectより

だ、そうですが、このfzip-prepare.pyをどう使ったらいいのかが全くわかりません。
(Pythonという言語のファイルだそうです。)

参考サイト

Marilena関係
Marilena Object Detection in AS3|_level0.CUPPY
mash/Marilena - Spark project
minomix blog » 大阪てら子 16 の感想とか発表したやつとか

OpenCV関係
Hacking is believing@itoshi.tv - MacBook ProへOpenCVをインストールして, iSightで顔認識したりするぞ (動画付き)
Milano::Monolog: ブログの画像から顔写真だけを抜き出してRSSにする
特集:OpenCVで学ぶ画像認識|gihyo.jp ... 技術評論社

OpenCVは全く何も触ってないので、全くわかりません、、。
てか、C++とかわからんし、、。

次回はFlickrの読み込み部分を書いてみたいと思います。

つづく、、。

・Marilenaシリーズ
Marilenaでアイドル(2)
Marilenaでアイドル(3)


About this entry