CIDetector和UIImagePickerController

ton*_*nyc 5 core-image face-detection orientation ios cifacefeature

我正在尝试实现内置的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);
}
Run Code Online (Sandbox Code Playgroud)

这总是返回0个功能.但是,如果我从应用程序内置的文件中使用UIImage,则人脸检测效果很好.

我正在使用这篇Pragmatic Bookshelf文章中的代码.

对于它的价值,我认为错误是当我将UIImage从相机转换为CIImage时,但它可能是任何东西.

Xia*_*ang 19

@tonyc您的解决方案仅适用于"UIImageOrientationRight"的特定情况.问题来自UIImage和CIDetectorImageOrientation中的方向之间的差异.来自iOS文档:

CIDetectorImageOrientation

用于指定要检测其要素的图像的显示方向的键.此键是一个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]}];
Run Code Online (Sandbox Code Playgroud)