iOS人脸识别 用苹果api<AVFoundation/AVFoundation.h>

Demo 地址 : https://github.com/wwpeter/FaceID.git

https://img-blog.csdnimg.cn/2020072417

iOS 系统自带了人脸识别的方法,而且非常简单。无论针对图片 or 摄像头,都有系统级方法。

一、使用 AVCaptureVideoDataOutput 需要实现AVCaptureVideoDataOutputSampleBufferDelegate 的代理方法。

这个 delegate 会返回每个视频帧给我们,但不是我们常见的 UIImage,需要我们做格式转换。

并且 delegate 是在非主线程,我们要做 UI 展示的时候,需要主动切换主线程。

 

你还是可以用视频获取到的每一帧转换为 UIImage 来识别,速度就...所以我们不会直接用这种方法来做人脸识别。

//摄像头相关设置
-(void)faceDeviceInit{
        //1.获取输入设备(摄像头)
        NSArray *devices = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront].devices;
        AVCaptureDevice *deviceF = devices[0];
        
        
        //2.根据输入设备创建输入对象
        AVCaptureDeviceInput*input = [[AVCaptureDeviceInput alloc] initWithDevice:deviceF error:nil];
        
        //3.创建原数据的输出对象
        AVCaptureMetadataOutput *metaout = [[AVCaptureMetadataOutput alloc] init];
        
        
        
        //4.设置代理监听输出对象输出的数据,在主线程中刷新
        [metaout setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
        self.session = [[AVCaptureSession alloc] init];
        
        //5.设置输出质量(高像素输出)
        if ([self.session canSetSessionPreset:AVCaptureSessionPreset640x480]) {
            [self.session setSessionPreset:AVCaptureSessionPreset640x480];
        }
        
        //6.添加输入和输出到会话
        [self.session beginConfiguration];
        if ([self.session canAddInput:input]) {
            [self.session addInput:input];
        }
        if ([self.session canAddOutput:metaout]) {
            [self.session addOutput:metaout];
        }
        
        if ([_session canAddOutput:self.videoDataOutput]) {
               [_session addOutput:self.videoDataOutput];
        }
        [self.session commitConfiguration];
        
        //7.告诉输出对象要输出什么样的数据,识别人脸, 最多可识别10张人脸
        [metaout setMetadataObjectTypes:@[AVMetadataObjectTypeFace]];
        
        AVCaptureSession *session = (AVCaptureSession *)self.session;
        
        //8.创建预览图层
          _previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
          _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        _previewLayer.frame = CGRectMake((ScreenWidth-ScaleW(30))/2-ScaleW(100), ScaleW(65), ScaleW(200), ScaleW(200));
          _previewLayer.cornerRadius = 100;
          [self.groundView.layer insertSublayer:_previewLayer atIndex:0];
        
        //9.设置有效扫描区域(默认整个屏幕区域)(每个取值0~1, 以屏幕右上角为坐标原点)
        metaout.rectOfInterest = self.bounds;
        
        //前置摄像头一定要设置一下 要不然画面是镜像
        for (AVCaptureVideoDataOutput* output in session.outputs) {
            for (AVCaptureConnection * av in output.connections) {
                //判断是否是前置摄像头状态
                if (av.supportsVideoMirroring) {
                    //镜像设置
                    av.videoOrientation = AVCaptureVideoOrientationPortrait;
    //                av.videoMirrored = YES;
                }
            }
        }
        
        //10. 开始扫描
        [self.session startRunning];
        
    
    
}

- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    if (metadataObjects.count>1) {
        self.tishiLable.text = @"必须一个人进行人脸识别~";
        return;
    } else {
        for(AVMetadataObject *metaObject in metadataObjects){
              
             if([metaObject isKindOfClass:[AVMetadataFaceObject class ]] && metaObject.type == AVMetadataObjectTypeFace){
                 if (!_successful) {
                     if (!self.progress) {
                         //进行网络请求
                          [self cleanupSelfReferencecleanupSelfReference];
                     }
                     
                 }

             } else {
                 self.tishiLable.text = @"未检测到人脸~";
             }
         }
    }
 
}
- (UIImage*)imageFromPixelBuffer:(CMSampleBufferRef)p {
    CVImageBufferRef buffer;
    buffer = CMSampleBufferGetImageBuffer(p);

    CVPixelBufferLockBaseAddress(buffer, 0);
    uint8_t *base;
    size_t width, height, bytesPerRow;
    base = (uint8_t *)CVPixelBufferGetBaseAddress(buffer);
    width = CVPixelBufferGetWidth(buffer);
    height = CVPixelBufferGetHeight(buffer);
    bytesPerRow = CVPixelBufferGetBytesPerRow(buffer);

    CGColorSpaceRef colorSpace;
    CGContextRef cgContext;
    colorSpace = CGColorSpaceCreateDeviceRGB();
    cgContext = CGBitmapContextCreate(base, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    CGColorSpaceRelease(colorSpace);

    CGImageRef cgImage;
    UIImage *image;
    cgImage = CGBitmapContextCreateImage(cgContext);
    image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    CGContextRelease(cgContext);

    CVPixelBufferUnlockBaseAddress(buffer, 0);


    return image;
}

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{

    [connection setVideoOrientation:AVCaptureVideoOrientationPortrait];

    
    self.imgTemp = [self imageFromSampleBuffer:sampleBuffer];

}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 什么是 AVFoundationAVFoundation苹果公司提供的一个多媒体处理框架,它能够处理音频、视频、文本和图像等媒体类型,还能够实现录制、编辑、播放等多种操作。 2. AVFoundation的优点是什么? AVFoundation有以下几个优点: - 它可以在多个平台上使用,包括iOS、macOS和tvOS等。 - 它提供了灵活的API,可以对多种媒体类型进行处理。 - 它支持硬件加速,能够提高处理速度和性能。 - 它支持多种格式的媒体文件,包括MP3、AAC、H.264和MPEG-4等。 3. 如何使用AVFoundation实现音频录制? 在使用AVFoundation实现音频录制时,需要执行以下步骤: - 创建一个AVAudioSession对象,用于管理音频会话。 - 创建一个AVAudioRecorder对象,用于录制音频。 - 配置录音参数,例如音频格式、采样率、通道数、音频质量等。 - 调用AVAudioRecorder的record方法开始录音。 - 调用AVAudioRecorder的stop方法停止录音。 4. AVFoundation中的AVPlayerLayer是什么? AVPlayerLayer是一个CALayer子类,用于在iOS和macOS应用程序中显示视频内容。它可以显示一个AVPlayer对象的输出,并且支持全屏播放、画中画、视频内容缩放等功能。 5. 如何使用AVFoundation实现视频播放? 在使用AVFoundation实现视频播放时,需要执行以下步骤: - 创建一个AVPlayer对象,用于播放视频。 - 创建一个AVPlayerLayer对象,用于显示视频内容。 - 将AVPlayerLayer对象添加到视图层次结构中。 - 创建一个AVPlayerItem对象,用于管理视频资源。 - 调用AVPlayer的replaceCurrentItemWithPlayerItem方法将AVPlayerItem与AVPlayer关联。 - 调用AVPlayer的play方法开始播放视频。 6. 如何在AVFoundation中实现视频编辑? 在AVFoundation中实现视频编辑通常需要使用AVAsset、AVAssetTrack、AVComposition、AVMutableComposition等类。以下是实现视频编辑的大致步骤: - 创建一个AVAsset对象,用于表示视频资源。 - 创建一个AVMutableComposition对象,用于管理视频资源。 - 使用AVAssetTrack获取视频的音频和视频轨道。 - 使用AVMutableCompositionTrack将音频和视频轨道添加到AVMutableComposition中。 - 使用AVAssetExportSession导出编辑后的视频。 7. AVFoundation中的AVCaptureSession是什么? AVCaptureSession是用于管理视频和音频输入的会话对象。它可以管理多个输入设备(例如摄像头、麦克风等)并且可以将它们合并到单个输出中。使用AVCaptureSession可以方便地实现视频录制、视频流传输、实时视频分析等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值