iOS 人脸检测

如果用iOS 原生的CIDetector来做人脸检测

/** CIDetector发现的脸部特征。
  所有的位置都是相对于原始图像. */
NS_CLASS_AVAILABLE(10_7, 5_0)
@interface CIFaceFeature : CIFeature
{
    CGRect bounds;
    BOOL hasLeftEyePosition;
    CGPoint leftEyePosition;
    BOOL hasRightEyePosition;
    CGPoint rightEyePosition;
    BOOL hasMouthPosition;
    CGPoint mouthPosition;
    
    
    BOOL hasTrackingID;
    int trackingID;
    BOOL hasTrackingFrameCount;
    int trackingFrameCount;
    
    BOOL hasFaceAngle;
    float faceAngle;
    
    BOOL hasSmile;
    BOOL leftEyeClosed;
    BOOL rightEyeClosed;
}

/**脸部各个基点的坐标。
 
  请注意,左眼是脸左侧的眼睛
  从观察者的角度来看。 这不是左眼
  主体的视角. */

@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;      //口的坐标

@property (readonly, assign) BOOL hasTrackingID;         //指示面部对象是否具有跟踪ID。
@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;       //右眼是否闭上

@end

关于trackingID
核心图像提供了在视频流中检测到的脸部的跟踪标识符,您可以使用该标识符来识别在一个视频帧中检测到的CIFaceFeature对象是在先前视频帧中检测到的同一个脸部。
只有在框架中存在人脸并且不与特定人脸相关联时,该标识符才会一直存在。 
换句话说,如果脸部移出视频帧并在稍后返回到帧中,则分配另一个ID。 (核心图像检测面部,但不识别特定的面部。)

这个有点抽象,暂时不理解

测试

打印数据

 bounds                  : {{237.5, 115}, {435, 435}}
 hasLeftEyePosition      : 1
 leftEyePosition         : {381.25, 405}
 hasRightEyePosition     : 1
 rightEyePosition        : {550, 388.75}
 hasMouthPosition        : 1
 mouthPosition           : {450, 225}
 hasTrackingID           : 0
 trackingID              : 0
 hasTrackingFrameCount   : 0
 trackingFrameCount      : 0
 hasFaceAngle            : 1
 faceAngle               : 3.000000rightEyeClosed
 hasSmile                : 0
 leftEyeClosed           : 0
 rightEyeClosed          : 0

发现

hasSmile, leftEyeClosed, rightEyeClosed 检测都不准确

整体来说除了:

bounds ,leftEyePosition, rightEyePosition, mouthPosition这四个属性有可用价值,其他的可用价值体验就不那么明显了

也就是

可以用,但不推荐

实现思路

  • 正常创建一个相机,初始化相机的所有功能(怎么实现iOS相机功能,请教度娘)
  • (预览的时候)获取相机的视频帧数据,也就是在相机预览的时候,会不断的调用以下的方法获取帧数据
(遵循协议 : AVCaptureVideoDataOutputSampleBufferDelegate)
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
       fromConnection:(AVCaptureConnection *)connection;
方法:
// 通过抽样缓存数据创建一个UIImage对象
- (UIImage *)imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer
{
    //CIImage -> CGImageRef -> UIImage
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);  //拿到缓冲区帧数据
    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer];            //创建CIImage对象
    CIContext *temporaryContext = [CIContext contextWithOptions:nil];           //创建上下文
    CGImageRef cgImageRef = [temporaryContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer))];
    UIImage *result = [[UIImage alloc] initWithCGImage:cgImageRef scale:1.0 orientation:UIImageOrientationLeftMirrored];  //创建UIImage对象
    CGImageRelease(cgImageRef);  //释放上下文
    return result;
}
/**识别脸部*/
-(NSArray *)detectFaceWithImage:(UIImage *)faceImag
{
    //此处是CIDetectorAccuracyHigh,若用于real-time的人脸检测,则用CIDetectorAccuracyLow,更快
    CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace
                                                  context:nil
                                                  options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
    CIImage *ciimg = [CIImage imageWithCGImage:faceImag.CGImage];
    NSArray *features = [faceDetector featuresInImage:ciimg];

    CIFaceFeature *faceFeature = [features firstObject];
    if (faceFeature) {
        NSLog(@"bounds                  : %@",NSStringFromCGRect(faceFeature.bounds));
        NSLog(@"hasLeftEyePosition      : %d",faceFeature.hasLeftEyePosition);
        NSLog(@"leftEyePosition         : %@",NSStringFromCGPoint(faceFeature.leftEyePosition));
        NSLog(@"hasRightEyePosition     : %d",faceFeature.hasRightEyePosition);
        NSLog(@"rightEyePosition        : %@",NSStringFromCGPoint(faceFeature.rightEyePosition));
        NSLog(@"hasMouthPosition        : %d",faceFeature.hasMouthPosition);
        NSLog(@"mouthPosition           : %@",NSStringFromCGPoint(faceFeature.mouthPosition));
        NSLog(@"hasTrackingID           : %d",faceFeature.hasTrackingID);
        NSLog(@"trackingID              : %d",faceFeature.trackingID);
        NSLog(@"hasTrackingFrameCount   : %d",faceFeature.hasTrackingFrameCount);
        NSLog(@"trackingFrameCount      : %d",faceFeature.trackingFrameCount);
        NSLog(@"hasFaceAngle            : %d",faceFeature.hasFaceAngle);
        NSLog(@"faceAngle               : %frightEyeClosed",faceFeature.faceAngle);
        NSLog(@"hasSmile                : %d",faceFeature.hasSmile);
        NSLog(@"leftEyeClosed           : %d",faceFeature.leftEyeClosed);
        NSLog(@"rightEyeClosed          : %d",faceFeature.rightEyeClosed);
        NSLog(@"\n\n\n");
    }
    
    return features;
}

关于人脸识别的一些思考 :
  • 人脸识别/检测的应用区分场景,
    比如 : 美图/视频编辑, 社区监控,人脸门禁,智能家居,广告展示,老人购物等…
  • 美图/视频编辑 : ==> 图片数据在客户端上处理.
  • 社区监控,人脸门禁,智能家居,广告展示,老人购物 : ==> 图片数据在服务器上处理.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 1.引入头文件 #import 代理 2.新建属性 @property(strong,nonatomic)AVC...
    huasali阅读 1,155评论 0 0
  • 能检测出坐标,不能生成特征值。 1,人脸检测 AVCaptureMetadataOutputAVMetadataF...
    我是小胡胡123阅读 656评论 0 0
  • 在过去感到疲惫的原因,仅仅只会是坐在工作室的电脑前一整天,因为工作任务密集无法动弹产生的久坐的疲惫。 然而这个年末...
    Vogen阅读 964评论 0 0
  • #霆瀚霆五题# 1、铁链发出叮当的碰撞声,军靴与地面的接触声伴随着吱呀的开门声响了起来,湿润的空气随着风吹进了监狱...
    杦酒阅读 313评论 0 1
  • 文\逍遥女公子 公司还未收假,难得有几天清闲,躲在漫咖啡里看闲书,好不自在。 正在无聊之际,闺蜜突然发来微信,跟我...
    逍遥女公子阅读 471评论 0 1