嘿,我正在尝试使用 AVCaptureSession 访问 iPhone 相机的原始数据。我遵循 Apple 提供的指南 ( link here )。
samplebuffer中的原始数据是YUV格式(我对原始视频帧格式的理解是否正确??),如何从samplebuffer中存储的原始数据中直接获取Y分量的数据。
最佳答案
当设置返回原始相机帧的 AVCaptureVideoDataOutput 时,您可以使用如下代码设置帧的格式:
[videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
在本例中,指定了 BGRA 像素格式(我使用它来匹配 OpenGL ES 纹理的颜色格式)。该格式的每个像素都有一个字节,按顺序表示蓝色、绿色、红色和 alpha。这样做可以很容易地提取颜色分量,但由于需要从相机 native YUV 颜色空间进行转换,您确实牺牲了一点性能。
其他受支持的色彩空间包括较新设备上的 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
和 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
以及 iPhone 3G 上的 kCVPixelFormatType_422YpCbCr8
。 VideoRange
或 FullRange
后缀仅指示返回的字节是否在 Y 的 16 - 235 和 UV 的 16 - 240 之间,还是每个组件的完整 0 - 255 之间。
我相信 AVCaptureVideoDataOutput 实例使用的默认色彩空间是 YUV 4:2:0 平面色彩空间(iPhone 3G 除外,它是 YUV 4:2:2 交错)。这意味着视频帧中包含两个图像数据平面,Y 平面在前。对于生成的图像中的每个像素,该像素处的 Y 值都有一个字节。
您可以通过在委托(delegate)回调中实现类似的操作来获取原始 Y 数据:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
unsigned char *rawPixelBase = (unsigned char *)CVPixelBufferGetBaseAddress(pixelBuffer);
// Do something with the raw pixels here
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}
然后,您可以找出图像上每个 X、Y 坐标在帧数据中的位置,并拉出与该坐标处的 Y 分量相对应的字节。
Apple 的 FindMyiCone 样本来自 WWDC 2010 (可与视频一起访问)展示了如何处理每帧的原始 BGRA 数据。我还创建了一个示例应用程序,您可以下载 here 的代码,执行 color-based object tracking使用 iPhone 摄像头的实时视频。两者都展示了如何处理原始像素数据,但它们都不能在 YUV 色彩空间中工作。
关于iphone - 如何从 AVCaptureSession 产生的 CMSampleBuffer 中获取 Y 分量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4085474/