UIImage人脸检测

8
我正在尝试编写一个程序,它接收UIImage并返回一个只包含脸的新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个回答

5

使用CIContext从图像中裁剪人脸要简单得多且不会弄乱。代码示例如下:

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

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


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);

这个非常有效。

5
我正在研究同样的事情,你能解释一下你为y轴执行的计算吗?还有什么是“largestface”? - Rory Lester

0

要实现这个并不简单,问题在于iPhone相机拍摄的图像始终处于竖屏模式,需要使用元数据设置来使它们正确显示。如果您事先告诉面部检测调用图像的旋转方向,还可以获得更好的准确性。为了让事情变得复杂,您必须以EXIF格式传递图像方向。

幸运的是,苹果有一个名为Squarecam的示例项目,涵盖了所有这些内容,建议您查看详情。


是的,我已经考虑到图像旋转的问题了。我的问题与UIImage和CG例程的不同起点有关。 - Tim Sullivan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接