gpt4 book ai didi

swift - 转换为 vImage 的 CMSampleBuffer 帧颜色错误

转载 作者:搜寻专家 更新时间:2023-10-31 22:56:17 24 4
gpt4 key购买 nike

我正在尝试将 CMSampleBuffer 从相机输出转换为 vImage,然后再进行一些处理。不幸的是,即使没有任何进一步的编辑,我从缓冲区获得的帧也有错误的颜色:

Example image of current implementation

实现(不考虑内存管理和错误):

配置视频输出设备:

    videoDataOutput = AVCaptureVideoDataOutput()
videoDataOutput.videoSettings = [String(kCVPixelBufferPixelFormatTypeKey): kCVPixelFormatType_32BGRA]
videoDataOutput.alwaysDiscardsLateVideoFrames = true
videoDataOutput.setSampleBufferDelegate(self, queue: captureQueue)
videoConnection = videoDataOutput.connection(withMediaType: AVMediaTypeVideo)

captureSession.sessionPreset = AVCaptureSessionPreset1280x720

let videoDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
guard let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice) else {
return
}

从从相机接收到的 CASampleBuffer 创建 vImage:

   // Convert `CASampleBuffer` to `CVImageBuffer`
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }

var buffer: vImage_Buffer = vImage_Buffer()
buffer.data = CVPixelBufferGetBaseAddress(pixelBuffer)
buffer.rowBytes = CVPixelBufferGetBytesPerRow(pixelBuffer)
buffer.width = vImagePixelCount(CVPixelBufferGetWidth(pixelBuffer))
buffer.height = vImagePixelCount(CVPixelBufferGetHeight(pixelBuffer))

let vformat = vImageCVImageFormat_CreateWithCVPixelBuffer(pixelBuffer)
let bitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.last.rawValue | CGBitmapInfo.byteOrder32Little.rawValue)

var cgFormat = vImage_CGImageFormat(bitsPerComponent: 8,
bitsPerPixel: 32,
colorSpace: nil,
bitmapInfo: bitmapInfo,
version: 0,
decode: nil,
renderingIntent: .defaultIntent)

// Create vImage
vImageBuffer_InitWithCVPixelBuffer(&buffer, &cgFormat, pixelBuffer, vformat!.takeRetainedValue(), cgColor, vImage_Flags(kvImageNoFlags))

将缓冲区转换为 UIImage:

为了测试,将 CVPixelBuffer 导出到 UIImage,但将其添加到视频缓冲区具有相同的结果。

var dstPixelBuffer: CVPixelBuffer?

let status = CVPixelBufferCreateWithBytes(nil, Int(buffer.width), Int(buffer.height),
kCVPixelFormatType_32BGRA, buffer.data,
Int(buffer.rowBytes), releaseCallback,
nil, nil, &dstPixelBuffer)

let destCGImage = vImageCreateCGImageFromBuffer(&buffer, &cgFormat, nil, nil, numericCast(kvImageNoFlags), nil)?.takeRetainedValue()

// create a UIImage
let exportedImage = destCGImage.flatMap { UIImage(cgImage: $0, scale: 0.0, orientation: UIImageOrientation.right) }

DispatchQueue.main.async {
self.previewView.image = exportedImage
}

最佳答案

尝试在您的 CV 图像格式上设置色彩空间:

    let vformat = vImageCVImageFormat_CreateWithCVPixelBuffer(pixelBuffer).takeRetainedValue()

vImageCVImageFormat_SetColorSpace(vformat,
CGColorSpaceCreateDeviceRGB())

...并更新对 vImageBuffer_InitWithCVPixelBuffer 的调用以反射(reflect) vformat 现在是托管引用这一事实:

    let error = vImageBuffer_InitWithCVPixelBuffer(&buffer, &cgFormat, pixelBuffer, vformat, nil, vImage_Flags(kvImageNoFlags))

最后,您可以删除以下行,vImageBuffer_InitWithCVPixelBuffer 正在为您完成这项工作:

//        buffer.data = CVPixelBufferGetBaseAddress(pixelBuffer)
// buffer.rowBytes = CVPixelBufferGetBytesPerRow(pixelBuffer)
// buffer.width = vImagePixelCount(CVPixelBufferGetWidth(pixelBuffer))
// buffer.height = vImagePixelCount(CVPixelBufferGetHeight(pixelBuffer))

请注意,您不需要锁定 Core Video 像素缓冲区,如果您检查 headerdoc,它说“在调用此函数之前不需要锁定 CVPixelBuffer”。

关于swift - 转换为 vImage 的 CMSampleBuffer 帧颜色错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46140785/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com