AVFoundation - 从Y平面获取灰度图像(kCVPixelFormatType_420Y

2019-07-28 23:59发布

我使用AVFoundation拍摄录像,我在录音kCVPixelFormatType_420YpCbCr8BiPlanarFullRange格式。 我想直接从YpCbCr格式的Y平面内使灰度图像。

我想尽量创造CGContextRef通过调用CGBitmapContextCreate ,但问题是,我不知道什么是色彩空间和像素格式选择。

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
       fromConnection:(AVCaptureConnection *)connection 
{       
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CVPixelBufferLockBaseAddress(imageBuffer,0);        

    /* Get informations about the Y plane */
    uint8_t *YPlaneAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
    size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(imageBuffer, 0);
    size_t width = CVPixelBufferGetWidthOfPlane(imageBuffer, 0);
    size_t height = CVPixelBufferGetHeightOfPlane(imageBuffer, 0);

    /* the problematic part of code */
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();

    CGContextRef newContext = CGBitmapContextCreate(YPlaneAddress,
    width, height, 8, bytesPerRow, colorSpace, kCVPixelFormatType_1Monochrome);

    CGImageRef newImage = CGBitmapContextCreateImage(newContext); 
    UIImage *grayscaleImage = [[UIImage alloc] initWithCGImage:newImage];

    // process the grayscale image ... 
}

当我运行上面的代码,我得到这个错误:

<Error>: CGBitmapContextCreateImage: invalid context 0x0
<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaPremultipliedLast; 192 bytes/row.

PS:对不起,我的英语水平。

Answer 1:

如果我没有记错的话,你不应该通过去CGContext 。 相反,你应该创建一个数据提供者,然后直接图像。

在你的代码另一个错误是使用的kCVPixelFormatType_1Monochrome不变。 它在视频处理(AV库)使用恒定的,而不是在核心图形(CG库)。 只需使用kCGImageAlphaNone 。 所需要(而不是三个作为用于RGB)每个像素的单个组件(灰色)从彩色空间的。

它看起来是这样的:

CGDataProviderRef  dataProvider = CGDataProviderCreateWithData(NULL, YPlaneAdress,
      height * bytesPerRow, NULL);
CGImageRef newImage = CGImageCreate(width, height, 8, 8, bytesPerRow,
      colorSpace, kCGImageAlphaNone, dataProvider, NULL, NO, kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);


文章来源: AVFoundation - Get grayscale image from Y plane (kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)