美文网首页iOS技术栈IOSIOS面试裤
选取图像 + 人脸识别

选取图像 + 人脸识别

作者: earthX | 来源:发表于2016-05-13 18:23 被阅读1847次

今天无意翻到了人脸识别,突然想在ios设备上实现,这里我们主要用到了几个类:CIContext,CIDetector

CIContext

CIContext 是Core Image的一个对象,Core Image是一个OS X和iOS的图像处理框架。通过它Core Image可以绘制一个CIFilter产生的结果。一个Core Image Context可以基于CPU或GPU。

CIDetector

Core Image 已经提供了 CIDetector 类。用它来做人脸检测已经相当好了,并且它已经被优化过,使用起来也很容易:

CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:context options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];NSArray *faces = [faceDetector featuresInImage:image];

从该图片中检测到的每一张面孔都在数组 faces 中保存着一个 CIFaceFeature 实例。这个实例中保存着这张面孔的所处的位置和宽高,除此之外,眼睛和嘴的位置也是可选的。

@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;
}

人脸监测的步骤是:先获取图像,然后转成CIImage格式,利用CIFeature特征,使用探测器CIDetector拿到所有的人脸,然后在图中圈出,即可达到人脸识别的目的,关键代码如下:

//获取图片
    UIImage *image = self.imageview.image;
    //转成CIImage
    CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage];
    //拿到所有的脸
    NSArray <CIFeature *> *featureArray = [self.detector featuresInImage:ciImage];

    if (featureArray.count == 0) {
        NSLog(@"未检测到人脸");
        //初始化提示框;
        UIAlertController *alert1 = [UIAlertController alertControllerWithTitle:@"提示" message:@"未检测到人脸" preferredStyle: UIAlertControllerStyleAlert];
        [alert1 addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
            //点击按钮的响应事件;
        }]];
        
        //弹出提示框;
        [self presentViewController:alert1 animated:true completion:nil];
        
    }else{
        //遍历
        for (CIFeature *feature in featureArray){
            
            //将image沿y轴对称
            CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, -1);
            //将image往上移动
            CGFloat imageH = ciImage.extent.size.height;
            transform = CGAffineTransformTranslate(transform, 0, -imageH);
            //在image上画出方框
            CGRect feaRect = feature.bounds;
            //调整后的坐标
            CGRect newFeaRect = CGRectApplyAffineTransform(feaRect, transform);
            //调整imageView的frame
            CGFloat imageViewW = self.imageview.bounds.size.width;
            CGFloat imageViewH = self.imageview.bounds.size.height;
            CGFloat imageW = ciImage.extent.size.width;
            //显示
            CGFloat scale = MIN(imageViewH / imageH, imageViewW / imageW);
            //缩放
            CGAffineTransform scaleTransform = CGAffineTransformMakeScale(scale, scale);
            
            //修正
            newFeaRect = CGRectApplyAffineTransform(newFeaRect, scaleTransform);
            newFeaRect.origin.x += (imageViewW - imageW * scale ) / 2;
            newFeaRect.origin.y += (imageViewH - imageH * scale ) / 2;
            NSLog(@"xxx:%f",newFeaRect.origin.x);
            
            //绘画
            UIView *breageView = [[UIView alloc] initWithFrame:newFeaRect];
            breageView.layer.borderColor = [UIColor redColor].CGColor;
            breageView.layer.borderWidth = 2;
            [self.imageview addSubview:breageView];
        }

    }
监测成功.png 监测失败.jpg

上述图像载入的时候,采用了一个用户头像上传的demo,顺道一起研究了,选取图像可以选择两种途径,第一种是拍照识别,第二种从个人相册中载入,并且将载入后的图像写入沙盒中。

选取图像

@property(nonatomic,strong) UIPopoverController *imagePickerPopover; //

需要注意的是 UIPopoverController ,是iPad开发中常见的一种控制器(在iPhone上不允许使用)
跟其他控制器不一样的是,它直接继承自NSObject,并非继承自UIViewController
它只占用部分屏幕空间来呈现信息,而且显示在屏幕的最前面,但是在IOS9的时候已经被废除。

可以选用IOS8提供的新特性 UIPresentationController,UIPresentationController是提供高级视图切换的类。它让管理present ViewController的过程变得简单。

在iPad的设置页面,可以通过popOver弹出一个UIViewController,这个弹出的,可以和用户交互的Controller叫做PresentedViewController,而后面那个被部分遮挡的UIViewController叫做PresentingViewController,而在UIPresentationController中,PresentedViewController是presentation的content,而PresentingViewController叫做Chrome。

  • UIPopoverPresentationController
    它在iOS8中替代了UIPopoverController,它在功能上与旧的controller完全等同,并且新增了一些内置的适配特性,可以自动适配iPad与iPhone。以下是新版与旧版接口的比较:

  • UIPopoverController使用方法:

