iOS5から使えるようになったCIDetectorがiOS7で更に進化し、笑顔やまばたき(目をつぶっているかどうか)を検出可能となりました。

すごく簡単に実装できる上に処理も遅くないのでいろいろな使い道があると思います。

下準備

まずCoreImageフレームワークをプロジェクトに追加しておきます。

検出

 1CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace
 2                                          context:nil
 3                                          options:@{CIDetectorAccuracy: CIDetectorAccuracyLow}];
 4
 5CIImage* image = [CIImage imageWithCGImage:uiimage.CGImage];
 6NSArray *features = [detector featuresInImage:image
 7                                      options:@{ CIDetectorSmile:@YES,
 8                                                 CIDetectorEyeBlink:@YES,
 9                                                 CIDetectorImageOrientation:[NSNumber numberWithInt:[self exifOrientation:uiimage]]
10                                                 }
11                     ];
12
13
14for(CIFaceFeature* face in features){ 
15    // faceを使って何かする(矩形を描画する、など)
16}

画像の向きについて

iOSデバイスのカメラで撮影した画像の場合、撮影時のデバイスの向きに応じて内部的に方向を持っています。その方向というのをCIDetectorfeaturesInImageに渡してあげないと正しく検出されません。

uiimage.imageOrientation によって渡すべき値がことなるので、次のようなメソッドを定義して使いました。

 1- (NSUInteger)exifOrientation:(UIImage*)image
 2{
 3    NSUInteger orientation = 0;
 4    switch (image.imageOrientation) {
 5        case UIImageOrientationUp:
 6            orientation = 1;
 7            break;
 8        case UIImageOrientationDown:
 9            orientation = 3;
10            break;
11        case UIImageOrientationLeft:
12            orientation = 8;
13            break;
14        case UIImageOrientationRight:
15            orientation = 6;
16            break;
17        case UIImageOrientationUpMirrored:
18            orientation = 2;
19            break;
20        case UIImageOrientationDownMirrored:
21            orientation = 4;
22            break;
23        case UIImageOrientationLeftMirrored:
24            orientation = 5;
25            break;
26        case UIImageOrientationRightMirrored:
27            orientation = 7;
28            break;
29        default:
30            break;
31    }
32    return orientation;
33
34}

笑顔・まばたきの検出

featuresInImageに渡すオプションに笑顔を検出するかどうか、まばたきを検出するかどうかというオプションを追加しておくと、帰ってくるCIFaceFeatureにそれらの情報が入ってくるようになります。

今回は両方ともYESとしておきました。

CIFaceFeature

次のようなプロパティを持ちます。

  • bounds
  • leftEyePosition
  • rightEyePosition
  • mouthPosition
  • hasSmile
  • leftEyeClosed
  • rightEyeClosed

hasSmileleftEyeClosedなどで笑顔やまばたきがわかりますね。

フリー写真を使って試してみた

こんな感じです。 ちゃんと笑顔フラグも取れました。