iOS 基于CIDetector的人脸检测

时间:2024-03-07 13:33:45

  首先了解一下iOS里的CoreImage,CoreImage是一种图像处理和分析技术,旨在为静态和视频图像提供近实时处理。它使用GPU或CPU渲染路径,对Core Graphics,Core Video和Image I / O框架中的图像数据类型进行操作。Core Image通过提供易于使用的应用程序编程接口(API)隐藏了低级图形处理的细节。您不需要了解OpenGL,Op​​enGL ES或Metal的细节来充分利用GPU的强大功能,也无需了解Grand Central Dispatch(GCD)以获得多核处理的优势。Core Image为您处理细节。

 

 Core Image框架提供:

  • 访问内置图像处理过滤器

  • 特征检测功能

  • 支持自动图像增强

  • 将多个过滤器链接在一起以创建自定义效果的功能

  • 支持创建在GPU上运行的自定义过滤器

  • 基于反馈的图像处理功能

显然这个框架十分强悍!文档上也说了CoreImage所做的是人脸检测而非人脸识别,写了一个小demo学习一下基于CIDetector的人脸检测。

//检测的图片,注意调整一下尺寸否则检测出来的位置对不上
    UIImageView * imgView = [[UIImageView alloc] initWithFrame:self.view.bounds];
    [imgView setImage:[UIImage imageNamed:@"myImage"] ];
    [self.view addSubview:imgView];
    
    //检测出来的结果位置Y轴和图像本身的Y轴是相反的,这里我就拿一个view装载结果将它反转就能看出效果了
    UIView * view = [[UIView alloc] initWithFrame:self.view.bounds];
    [view setTransform:CGAffineTransformMakeScale(1, -1)];
    [self.view addSubview:view];
    
    //CoreImage用于处理或生成的图像类型
    CIImage * myImage = [[CIImage alloc] initWithCGImage:imgView.image.CGImage options:nil];
    
    //用于渲染图像处理结果和执行图像分析的评估上下文
    CIContext * context = [CIContext context];
    
    //检测器的设置
    NSDictionary * opts = @{
                             CIDetectorAccuracy : CIDetectorAccuracyHigh , //检测精度
//                             CIDetectorEyeBlink : [NSNumber numberWithBool:true], //眼睛是否闭着
//                             CIDetectorSmile : [NSNumber numberWithBool:true] //是否微笑
                             };
    
    //检测器
    CIDetector * detector = [CIDetector detectorOfType:CIDetectorTypeFace
                                              context:context
                                              options:opts];
    
    //CoreImage返回一个CIFeature对象数组,每个对象代表图像中的一个面
    NSArray * features = [detector featuresInImage:myImage options:opts];
    
    //遍历检测结果
    for (CIFaceFeature * f in features) {
        NSLog(@"%@,%@,左眼%@,右眼%@", NSStringFromCGRect(f.bounds),f.hasSmile?@"":@"没笑",f.leftEyeClosed?@"闭着的":@"瞪着你",f.rightEyeClosed?@"闭着的":@"瞪着你");
        
        UIView *faceView = [[UIView alloc] initWithFrame:f.bounds];
        faceView.layer.borderColor = [UIColor redColor].CGColor;
        faceView.layer.borderWidth = 1;
        [view addSubview:faceView];
        
        if (f.hasLeftEyePosition) {
            NSLog(@"左眼 %g %g", f.leftEyePosition.x, f.leftEyePosition.y);
            UIView * leftEyeView = [[UIView alloc] initWithFrame:CGRectMake(f.leftEyePosition.x, f.leftEyePosition.y, 5, 5)];
            leftEyeView.layer.borderColor = [UIColor yellowColor].CGColor;
            leftEyeView.layer.borderWidth = 5;
            [view addSubview:leftEyeView];
        }
        if (f.hasRightEyePosition) {
            NSLog(@"右眼 %g %g", f.rightEyePosition.x, f.rightEyePosition.y);
            UIView * rightEyeView = [[UIView alloc] initWithFrame:CGRectMake(f.rightEyePosition.x, f.rightEyePosition.y, 5, 5)];
            rightEyeView.layer.borderColor = [UIColor yellowColor].CGColor;
            rightEyeView.layer.borderWidth = 5;
            [view addSubview:rightEyeView];
        }
        if (f.hasMouthPosition) {
            NSLog(@"嘴 %g %g", f.mouthPosition.x, f.mouthPosition.y);
            UIView * mouthView = [[UIView alloc] initWithFrame:CGRectMake(f.mouthPosition.x, f.mouthPosition.y, 5, 5)];
            mouthView.layer.borderColor = [UIColor greenColor].CGColor;
            mouthView.layer.borderWidth = 5;
            [view addSubview:mouthView];
        }
    }
