iPhone/iPadスマートアプリ開発レシピ
iPhone/iPadスマートアプリ開発レシピ(3)

iOS 5の顔検出機能とカメラを使ったiPhoneアプリを作る


クラスメソッド株式会社
開発部 姫野悟志
2012/6/7

顔検出機能を扱うiOS 5の「CIDetector」

 まず、撮影した画像を受け取るにはUIImagePickerControllerDelegateプロトコルのimagePickerController:didFinishPickingMediaWithInfo:メソッドを実装します。

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    // 撮影画像を取得
    UIImage *originalImage = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
    // 撮影した写真をUIImageViewへ設定
    picture.image = originalImage;
    
    // 検出器生成
    NSDictionary *options = [NSDictionary dictionaryWithObject:CIDetectorAccuracyLow forKey:CIDetectorAccuracy];
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:options];
    
    // 検出
    CIImage *ciImage = [[CIImage alloc] initWithCGImage:originalImage.CGImage];
    NSDictionary *imageOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:6] forKey:CIDetectorImageOrientation];
    NSArray *array = [detector featuresInImage:ciImage options:imageOptions];
    
    // 検出されたデータを取得
    for (CIFaceFeature *faceFeature in array) {
        // 眼鏡画像追加処理へ
        [self drawMeganeImage:faceFeature];
    }
    
    // カメラUIを閉じる
    [self dismissViewControllerAnimated:YES completion:nil];
}

撮影画像を取得してUIImageViewへ設定

- PR -

 まず、引数であるinfoからUIImagePickerControllerOriginalImageをキーにして撮影した画像を取得し画面にセットします。

精度を設定して検出器生成

 次に顔検出を行うCIDetectorクラスのインスタンスを生成します。3つ目の引数として渡すNSDictionaryには、CIDetectorAccuracyキーでCIDetectorAccuracyLowとCIDetectorAccuracyHighのどちらかをセットします。これは名前の通り、検出の精度を表しています。

 CIDetectorAccuracyLowは検出精度は低いが、その分パフォーマンスが良くCIDetectorAccuracyHighは検出精度は高いが、その分パフォーマンスは悪くなります。

 筆者が試したところ、写真によっては、どちらを利用しても検出精度はあまり変わらないという感想を持っています。そのため、今回はパフォーマンスを重視してCIDetectorAccuracyLowにしています。

顔検出の実行

 次は、いよいよ顔検出です。先ほど撮影した画像はUIImageクラスでしたが、検出はCIImageクラスでないとできないため、CIImageのインスタンスを生成します。また、検出のオプションを生成しますが、ここでは写真の向きを表すCIDetectorImageOrientationキーを設定しています。

 撮影した画像のUIImageは向きを持っていますが、CIImageの時点で向きの情報は消えてしまいます。顔検出には写真の向きが必要になるため、「6」をCIDetectorImageOrientationキーとしてNSDictionaryを生成します。この「6」とは、ホームボタンが下にある状態で撮影した場合になります。

 検出には、CIDetectorクラスのfeaturesInImageメソッドを利用します。CIImageとNSDictionaryを引数とし、検出された顔の数だけNSArrayが返されます。このNSArrayには、検出された顔の数だけCIFaceFeatureが入っています。

検出した顔にメガネをかけさせよう

 顔検出で取得したCIFaceFeatureクラスからメガネの位置やサイズを決めていきます。

- (void)drawMeganeImage:(CIFaceFeature *)faceFeature
{
    if (faceFeature.hasLeftEyePosition && faceFeature.hasRightEyePosition && faceFeature.hasMouthPosition) {
    
        // 顔のサイズ情報を取得
        CGRect faceRect = [faceFeature bounds];
        // 写真の向きで検出されたXとYを逆さにセットする
        float temp = faceRect.size.width;
        faceRect.size.width = faceRect.size.height;
        faceRect.size.height = temp;
        temp = faceRect.origin.x;
        faceRect.origin.x = faceRect.origin.y;
        faceRect.origin.y = temp;
    
        // 比率計算
        float widthScale = picture.frame.size.width / picture.image.size.width;
        float heightScale = picture.frame.size.height / picture.image.size.height;
        // 眼鏡画像のxとy、widthとheightのサイズを比率似合わせて変更
        faceRect.origin.x *= widthScale;
        faceRect.origin.y *= heightScale;
        faceRect.size.width *= widthScale;
        faceRect.size.height *= heightScale;
    
        // 眼鏡のUIImageViewを作成
        UIImage *glassesImage = [UIImage imageNamed:@"megane.png"];
        UIImageView *glassesImageView = [[UIImageView alloc]initWithImage:glassesImage];
        glassesImageView.contentMode = UIViewContentModeScaleAspectFit;
 
        // 眼鏡画像のリサイズ
        glassesImageView.frame = faceRect;
    
        // 眼鏡レイヤを撮影した写真に重ねる
        [picture addSubview:glassesImageView];
    }
}

 CIFaceFeatureクラスには、左右の目の位置や口の位置などの情報が入っていますが、今回は顔の範囲であるboundsの値からメガネの位置やサイズを決めていきます。

 CIFaceFeatureクラスのboundsはCGRectクラスです。x、y、width、heightの値がありますが、前項で説明した通り、取得した値の画像の向きが正しくないため、xとy、widthとheightの値を入れ替える必要があります。

 入れ替えたら実際の画像サイズと表示されている画像サイズの比率を算出します。そして、顔の範囲のCGRectクラスを比率に合わせて修正していきます。

 最後にメガネ画像のUIImageViewクラスを作成し、frameにサイズを合わせたCGRectクラスを指定します。できたViewを撮影した画像のサブViewとして追加すれば完成です。

