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

时间:2013-11-08 04:21:30

标签: ios objective-c ios6 core-image

从iOS6开始,Apple通过此次调用提供了使用原生YUV到CIImage的规定

  

initWithCVPixelBuffer:选择:

在核心图像编程指南中,他们提到了此功能

  

利用iOS 6.0及更高版本中对YUV图像的支持。   相机像素缓冲区本身是YUV但是大多数图像处理   算法期望RBGA数据。转换之间需要付出代价   二。 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];

我的形象是零。我不知道我错过了什么。

修改  我在通话前添加了锁定和解锁基地址。另外,我转储了pixelbuffer的数据,以确保pixellbuffer能够正确保存数据。它看起来只是init调用的错误。仍然CIImage对象返回nil。

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

2 个答案:

答案 0 :(得分:1)

控制台中应该有错误消息:initWithCVPixelBuffer failed because the CVPixelBufferRef is not IOSurface backed。有关如何创建支持IOSurface的CVPixelBuffer,请参阅Apple的Technical Q&A QA1781

  

致电CVPixelBufferCreateWithBytes()CVPixelBufferCreateWithPlanarBytes()会导致CVPixelBuffers不是IOSurface支持的......

     

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

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);
  

或者,如果提供给CVPixelBuffers的{​​{1}}词典包含CVPixelBufferPoolCreatePixelBuffer(),您可以使用现有像素缓冲池中的pixelBufferAttributes来支持IOSurface支持的CVPixelBufferPoolCreate()

答案 1 :(得分:0)

我正在研究类似的问题并且不断发现Apple的相同引用,而没有关于如何在YUV色彩空间中工作的任何进一步信息。我发现了以下内容:

  

默认情况下,Core Image假设处理节点是每像素128位,线性光,使用GenericRGB色彩空间的预乘RGBA浮点值。您可以通过提供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颜色空间转换为Core Image的RGB颜色空间。

我注意到没有YUV颜色空间,只有Gray和RGB;和他们校准的堂兄弟。我还不确定如何转换色彩空间,但如果我发现,肯定会报告。