iOS6:如何使用YUV到RGB的转换功能,从cvPixelBufferRef到CIImage

10

从iOS6开始,苹果公司提供了通过以下调用使用本地YUV到CIImage的选项:

initWithCVPixelBuffer:options:

在核心图像编程指南中,他们提到了这个特性

利用iOS 6.0及更高版本对YUV图像的支持。相机像素缓冲区本机为YUV格式,但大多数图像处理算法期望的是RGBA数据。在两者之间进行转换的代价是很高的。Core Image支持从CVPixelBuffer对象读取YUB并应用适当的颜色转换。

options = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCvCr88iPlanarFullRange) };

但是,我无法正确使用它。我有原始的YUV数据。所以,这就是我所做的。

                void *YUV[3] = {data[0], data[1], data[2]};
                size_t planeWidth[3] = {width, width/2, width/2};
                size_t planeHeight[3] = {height, height/2, height/2};
                size_t planeBytesPerRow[3] = {stride, stride/2, stride/2};
                CVPixelBufferRef pixelBuffer = NULL;
                CVReturn ret = CVPixelBufferCreateWithPlanarBytes(kCFAllocatorDefault,
                               width, 
                               height,
                               kCVPixelFormatType_420YpCbCr8PlanarFullRange, 
                               nil,
                               width*height*1.5,
                               3, 
                               YUV,
                               planeWidth,
                               planeHeight, 
                               planeBytesPerRow, 
                               nil,
                               nil, nil, &pixelBuffer); 

    NSDict *opt =  @{ (id)kCVPixelBufferPixelFormatTypeKey :
                        @(kCVPixelFormatType_420YpCbCr8PlanarFullRange) };

CIImage *image = [[CIImage alloc]   initWithCVPixelBuffer:pixelBuffer options:opt];

我的图片获取到的是nil。有任何想法我可能遗漏了什么吗?

编辑:我在调用之前添加了锁定和解锁基地址。此外,我转储了像素缓冲区的数据以确保像素缓冲区正确地保存了数据。看起来只有初始化调用出了问题。但CIImage对象仍然返回nil。

 CVPixelBufferLockBaseAddress(pixelBuffer, 0);
CIImage *image = [[CIImage alloc]   initWithCVPixelBuffer:pixelBuffer options:opt];
 CVPixelBufferUnlockBaseAddress(pixelBuffer,0);

你解决了吗?如果是,请发布你的解决方案。 - Amitg2k12
嗨Rugger,如果你能解决它,请提供解决方案。谢谢。 - Punita
2个回答

1

控制台应该显示错误消息:initWithCVPixelBuffer failed because the CVPixelBufferRef is not IOSurface backed。请参考苹果的Technical Q&A QA1781了解如何创建IOSurface-backed CVPixelBuffer

调用CVPixelBufferCreateWithBytes()CVPixelBufferCreateWithPlanarBytes()将导致不支持IOSurface的CVPixelBuffers...

...为此,您必须在使用CVPixelBufferCreate()创建像素缓冲区时,在pixelBufferAttributes字典中指定kCVPixelBufferIOSurfacePropertiesKey

NSDictionary *pixelBufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSDictionary dictionary], (id)kCVPixelBufferIOSurfacePropertiesKey,
    nil];
// you may add other keys as appropriate, e.g. kCVPixelBufferPixelFormatTypeKey,     kCVPixelBufferWidthKey, kCVPixelBufferHeightKey, etc.
 
CVPixelBufferRef pixelBuffer;
CVPixelBufferCreate(... (CFDictionaryRef)pixelBufferAttributes,  &pixelBuffer);

或者,您可以使用现有像素缓冲池中的CVPixelBufferPoolCreatePixelBuffer()创建基于IOSurface的CVPixelBuffers,前提是pixelBufferAttributes字典提供给CVPixelBufferPoolCreate()包括kCVPixelBufferIOSurfacePropertiesKey

0

我正在处理一个类似的问题,并且一直找到了来自苹果的同样引用,但没有更多关于如何在YUV颜色空间中工作的信息。我发现以下内容:

默认情况下,Core Image假定处理节点为每像素128位、线性光、预乘RGBA浮点值,使用通用RGB颜色空间。您可以通过提供Quartz 2D CGColorSpace对象来指定不同的工作颜色空间。请注意,工作颜色空间必须基于RGB。如果您有YUV数据作为输入(或其他非基于RGB的数据),则可以使用ColorSync函数将其转换为工作颜色空间。(有关创建和使用CGColorspace对象的信息,请参见Quartz 2D编程指南。) 对于8位YUV 4:2:2源,Core Image可以处理每千兆字节240个高清层。8位YUV是视频源的本机颜色格式,例如DV、MPEG、未压缩D1和JPEG。您需要将YUV颜色空间转换为RGB颜色空间以供Core Image使用。

我注意到没有YUV颜色空间,只有灰度和RGB;以及它们的校准版本。我还不确定如何转换颜色空间,但如果我找到了,我肯定会在这里报告。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接