Сканирование камеры в реальном времени iOS

#ios

#iOS

Вопрос:

Я разрабатываю приложение для iOS, в котором мне нужно выполнить сканирование некоторых объектов в реальном времени. Для этого мне нужно, например, снимать 3 или 4 кадра в секунду. Вот мой код для создания сеанса захвата:

 // Create an AVCaptureSession
    AVCaptureSession *captureSession = [[AVCaptureSession alloc] init];
    captureSession.sessionPreset = AVCaptureSessionPresetHigh;

    // Find a suitable AVCaptureDevice
    AVCaptureDevice *photoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    // Create and add an AVCaptureDeviceInput
    NSError *error = nil;
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:photoCaptureDevice error:amp;error];
    if(videoInput){
        [captureSession addInput:videoInput];
    }

    // Create and add an AVCaptureVideoDataOutput
    AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
    // we want BGRA, both CoreGraphics and OpenGL work well with 'BGRA'
    NSDictionary *rgbOutputSettings = [NSDictionary dictionaryWithObject:
                                       [NSNumber numberWithInt:kCMPixelFormat_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey];
    [videoOutput setVideoSettings:rgbOutputSettings];

    // Configure your output, and start the session
    dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
    [videoOutput setSampleBufferDelegate:self queue:queue];

    if(videoOutput){
        [captureSession addOutput:videoOutput];
    }

    [captureSession startRunning];


    // Setting up the preview layer for the camera
    AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    previewLayer.frame = cameraViewCanvas.bounds;

    // ADDING FINAL VIEW layer TO THE MAIN VIEW sublayer
    [cameraViewCanvas.layer addSublayer:previewLayer];
 

И метод делегирования, который вызывается в очереди:

 -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
    if(isCapturing){
        NSLog(@"output");

        CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate);
        CIImage *ciImage = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer options:(NSDictionary *)attachments];

        UIImage *newFrame = [[UIImage alloc] initWithCIImage:ciImage];
        [self showImage:newFrame];
    }
}
 

Проблема в том, что я не вижу изображения на экране, ошибок и предупреждений нет, но изображение не отображается. Мой вопрос — я на правильном пути, что нужно исправить в моем коде, чтобы отобразить изображение на экране?

Комментарии:

1. Не могли бы вы предоставить больше информации о вашем cameraViewCanvas ? Где оно определено и инициализировано и так далее…

2. Это просто @property (nonatomic, retain) IBOutlet UIView *cameraViewCanvas; для отображения видеовыхода камеры, это не для всего размера окна, поэтому я могу добавить некоторые другие объекты, например, UIImageView, чтобы просмотреть, какие кадры я уже сделал.

3. Итак, вы добавили его в InterfaceBuilder в основной вид?

4. да, не думайте, что проблема вызвана этим, потому что слой камеры выглядит нормально, поскольку я предполагаю, что есть что-то, связанное с преобразованием из CIImage в UIImage, были некоторые вопросы по этой теме, и я воспользовался некоторыми советами от них, но это все равно не работает.

Ответ №1:

Запоздало, но проблема, вероятно, связана с тем, что изображение не задано в основном потоке (скорее всего, captureOutput вызывается в отдельной созданной вами очереди отправки).

 dispatch_async(dispatch_get_main_queue(), ^{
  [self showImage:newFrame];
});
 

или

 [self performSelectorOnMainThread:@selector(showImage:) newFrame waitUntilDone:YES];