iOS原生人脸识别CIDetector使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013263917/article/details/54973462
  • 本片博客版权归黑马程序员所有:黑马程序员

  • 苹果原生人脸识别早在iOS5就已经有了,但是能够识别的数据及其的少,所以用的人不是很多。

  • 目前做的比较好的人脸识别就是Facebook的face++

  • 人脸识别原理简介:每一张图片都是由每一个像素点组成,而每一个像素点中又有对应的颜色值(如RGB),人的面部特征中,不同的五官,颜色值肯定存在差异,而人脸识别技术就是通过对照片中每一个像素的识别进行大量的算法处理,最终得出五官的轮廓

    • 性别、年龄、五官位置等都需要庞大的算法支持
    • *
  • 苹果原生的人脸识别并不是一个独立的框架,而是放在<CoreImage>框架中

    • 可见苹果并没有在这个领域花精力
  • Demo效果演示

这里写图片描述

  • 代码
    • 注意坐标的换算,CIFaceFeature计算出来的坐标的坐标系的Y轴与iOS的Y轴是相反的,需要自行处理

#import "ViewController.h"

@interface ViewController ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate>

@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@property(nonatomic,strong)UIImagePickerController *picker;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    // Do any additional setup after loading the view, typically from a nib.
}


#pragma mark - 相册
- (IBAction)photoButtonClick:(id)sender {

    if (!self.picker) {
        //初始化uiimagepickercontroller
        self.picker = [[UIImagePickerController alloc] init];
        //UIImagePickerController是UINavigationControllerDelegate的子类 所以设置代理的时候也要实现navigation的代理

        //是否可以编辑
        self.picker.allowsEditing = YES;
        //设置代理
        self.picker.delegate = self;
        //设置来源类型
        /**UIImagePickerControllerSourceType
         UIImagePickerControllerSourceTypePhotoLibrary:进入相册(横向排列)
         UIImagePickerControllerSourceTypeCamera:打开相机(必须要真机)
         UIImagePickerControllerSourceTypeSavedPhotosAlbum:进入相册(竖向排列)
         */
        self.picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;


    }

    //先清除上一次人脸识别到的视图
    for (UIView *view in self.imageView.subviews) {
        [view removeFromSuperview];
    }

    //弹出相机界面
    [self presentViewController:self.picker animated:YES completion:nil];
}

#pragma mark UIImagePickerControllerDelegate


//完成选取
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(nullable NSDictionary<NSString *,id> *)editingInfo
{
    NSLog(@"image:%@",image);
    self.imageView.image = image;

    //开始人脸识别
    [self beginDetectorFacewithImage:image];

    [picker dismissViewControllerAnimated:YES completion:nil];
}

//取消选取
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [picker dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark -开始人脸识别

- (void)beginDetectorFacewithImage:(UIImage *)image
{
    //1 将UIImage转换成CIImage
    CIImage* ciimage = [CIImage imageWithCGImage:image.CGImage];

    //缩小图片,默认照片的图片像素很高,需要将图片的大小缩小为我们现实的ImageView的大小,否则会出现识别五官过大的情况
    float factor = self.imageView.bounds.size.width/image.size.width;
    ciimage = [ciimage imageByApplyingTransform:CGAffineTransformMakeScale(factor, factor)];

    //2.设置人脸识别精度
    NSDictionary* opts = [NSDictionary dictionaryWithObject:
                          CIDetectorAccuracyHigh forKey:CIDetectorAccuracy];
    //3.创建人脸探测器
    CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeFace
                                              context:nil options:opts];
    //4.获取人脸识别数据
    NSArray* features = [detector featuresInImage:ciimage];
    //5.分析人脸识别数据
    for (CIFaceFeature *faceFeature in features){

        //注意坐标的换算,CIFaceFeature计算出来的坐标的坐标系的Y轴与iOS的Y轴是相反的,需要自行处理

        // 标出脸部
        CGFloat faceWidth = faceFeature.bounds.size.width;
        UIView* faceView = [[UIView alloc] initWithFrame:faceFeature.bounds];
        faceView.frame = CGRectMake(faceView.frame.origin.x, self.imageView.bounds.size.height-faceView.frame.origin.y - faceView.bounds.size.height, faceView.frame.size.width, faceView.frame.size.height);
        faceView.layer.borderWidth = 1;
        faceView.layer.borderColor = [[UIColor redColor] CGColor];
        [self.imageView addSubview:faceView];
        // 标出左眼
        if(faceFeature.hasLeftEyePosition) {
            UIView* leftEyeView = [[UIView alloc] initWithFrame:
                                   CGRectMake(faceFeature.leftEyePosition.x-faceWidth*0.15,
                                              self.imageView.bounds.size.height-(faceFeature.leftEyePosition.y-faceWidth*0.15)-faceWidth*0.3, faceWidth*0.3, faceWidth*0.3)];
            [leftEyeView setBackgroundColor:[[UIColor blueColor] colorWithAlphaComponent:0.3]];
//            [leftEyeView setCenter:faceFeature.leftEyePosition];
            leftEyeView.layer.cornerRadius = faceWidth*0.15;
            [self.imageView  addSubview:leftEyeView];
        }
        // 标出右眼
        if(faceFeature.hasRightEyePosition) {
            UIView* leftEye = [[UIView alloc] initWithFrame:
                               CGRectMake(faceFeature.rightEyePosition.x-faceWidth*0.15,
                                          self.imageView.bounds.size.height-(faceFeature.rightEyePosition.y-faceWidth*0.15)-faceWidth*0.3, faceWidth*0.3, faceWidth*0.3)];
            [leftEye setBackgroundColor:[[UIColor blueColor] colorWithAlphaComponent:0.3]];
            leftEye.layer.cornerRadius = faceWidth*0.15;
            [self.imageView  addSubview:leftEye];
        }
        // 标出嘴部
        if(faceFeature.hasMouthPosition) {
            UIView* mouth = [[UIView alloc] initWithFrame:
                             CGRectMake(faceFeature.mouthPosition.x-faceWidth*0.2,
                                        self.imageView.bounds.size.height-(faceFeature.mouthPosition.y-faceWidth*0.2)-faceWidth*0.4, faceWidth*0.4, faceWidth*0.4)];
            [mouth setBackgroundColor:[[UIColor greenColor] colorWithAlphaComponent:0.3]];

            mouth.layer.cornerRadius = faceWidth*0.2;
            [self.imageView  addSubview:mouth]; 
        }

    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
  • 从以上代码可以看出,人脸的数据主要放在CIFaceFeature这一个类中,它的API也比较的少

这里写图片描述

猜你喜欢

转载自blog.csdn.net/u013263917/article/details/54973462
今日推荐