UIImage人脸检测

时间:2012-02-23 19:51:08

标签: ios xcode core-graphics face-detection

我正在尝试编写一个带有UIImage的例程,并返回一个只包含face的新UIImage。这看起来非常简单,但是我的大脑在绕过CoreImage和UIImage空间时遇到了问题。

以下是基础知识:

- (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect {
    CGImageRef sourceImageRef = [image CGImage];
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
    CGImageRelease(newImageRef);
    return newImage;
}


-(UIImage *)getFaceImage:(UIImage *)picture {
  CIDetector  *detector = [CIDetector detectorOfType:CIDetectorTypeFace 
                                             context:nil 
                                             options:[NSDictionary dictionaryWithObject: CIDetectorAccuracyHigh forKey: CIDetectorAccuracy]];

  CIImage *ciImage = [CIImage imageWithCGImage: [picture CGImage]];
  NSArray *features = [detector featuresInImage:ciImage];

  // For simplicity, I'm grabbing the first one in this code sample,
  // and we can all pretend that the photo has one face for sure. :-)
  CIFaceFeature *faceFeature = [features objectAtIndex:0];

  return imageFromImage:picture inRect:faceFeature.bounds;
}

返回的图像来自翻转图像。我尝试使用以下内容调整faceFeature.bounds

CGAffineTransform t = CGAffineTransformMakeScale(1.0f,-1.0f);
CGRect newRect = CGRectApplyAffineTransform(faceFeature.bounds,t);

...但是这给了我图像之外的结果。

我确信有一些简单的方法可以解决这个问题,但是如果没有计算自下而上,然后使用它作为X创建一个新的矩形,是否有“正确”的方法来做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:5)

使用CIContext从图像中裁剪脸部会更容易,也更简洁。像这样:

CGImageRef cgImage = [_ciContext createCGImage:[CIImage imageWithCGImage:inputImage.CGImage] fromRect:faceFeature.bounds];
UIImage *croppedFace = [UIImage imageWithCGImage:cgImage];

其中 inputImage 是您的UIImage对象,而 faceFeature 对象的类型为CIFaceFeature,您可以从 [CIDetector featuresInImage:] 方法获得。

答案 1 :(得分:3)

由于似乎没有一种简单的方法可以做到这一点,我只是写了一些代码来做到这一点:

CGRect newBounds = CGRectMake(faceFeature.bounds.origin.x, 
                              _picture.size.height - faceFeature.bounds.origin.y - largestFace.bounds.size.height, 
                              faceFeature.bounds.size.width, 
                              faceFeature.bounds.size.height);

这很有魅力。

答案 2 :(得分:0)

没有简单的方法可以实现这一点,问题是来自iPhone相机的图像始终处于纵向模式,并且元数据设置用于使它们正确显示。如果您事先告诉它图像的旋转,您的面部检测调用也会获得更好的准确性。只是为了使事情变得复杂,你必须以EXIF格式传递图像方向。

幸运的是,有一个苹果样本项目涵盖了所有这一项Squarecam,我建议您查看详细信息