为什么Yp Cb Cr图像缓冲区在iOS 13中全部改组?

问题描述 投票:2回答:2

我有一个计算机视觉应用程序,可以从传感器获取灰度图像并进行处理。 iOS的图像采集是用Obj-C编写的,图像处理是使用OpenCV在C ++中执行的。因为我只需要亮度数据,所以我以YUV(或Yp Cb Cr)420双平面全范围格式获取图像,然后将缓冲区的数据分配给OpenCV Mat对象(请参见下面的获取代码)。到目前为止,这一直很有效,直到推出全新的iOS 13为止。由于某些原因,在iOS 13上,我获得的图像未对齐,从而导致对角线条纹。通过查看我获得的图像,我怀疑这是缓冲区的Y Cb和Cr分量顺序更改或缓冲区的步幅变化的结果。有谁知道iOS 13是否引入了这种更改以及如何更新代码来避免这种变化,最好以向后兼容的方式进行?]

这是我的图像获取代码:

//capture config
- (void)initialize {
    AVCaptureDevice *frontCameraDevice;
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if (device.position == AVCaptureDevicePositionFront) {
            frontCameraDevice = device;
        }
    }
    if (frontCameraDevice == nil) {
        NSLog(@"Front camera device not found");
        return;
    }

    _session = [[AVCaptureSession alloc] init];
    _session.sessionPreset = AVCaptureSessionPreset640x480;

    NSError *error = nil;
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:frontCameraDevice error: &error];
    if (error != nil) {
        NSLog(@"Error getting front camera device input: %@", error);
    }
    if ([_session canAddInput:input]) {
        [_session addInput:input];
    } else {
        NSLog(@"Could not add front camera device input to session");
    }

    AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
    // This is the default, but making it explicit
    videoOutput.alwaysDiscardsLateVideoFrames = YES;

    if ([videoOutput.availableVideoCVPixelFormatTypes containsObject:
                      [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange]]) {
        OSType format = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
        videoOutput.videoSettings = [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:format]
                                                                 forKey:(id)kCVPixelBufferPixelFormatTypeKey];
    } else {
        NSLog(@"YUV format not available");
    }

    [videoOutput setSampleBufferDelegate:self queue:dispatch_queue_create("extrapage.camera.capture.sample.buffer.delegate", DISPATCH_QUEUE_SERIAL)];
    if ([_session canAddOutput:videoOutput]) {
        [_session addOutput:videoOutput];
    } else {
        NSLog(@"Could not add video output to session");
    }

    AVCaptureConnection *captureConnection = [videoOutput connectionWithMediaType:AVMediaTypeVideo];
    captureConnection.videoOrientation = AVCaptureVideoOrientationPortrait;
}

//acquisition code 
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {

    if (_listener != nil) {
        CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        OSType format = CVPixelBufferGetPixelFormatType(pixelBuffer);

        NSAssert(format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, @"Only YUV is supported");

        // The first plane / channel (at index 0) is the grayscale plane
        // See more infomation about the YUV format
        // http://en.wikipedia.org/wiki/YUV
        CVPixelBufferLockBaseAddress(pixelBuffer, 0);
        void *baseaddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);

        CGFloat width = CVPixelBufferGetWidth(pixelBuffer);
        CGFloat height = CVPixelBufferGetHeight(pixelBuffer);

        cv::Mat frame(height, width, CV_8UC1, baseaddress, 0);

        [_listener onNewFrame:frame];

        CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
    }
}
ios objective-c opencv camera yuv
2个回答
2
投票
void *baseaddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); size_t width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0); size_t height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0); size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); cv::Mat frame(height, width, CV_8UC1, baseaddress, bytesPerRow);

注意,我还通过使用平面的尺寸而不是缓冲区的尺寸来更改了宽度和高度的获取方式。对于Y平面,它应该始终相同。我不确定是否会有所不同。

也要当心:更新Xcode以支持iOS 13 SDK之后,我不得不从测试设备上卸载我的应用程序,因为否则,Xcode会继续运行旧版本而不是新编译的版本。 

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.