我正在尝试实现内置的iOS 5人脸检测API。我正在使用UIImagePickerController
实例来允许用户拍照,然后我尝试使用CIDetector
来检测面部特征。遗憾的是,featuresInImage
总是返回大小为 0 的数组。
代码如下:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage* picture = [info objectForKey:UIImagePickerControllerOriginalImage];
NSNumber *orientation = [NSNumber numberWithInt:
[picture imageOrientation]];
NSDictionary *imageOptions =
[NSDictionary dictionaryWithObject:orientation
forKey:CIDetectorImageOrientation];
CIImage *ciimage = [CIImage imageWithCGImage:[picture CGImage]
options:imageOptions];
NSDictionary *detectorOptions =
[NSDictionary dictionaryWithObject:CIDetectorAccuracyLow
forKey:CIDetectorAccuracy];
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace
context:nil
options:detectorOptions];
NSArray *features = [detector featuresInImage:ciimage];
NSLog(@"Feature size: %d", features.count);
}
这始终返回 0 个特征。但是,如果我使用内置到应用程序中的文件中的 UIImage,则人脸检测效果很好。
我正在使用这篇实用书架文章中的代码。
对于它的价值,我认为错误在于我将UIImage从相机转换为CIImage时,但它可能是任何东西。
@tonyc 您的解决方案仅适用于"UIImageOrientationRight"的特定情况。问题来自UIImage和CIDetectorImageOrientation中方向之间的差异。从 iOS 文档:
CIDetectorImageOriented
用于指定要检测其要素的图像的显示方向的键。此键是一个 NSNumber 对象,其值与 TIFF 定义的值相同,并且EXIF规格;值的范围为 1 到 8。价值指定图像的原点 (0,0) 所在的位置。如果不是存在,默认值为 1,表示图像的原点为上,左。有关每个值指定的图像来源的详细信息,参见 kCGImagePropertyOrientation。
在 iOS 5.0 及更高版本中可用。
在CIDetector.h中声明。
所以现在的问题是这两个方向之间的转换,这是我在我的代码中所做的,我测试了它适用于所有方向:
int exifOrientation;
switch (self.image.imageOrientation) {
case UIImageOrientationUp:
exifOrientation = 1;
break;
case UIImageOrientationDown:
exifOrientation = 3;
break;
case UIImageOrientationLeft:
exifOrientation = 8;
break;
case UIImageOrientationRight:
exifOrientation = 6;
break;
case UIImageOrientationUpMirrored:
exifOrientation = 2;
break;
case UIImageOrientationDownMirrored:
exifOrientation = 4;
break;
case UIImageOrientationLeftMirrored:
exifOrientation = 5;
break;
case UIImageOrientationRightMirrored:
exifOrientation = 7;
break;
default:
break;
}
NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh }; // TODO: read doc for more tuneups
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:detectorOptions];
NSArray *features = [faceDetector featuresInImage:[CIImage imageWithCGImage:self.image.CGImage]
options:@{CIDetectorImageOrientation:[NSNumber numberWithInt:exifOrientation]}];
果然,在花了一天时间研究这个问题并被难倒之后,我在发布这个一小时后找到了解决方案。
我最终注意到人脸检测确实适用于横向,但不适用于纵向。
事实证明我需要这些选项:
NSDictionary *imageOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:6]
forKey:CIDetectorImageOrientation];
NSArray *features = [detector featuresInImage:ciimage options:imageOptions];
Swift 3 版本
var exifOrientation : Int
switch (inputImage.imageOrientation)
{
case UIImageOrientation.up:
exifOrientation = 1;
case UIImageOrientation.down:
exifOrientation = 3;
case UIImageOrientation.left:
exifOrientation = 8;
case UIImageOrientation.right:
exifOrientation = 6;
case UIImageOrientation.upMirrored:
exifOrientation = 2;
case UIImageOrientation.downMirrored:
exifOrientation = 4;
case UIImageOrientation.leftMirrored:
exifOrientation = 5;
case UIImageOrientation.rightMirrored:
exifOrientation = 7;
}
let ciImage = CIImage(cgImage: inputImage.cgImage!)
let options = [CIDetectorAccuracy: CIDetectorAccuracyHigh]
let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: options)!
let faces = faceDetector.features(in: ciImage, options:["CIDetectorImageOrientation":exifOrientation])
我遇到了类似的问题 - 人脸检测器的工作方向与图像方向属性不匹配。iOS 人脸检测器方向和 CIImage 方向设置
我发现可以帮助解决这个问题的一个快速解决方法是一起忽略图像方向并"展平"图像(这样就没有图像方向数据)
我使用了以下代码:
http://blog.logichigh.com/2008/06/05/uiimage-fix/
果然,它看起来对于前置摄像头照片的效果要好得多。我对景观的尝试还不够,无法判断它是否对那里有所帮助,但看起来很有希望