如何从CVPixelBufferRef获取RGB(或任何其他格式)像素值?香港专业教育学院尝试了许多方法,但没有成功。
func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) { let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)! CVPixelBufferLockBaseAddress(pixelBuffer, 0) let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer) //Get individual pixel values here CVPixelBufferUnlockBaseAddress(pixelBuffer, 0) }
baseAddress是不安全的可变指针,或更确切地说是UnsafeMutablePointer<Void>。将指针转换Void为更特定的类型后,即可轻松访问内存:
baseAddress
UnsafeMutablePointer<Void>
Void
// Convert the base address to a safe pointer of the appropriate type let byteBuffer = UnsafeMutablePointer<UInt8>(baseAddress) // read the data (returns value of type UInt8) let firstByte = byteBuffer[0] // write data byteBuffer[3] = 90
确保使用正确的类型(8、16或32位unsigned int)。这取决于视频格式。最有可能是8位。
缓冲区格式的更新:
您可以在初始化AVCaptureVideoDataOutput实例时指定格式。您基本上可以选择:
AVCaptureVideoDataOutput
如果您对颜色值和速度(或更确切地说,最大帧速率)不感兴趣,那么请选择更简单的BGRA格式。否则,请选择一种更有效的本机视频格式。
如果有两个平面,则必须获取所需平面的基址(请参见视频格式示例):
视频格式示例
let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)! CVPixelBufferLockBaseAddress(pixelBuffer, 0) let baseAddress = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0) let bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0) let byteBuffer = UnsafeMutablePointer<UInt8>(baseAddress) // Get luma value for pixel (43, 17) let luma = byteBuffer[17 * bytesPerRow + 43] CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
BGRA示例
let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)! CVPixelBufferLockBaseAddress(pixelBuffer, 0) let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer) let int32PerRow = CVPixelBufferGetBytesPerRow(pixelBuffer) let int32Buffer = UnsafeMutablePointer<UInt32>(baseAddress) // Get BGRA value for pixel (43, 17) let luma = int32Buffer[17 * int32PerRow + 43] CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)