iOS5の顔認識を使ってみた | モンスター・ラボTech/Designブログ

モンスター・ラボTech/Designブログ

株式会社モンスター・ラボのテクノロジスト、デザイナーによる持ち回りブログです。



技術系の仕事してます。
泉と申します。(_ _)>


遊んでる訳じゃありません。仕事の為に、先にいろいろ実験してるんです。
言い訳じゃないですよ。


iOS5に搭載された顔認識機能を使ってなんか作ろうと思って遊んでみましたが
まだweb上にあんまりサンプルがないのと、幾つかハマったポイントがあるので
書いとこうと思います。(技術系の人でないとさっぱり分からんと思いますが)
ただ、iPhoneいじり始めで怪しい部分が多々あるのでまんま信じないでください。




●やろうとしたこと
 iDetectが左右の目と口の位置が検出してくるので、
 ビデオ入力(640*480)でリアルタイムで顔認識して、目の状態変化を追って
 目の位置にレイヤーかける様なこと


●ハマったポイント
 iDetectorの検出設定と出力される座標方向、ビデオバッファの座標、
  画面との位置合わせの座標関係が????だった。
 


【検出設定】
 ここは普通に資料でわかりますが、iphoneを縦に普通にもってる状態、横構え状態などで
 カメラに対する顔の方向が変わるので、これをまず設定せねばなりません。


   NSNumber* orientation=[NSNumber numberWithInt:orientation_];  
   NSDictionary* foptions=[NSDictionary dictionaryWithObject:orientation    
   forKey:CIDetectorImageOrientation];


  ただ、デフォルトが横構えになってるのと、OpenGLとか使う場合など、
 再定義する必要があるケースがあり、なにを入れればいいの?となるので
 orientation_になにが入るのと言うと、だいたい下の様になります。
 (縦持ち以外はまだ動かしてないので間違ってたらごめんなさい)


  switch (orientation) {
    case UIInterfaceOrientationLandscapeLeft:
        orientation_=1;
        break;

        orientation_=3;
        break;

      orientation_=5; 
        break;

      orientation_=7;
        break;
      default:break;
   }




【iDetectから出力される座標方向】
   検出方向で、縦だとか横だとか設定するにも関わらず、iDetectorの返す座標は、
  横に構えたときの座標になります。(0,0)は横に構えた場合の左下すみです。


・横構えで見てるとき   
----------640------------
|                   
|     目      目
|         口

(0,0)→ -----------------
  


・縦構えで見てるときも基準位置は横のときのままです。
 つまり、縦に構えてるときは、xy逆に考える必要があるということです。


(0,0)→--480--
↓     
|
|  目 目
640   口
|
|
| -----------




【ビデオバッファの座標方向】
 検出した目とか口の部分の画像情報を取ったり、ARするのに重ねたりするとかすると
 対応する位置のビデオのピクセルバッファを取得する必要があります。
 
 bitmapなんかを触った人は経験があると思いますが、bitmapだとピクセルバッファは
 画面の下から入っています。が、そうだと思ったら逆でした。
 逆にiOS良くできてるな~と思います。


  *こっちの左右は、videoのinput設定でミラーとかすると変わりますので、
  別途注意がいります。




(0,0)→ ------640-----
↓                 
|     目    目 
480      口
|
 --------------------


 
【画面との合わせ】
 バッファをいじるのでなく、上にレイヤーとか重ねようとする場合、
 ビデオのバッファが640*480だとしても、画面は320*460?だっけ?なので、
 比率を調整しないと、位置が合いません。
  縦に構えてる場合などは以下の様にすればとりあえず合います。
   f.leftEyePosition.y*preview_.frame.size.width/480;
   f.leftEyePosition.x*preview_.frame.size.height/640;
   f.rightEyePosition.y*preview_.frame.size.width/480;
   f.rightEyePosition.x*preview_.frame.size.height/640;




今回はとりあえずこれだけ。
ではまた。