CIImage是CoreImage用来处理图像的类型可以配合CIContext、CIFilter、CIVector、CIColor等来处理图像过滤颜色等。


检测器的设置
 NSDictionary * opts = @{
                             CIDetectorAccuracy : CIDetectorAccuracyHigh //检测精度
                             };

CIDetectorImageOrientation
用于要检测其功能的图像的显示方向的选项。

CIDetectorEyeBlink
Core Image是否执行其他处理以识别检测到的面部中的闭眼的选项。

CIDetectorSmile
Core Image是否执行其他处理以识别检测到的面部中的微笑的选项。

CIDetectorFocalLength
识别用于捕获要由检测器处理的图像的像素的焦距的选项。

CIDetectorAspectRatio
一个选项,指定要搜索的矩形的宽高比(宽度除以高度)。

CIDetectorReturnSubFeatures
一个选项,指定是否返回检测到的要素的组件的要素信息。

还有其他配置。

创建一个CIDetector用于检测图像

CIDetector * detector = [CIDetector detectorOfType:CIDetectorTypeFace
                                              context:context
                                              options:opts];

CIDetectorTypeFace
用于搜索静止图像或视频中的面部,返回提供有关检测到的面部信息的对象。

CIDetectorTypeRectangle
用于搜索静止图像或视频中的矩形区域,返回提供有关检测到的区域的信息的对象。

CIDetectorTypeQRCode
用于在静止图像或视频中搜索快速响应代码(一种2D条形码),返回提供有关检测到的条形码信息的对象。

CIDetectorTypeText
用于搜索静止图像或视频中的文本,返回提供有关检测到的区域的信息的对象。

用CIFaceFeature接收CIDetector的检测结果

@property (readonly, assign) CGRect bounds;            //面部的位置和尺寸
@property (readonly, assign) BOOL hasLeftEyePosition;  
@property (readonly, assign) CGPoint leftEyePosition;  //左眼的位置
@property (readonly, assign) BOOL hasRightEyePosition; 
@property (readonly, assign) CGPoint rightEyePosition; //右眼的位置
@property (readonly, assign) BOOL hasMouthPosition;    
@property (readonly, assign) CGPoint mouthPosition;    //嘴巴的位置

/**
 视频跟踪ID
*/
@property (readonly, assign) BOOL hasTrackingID;       
@property (readonly, assign) int trackingID;           
@property (readonly, assign) BOOL hasTrackingFrameCount;
@property (readonly, assign) int trackingFrameCount;

@property (readonly, assign) BOOL hasFaceAngle;//
@property (readonly, assign) float faceAngle;//

@property (readonly, assign) BOOL hasSmile;//是否微笑
@property (readonly, assign) BOOL leftEyeClosed;//左眼是否闭着
@property (readonly, assign) BOOL rightEyeClosed;//右眼是否闭着

很荣幸请来祖哥(网上下的图片)做模特测试了一下demo!!测试结果一般,有时候检测不到脸,检测到的脸部如果比较小像素比较低检测的微笑、眼睛是否闭着几乎都是错的!