要は、顔検出部分に画像を配置するだけなんですが、ちょっと引っかかったのでメモ。
この手のサンプルはたくさんあるけど、大体がCIFilter使ってるパターンが多いので、その部分をUIImageで描画すればいいんじゃないかってメドをつけたんだけど、なかなかうまく行かなかった。大まかにいうと下記の点。
1.UIImageで描画する際に、y方向の座標が逆になる。
通常、左上が(0,0)になると思ってたんだけど、y方向は画像の左下が(0,0)になっているようで、その点を描画時に補正。
2.カメラ/カメラロールの画像の向き
iPhoneで撮影されたデータは、UIImage.imageOrientationに向きを持っている。
参考:まみったー iPhone の向きと UIImageOrientation メモ
で、この向きが縦位置の時にうまくいかなかったので、色々調べたら、一度、UIImageで書き直してしまえば問題ないらしい。
これはちょっと勘違いがありましたので、詳しくはこちらを。
参考:iPhoneカメラで撮影した画像のUIImageからCGImageを取り出すと90度傾く問題の解決法
これで基本的には問題ないようです。
一応、該当部分のソースはこんな感じです。
- (IBAction)checkFace2:(UIBarButtonItem *)sender { //UIImage.imageOrientationの値によって動作が異なるので、元画像を再描画しておく。 UIImage *orgImage =[UIImage imageWithCGImage:_originalImage.CGImage]; UIGraphicsBeginImageContext(orgImage.size); [orgImage drawInRect:CGRectMake(0, 0, orgImage.size.width, orgImage.size.height)]; orgImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); CIImage *coreImage = [CIImage imageWithCGImage:orgImage.CGImage]; //オプション辞書作成(顔検出の精度/高精度) NSDictionary *options = [NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh forKey:CIDetectorAccuracy]; //CIDetectorを生成(画像解析/現在は顔検出のみ指定可能) CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:_imageContext options:options]; //顔検出(位置情報を配列で返す) NSArray *faces = [faceDetector featuresInImage:coreImage options:nil]; //顔部分に画像を載せる for(CIFaceFeature *face in faces){ NSLog(@"---check"); coreImage = [CIFilter filterWithName:@"CISourceOverCompositing" keysAndValues:kCIInputImageKey, [self makeIconForFace:face], kCIInputBackgroundImageKey, coreImage, nil].outputImage; } CGImageRef cgImage = [_imageContext createCGImage:coreImage fromRect:[coreImage extent]]; //image化するときの向きは、オリジナルに合わせないと横になる。何で? _myImageView.image = [UIImage imageWithCGImage:cgImage scale:1.0f orientation:_myImageView.image.imageOrientation]; CGImageRelease(cgImage); }
//顔にアイコンを描画 - (CIImage*)makeIconForFace:(CIFaceFeature*)face{ // アイコンのUIImageを作成 UIImage *iconImage = [UIImage imageNamed:@"icon_250_reasonably_small.jpg"]; // 顔のサイズ情報を取得 CGRect faceRect = [face bounds]; int w = _originalImage.size.width; int h = _originalImage.size.height; int cx = faceRect.origin.x; int cy = faceRect.origin.y; int icon_w = faceRect.size.width; int icon_h = faceRect.size.height; //アイコンを顔サイズで描画(yは左下原点になるようなので補正) UIGraphicsBeginImageContext(CGSizeMake(w, h)); [iconImage drawInRect:CGRectMake(cx, h - (cy + icon_h), icon_w, icon_h)]; UIImage *iconImage_after = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); CIImage *image = [CIImage imageWithCGImage:iconImage_after.CGImage]; return image; }
テスト結果はこんな感じ。
テスト環境:iPhone5+Xcode 5.1.1
「iOSの顔検出を画像で表示する」への1件のフィードバック
コメントは停止中です。