iOS相机人脸检测

8

我收到了一个图片视图

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = info[UIImagePickerControllerMediaType];

    [self dismissViewControllerAnimated:YES completion:nil];

    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
        UIImage *image = info[UIImagePickerControllerOriginalImage];

        //imgvprofileImage.image = image;
        //[self detectForFacesInUIImage:[UIImage imageNamed:@"image00.jpg"]];

        [self detectForFacesInUIImage:image];
    }
    else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
    {
        // Code here to support video if enabled
    }
}

当我发送这样的照片时:
[self detectForFacesInUIImage:[UIImage imageNamed:@"image00.jpg"]]; 

检测功能良好,可以找到人脸,但使用摄像头返回的图像时无法正常工作。
 [self detectForFacesInUIImage:image]

这是我用来检测人脸的函数。
-(void)detectForFacesInUIImage:(UIImage *)facePicture
{
    CIImage* image = [CIImage imageWithCGImage:facePicture.CGImage];

    CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:[NSDictionary dictionaryWithObject:CIDetectorAccuracyLow forKey:CIDetectorAccuracy]];

    NSArray* features = [detector featuresInImage:image];

    if (features.count == 0) {
        NSLog(@"There is no faces in captured image ") ;
    }

    for(CIFaceFeature* faceObject in features)
    {
        CGRect modifiedFaceBounds = faceObject.bounds;
        modifiedFaceBounds.origin.y = facePicture.size.height-faceObject.bounds.size.height-faceObject.bounds.origin.y;

        [self addSubViewWithFrame:facePicture toRect:modifiedFaceBounds] ;
    }
}
2个回答

5

问题出现在图片方向上。

我不记得这张照片是在哪里拍的,但以下方法有效:

- (void) detectForFaces:(CGImageRef)facePicture orientation:(UIImageOrientation)orientation {


    CIImage* image = [CIImage imageWithCGImage:facePicture];

    CIContext *context = [CIContext contextWithOptions:nil];                    // 1
    NSDictionary *opts = @{ CIDetectorAccuracy : CIDetectorAccuracyLow };      // 2
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace
                                              context:context
                                              options:opts];                    // 3

    int exifOrientation;
    switch (orientation) {
        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;
    }


    opts = @{ CIDetectorImageOrientation :[NSNumber numberWithInt:exifOrientation
                                           ] };

    NSArray *features = [detector featuresInImage:image options:opts];

    if ([features count] > 0) {
        CIFaceFeature *face = [features lastObject];
        NSLog(@"%@", NSStringFromCGRect(face.bounds));
    }
}

如何使用:
UIImage *image = // some image here;
[self detectForFaces:image.CGImage orientation:image.imageOrientation];

当我在裁剪图像之前,它完全是脸部,但现在不准确了吗? - mohamed
您可以尝试在选项中更改准确性,但应该保持相同的功能。 - Volodymyr B.
准确性取决于图像的质量和大小!方向不应对其产生影响。如果您想,可以轻松旋转图像并尝试使用正确的图像方向来确定是否不是这种方法。 - Volodymyr B.
@mohamed 你确定你在ImageView中显示的图片没有变形吗?使用默认选项,内容可以被缩放以适应视图。如果你确实像那样检查了...还是再检查一下吧。 - Volodymyr B.
@mohamed 好的,我不知道这个方法周围发生了什么,所以无法提供帮助。继续努力找到问题所在。 - Volodymyr B.
显示剩余8条评论

2

这里需要进行一个小修正。

- (void) detectForFaces:(UIImage *)facePicture orientation:(UIImageOrientation)orientation {


CIImage* image = [CIImage imageWithCGImage:facePicture.CGImage];

CIContext *context = [CIContext contextWithOptions:nil];                    // 1
NSDictionary *opts = @{ CIDetectorAccuracy : CIDetectorAccuracyLow };      // 2
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace
                                          context:context
                                          options:opts];                    // 3

int exifOrientation;
switch (orientation) {
    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;
}


opts = @{ CIDetectorImageOrientation :[NSNumber numberWithInt:exifOrientation
                                       ] };

NSArray *features = [detector featuresInImage:image options:opts];

if ([features count] > 0) {
    CIFaceFeature *face = [features lastObject];
    NSLog(@"%@", NSStringFromCGRect(face.bounds));
}}

UIImage *image = // 这里有一些图像; [self detectForFaces:image orientation:image.imageOrientation];

只发送 image 而不是 image.CGImage 这对我很有效


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