iOSの顔検出は難しくない

 今回はメガネの画像を、もともと人の顔と同じぐらいのサイズになるよう作成していたので、顔の範囲からメガネ画像の向きを決めましたが、もっと詳細にやる場合は、左右の目の位置や口の位置から正確にメガネの位置やサイズを決めることも可能です。

 また、詳細な位置を利用すれば、斜めになっている顔にもキレイにメガネをかけることが可能です。

 顔検出についての説明を重視したため、viewを重ねただけの、疑似的な画像表示となっていますが、CALayerクラスなどを利用して1枚の画像として作成すると、フォトライブラリへの保存なども可能になります。

 顔検出という名前から、難しそうなイメージはありますが、便利なクラスが用意されているので難しく考えずに、皆さんいろいろと試してみてください。

■ @IT関連記事


iPhoneアプリ開発入門
盛り上がるiOS(iPhone・iPad・iPod touch)アプリ開発。そのハウツーや魅力に関する@IT記事一覧です

画像をタッチ編集! アートなiPhoneカメラアプリを作る
Retinaに映える! iOS美麗アプリ制作入門(3) カメラの起動やピクセル情報の扱いが簡単なopenFrameworksを使ってタッチやドラッグで画像の色見を変えるアプリを作ろう
Smart & Social」フォーラム 2012/5/8
iPhoneで動くARアプリを作るためのライブラリ10選
モバイルARアプリ開発“超”入門(5)
 ARToolkitをはじめ、iOS(iPhone/iPad)で使えるAR(拡張現実)を実現するためのさまざまなライブラリをサンプルやコードを交えて紹介
Smart & Social」フォーラム 2012/1/25
グランプリは生徒と先生が作った役に立つAR
D89クリップ(34) 
今年のiPhone・iPadアプリ大賞を勝手に決めてしまうイベントで、最終プレゼンに選ばれた12組のアプリを紹介します
Web RTC、Face.jsとJSARToolkitのお味は?
HTML5の味見しちゃうよ(1) 
Web RTC、Face.jsとJSARToolkitを試した。JavaScriptを使って、Webカメラで顔認識とAR(拡張現実)してみよう
ARに使えるOpenCVで作る画像認識Androidアプリ
モバイルARアプリ開発“超”入門(終)
 オープンソースのコンピュータヴィジョンライブラリ「OpenCV」を利用した画像認識アプリの作成について簡単なサンプルを交え解説
Smart & Social」フォーラム 2012/3/1
Android 4.0で注目の顔認識をアプリに組み込むには
Androidで動く携帯Javaアプリ作成入門(28)
 カメラを使った画面アンロック、オートフォーカス、ライブエフェクトなど応用例が多彩な顔認識機能を使うための基礎知識を解説
Smart & Social」フォーラム 2012/1/18
もはやケータイに必須のカメラをAndroidで制御しよう
Androidで動く携帯Javaアプリ作成入門(17) 
標準カメラ制御用APIを解説します。起動・終了・撮影だけでなくフォーカスやフラッシュなども制御できます。ARに応用も!?
Smart & Social」フォーラム 2010/5/27
App InventorでもAndroidで人気のカメラアプリを作る
App Inventorでアプリ開発はどこまでできるのか(4) App Inventorのカメラ部品の概要、JavaのAPIで扱うときとの違いを解説し簡単な落書きカメラアプリの作り方を紹介する
Smart & Social」フォーラム 2011/7/19
Windows Phoneで動くカメラアプリ作成の基礎知識
Silverlightベースで作るWP7アプリ開発入門(7)
 iPhoneやAndroidでも人気のカメラを使ったアプリの作り方の基本としてプレビュー表示や撮影画像の保存方法を解説
Smart & Social」フォーラム 2011/12/2
Silverlightで作れるAR(拡張現実)アプリの基礎知識
楽しいWindows 7アプリ作成入門(4) 
オープンソースライブラリ「NyARToolkitCS」「SLARToolkit」の登場でWPF、C#、Silverlight環境でもARが体験できるようになりました

1-2  

 INDEX
iPhone/iPadスマートアプリ開発レシピ(3) 
iOS 5の顔検出機能とカメラを使ったiPhoneアプリを作る
  Page1
カメラと顔検出を利用したメガネアプリ
いまさら聞けない顔“検出”と顔“認識”の違い
カメラ機能を扱うiOSの「UIImagePickerController」
Page2
顔検出機能を扱うiOS 5の「CIDetector」
検出した顔にメガネをかけさせよう
iOSの顔検出は難しくない



 Smart&Social フォーラム トップページへ



Smart & Social フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Smart & Social 記事ランキング

本日 月間