美文网首页
iOS 获取摄像头的每一帧

iOS 获取摄像头的每一帧

作者: 梵高的老巫婆 | 来源:发表于2017-06-20 12:16 被阅读871次

    ####序言: 最近公司开始做车牌扫描识别 用到了自定义扫描框和捕获摄像头每一帧转换成图片进行识别. 找了点网上的方法加上自己写的给自己做个总结.

    ***

    ####视频录制或者拍照可以用UIImagePickerController,不过UIImagePickerController会跳转到系统原生页面.还可以通过另一种方式来获取摄像头数据首先导入 #import 接下来的类需要实现AVCaptureVideoDataOutputSampleBufferDelegate这个协议,只需要实现协议中的一个方法就可以得到摄像头捕获的数据了

    ```

    @property(nonatomic,strong)AVCaptureSession*session;

    @property(nonatomic,strong)UIImageView*imageView;

    @property(nonatomic,strong)CALayer*customLayer;

    @property(nonatomic,strong)AVCaptureVideoPreviewLayer*prevLayer;

    - (void)setupCaptureSession

    {

    NSError*error =nil;

    // Create the session

    self.session= [[AVCaptureSessionalloc]init];

    self.session.sessionPreset=AVCaptureSessionPresetMedium;

    AVCaptureDevice*device = [AVCaptureDevice

    defaultDeviceWithMediaType:AVMediaTypeVideo];//这里默认是使用后置摄像头,你可以改成前置摄像头

    // Create a device input with the device and add it to the session.

    AVCaptureDeviceInput*input = [AVCaptureDeviceInputdeviceInputWithDevice:device

    error:&error];

    if(!input) {

    // Handling the error appropriately.

    }

    [self.sessionaddInput:input];

    AVCaptureVideoDataOutput*output = [[AVCaptureVideoDataOutputalloc]init] ;

    [self.sessionaddOutput:output];

    dispatch_queue_tqueue =dispatch_queue_create("myQueue",NULL);

    [outputsetSampleBufferDelegate:selfqueue:queue];

    output.videoSettings= [NSDictionarydictionaryWithObjectsAndKeys:

    [NSNumbernumberWithInt:kCVPixelFormatType_32BGRA],kCVPixelBufferPixelFormatTypeKey,

    [NSNumbernumberWithInt:320], (id)kCVPixelBufferWidthKey,

    [NSNumbernumberWithInt:240], (id)kCVPixelBufferHeightKey,

    nil];

    AVCaptureVideoPreviewLayer* preLayer = [AVCaptureVideoPreviewLayerlayerWithSession:self.session];

    preLayer.frame=CGRectMake(0,64,kScreenWidth,kScreenHeight*2/3);

    preLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;

    [preLayeraddSublayer:self.scanZomeBack.layer];

    [self.view.layeraddSublayer:preLayer];

    output.minFrameDuration=CMTimeMake(1,15);

    [self.sessionstartRunning];

    }

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

    UIImage*image = [selfimageFromSampleBuffer:sampleBuffer];

    NSData* mData =UIImageJPEGRepresentation(image,0.5);

    UIImage*PR_image = [UIImageimageWithData:mData];

    //NSLog(@"PR_image:%@",PR_image);

    [self identifyImage:PR_image];

    }

    - (UIImage*)imageFromSampleBuffer:(CMSampleBufferRef)sampleBuffer{

    CVImageBufferRefimageBuffer =CMSampleBufferGetImageBuffer(sampleBuffer);

    CVPixelBufferLockBaseAddress(imageBuffer,0);

    void*baseAddress =CVPixelBufferGetBaseAddress(imageBuffer);

    size_tbytesPerRow =CVPixelBufferGetBytesPerRow(imageBuffer);

    // Get the pixel buffer width and height

    size_twidth =CVPixelBufferGetWidth(imageBuffer);

    size_theight =CVPixelBufferGetHeight(imageBuffer);

    // Create a device-dependent RGB color space

    CGColorSpaceRefcolorSpace =CGColorSpaceCreateDeviceRGB();

    // Create a bitmap graphics context with the sample buffer data

    CGContextRefcontext =CGBitmapContextCreate(baseAddress, width, height,8,

    bytesPerRow, colorSpace,kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);

    // Create a Quartz image from the pixel data in the bitmap graphics context

    CGImageRefquartzImage =CGBitmapContextCreateImage(context);

    // Unlock the pixel buffer

    CVPixelBufferUnlockBaseAddress(imageBuffer,0);

    // Free up the context and color space

    CGContextRelease(context);

    CGColorSpaceRelease(colorSpace);

    // Create an image object from the Quartz image

    //UIImage *image = [UIImage imageWithCGImage:quartzImage];

    UIImage*image = [UIImageimageWithCGImage:quartzImagescale:1.0forientation:UIImageOrientationRight];

    // Release the Quartz image

    CGImageRelease(quartzImage);

    return(image);

    }

    ```

    ***

    ####其中preLayer是一个预览摄像的界面 .位置什么的也是在preLayer.frame里可设置。你可以在你这个controller中的初始化调用- (void)setupCaptureSession 方法  这样摄像头就开始工作了,摄像头关闭的话 [session stopRunning];

    相关文章

      网友评论

          本文标题:iOS 获取摄像头的每一帧

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