UIViewController *contentController = [[UIViewController alloc] init];
UIPopoverController *poc = [UIPopoverController alloc] initWithContentViewController:contentController];
[poc presentPopoverFromBarButtonItem:item permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

但是这个是ipad的类,如果要创建一个在iPad与iPhone上通用的方法,那么需要以下的代码:

    UIViewController *contentController = [[UIViewController alloc] init];

    if([[UIDevice currentDevice] userInterfaceIdim] == UIUserInterfaceIdiomPad){
        UIPopoverController *poc = [UIPopoverController alloc] initWithContentViewController:contentController];
        [poc presentPopoverFromBarButtonItem:item permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }else{
       [self presentViewController:contentController animated:YES completion:nil];
    }

然而我们如果使用UIPopoverPresentationController,那么就不再需要判断设备,例如:

    UIViewController *contentController = [[UIViewController alloc] init];

    UIPopoverPresentationController *popVC = contentController.popoverPresentationController;
    popVC.barButtonItem = item;
    popVC.permittedArrowDirections = UIPopoverArrowDirectionAny;
    popVC.delegate = self;

    [self presentViewController:contentController animated:YES completion:nil];

  • 将UIViewController的modalPresentationStyle设置成UIModalPresentationPopover,这个值用来实现popover效果,并且各个平台自动适应。第二行中,通过popoverPresentationController属性来获取它的popoverPresentationController,而不是创建一个新的。然后设置它的一些界面属性,最后调用presentViewController方法来显示这个controller。这样就可以在iPad与iPhone显示自动适应的popover效果了。
    其中,iPhone上的自适应是在delegate中实现的:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresemtatopmController:(UIPresentationController * controller)
{
    return UIModalPresentationFullScreen;
}

- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style
{ 
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller.presentedViewController];
    return navController;

}

  • UIImagePickerController

    UIImagePickerController 是系统提供的用来获取图片和视频的接口,用UIImagePickerController 类来获取图片视频,大体分为以下几个步骤:

  1. 初始化UIImagePickerController 类;
  2. 设置UIImagePickerController 实例的数据来源类型;
  3. 设置设置代理;
  4. 如果需要做图片修改的话设置allowsEditing =yes。

数据来源类型一共有三种:

enum {
   UIImagePickerControllerSourceTypePhotoLibrary ,//来自图库
   UIImagePickerControllerSourceTypeCamera ,//来自相机
   UIImagePickerControllerSourceTypeSavedPhotosAlbum //来自相册
};

在用这些来源的时候最好检测以下设备是否支持;

 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        NSLog(@"支持相机");
    }
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
    {
        NSLog(@"支持图库");
    }
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
    {
        NSLog(@"支持相片库");
    }

调用摄像头来获取资源

- (void)viewDidLoad {
    [super viewDidLoad];
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker = [[UIImagePickerController alloc]init];
    picker.view.backgroundColor = [UIColor orangeColor];
    UIImagePickerControllerSourceType sourcheType = UIImagePickerControllerSourceTypeCamera;
    picker.sourceType = sourcheType;
    picker.delegate = self;
    picker.allowsEditing = YES;
}

上面只是实例了UIImagePickerController及其属性 在需要获取图片的时候需要弹出窗口调用

[self presentViewController:picker animated:YES completion:nil];

完整的选取相册代码如下:

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"请选择打开方式" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    [alert addAction:[UIAlertAction actionWithTitle:@"打开相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
        imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
        //创建UIPopoverController对象前先检查当前设备是不是ipad
        if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
            self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
            self.imagePickerPopover.delegate = self;
            [self.imagePickerPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        }else{
            [self presentViewController:imagePicker animated:YES completion:nil];
        }
        
    }]];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"我的相册" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
    
        imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        //创建UIPopoverController对象前先检查当前设备是不是ipad
        if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
            self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
            self.imagePickerPopover.delegate = self;
            [self.imagePickerPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        }else{
        
            [self presentViewController:imagePicker animated:YES completion:nil];
        }
    }]];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *_Nonnull action){
        //取消
    }]];
    
    //弹出提示框
    [self presentViewController:alert animated:YES completion:nil];

本文从人脸识别出发,记录了ios设备进行人脸识别时,使用的CIDetector类,顺带温习了一下拉起相册的相关知识,由UIPopoverController到UIPresentationController,详细记录。

附上传送门:https://github.com/earthX/EXFaceRecognition

相关文章

  • 选取图像 + 人脸识别

    今天无意翻到了人脸识别,突然想在ios设备上实现,这里我们主要用到了几个类:CIContext,CIDetecto...

  • facexx解析:人脸识别技术市场在哪些领域?

    人脸识别技术经历了可见光图像人脸识别、三维图像人脸识别/热成像人脸识别、基于主动近红外图像的多光源人脸识别三层进化...

  • UIImagePickerController

    紧接着上一篇文章,选取图像并研究了人脸识别,说到选取头像就离不开UIImagePickerController这个...

  • 人脸识别产品设计基础

    人脸识别的产品设计 图像获取 图像获取是人脸识别的第一步,人脸图像主要来源为各类相机,图像质量很大程度会影响人脸识...

  • 学习笔记TF058:人脸识别

    人脸识别,基于人脸部特征信息识别身份的生物识别技术。摄像机、摄像头采集人脸图像或视频流,自动检测、跟踪图像中人脸,...

  • iOS ---人脸检测

    检测图像中的人脸 Core Image可以分析并找到图像中的人脸。它执行的是人脸检测,而不是识别。人脸检测是识别包...

  • 人脸识别预研

    1. 人脸识别发展 以往的人脸识别主要是包括人脸图像采集、人脸识别预处理、身份确认、身份查找等技术和系统。现在人脸...

  • 如何提高识别率?影响刷脸通闸时人脸采集的主要因素

    在人脸识别技术的应用中,人脸识别利用摄像头进行人脸的采集,并自动在图像中检测和跟踪人脸,进而对检测到的人脸图像进行...

  • 【计算机视觉】对检测的人脸进行剪切和归一化

    引子 要进行人脸的识别,尤其是复杂环境下的人脸识别,就要在捕获人脸图像之后对图像进行预处理的工作,如图像的大小和灰...

  • 【转载】人脸识别系统的原理与发展

    1,人脸识别介绍 广义定义:构建人脸识别系统的一系列相关技术,包括人脸图像采集,人脸定位,人脸识别预处理,身份确认...

网友评论

    本文标题:选取图像 + 人脸识别

    本文链接:https://www.haomeiwen.com/subject/khqmrttx.html