我正在从iOS AVCaptureSesion读取样本缓冲区,对它们执行一些简单的图像处理,然后从结果图像中分析像素。我使用openCV进行图像处理,但是我想切换到核心图像,我希望这些操作能更有效。但是我完全坚持如何从生成的CIImage中读取像素值。
当我有一个由CGImage支持的UIImage时,我可以使用cgImage dataProvider来访问底层像素数据(例如下面的例子)。但是CIImage的模拟是什么?
以下是我的总体流程:
// Getting sample video data
var session : AVCaptureSession = AVCaptureSession()
// processing the sample buffer with core image
func handleSampleBuffer(sampleBuffer: CMSampleBuffer)
{
let cvImage: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
let ciImage: CIImage = CIImage(cvPixelBuffer: cvImage)
let filteredImage = processWithCoreImage(image: ciImage)
//
// How can I efficiently get pixel values from filtered image here?
//
}
func processWithCoreImage(image: CIImage) -> CIImage
{
// process with a core image filter chain
let filter1 = CIFilter(name: “…”)!
filter1.setValue(image, forKey: kCIInputImageKey)
filter1.setValue(…, forKey: …)
…
let outputImage = filter.outputImage
return outputImage
}
// With a regular UIImage I was doing something like this to get pixel data
// However CIImage does not have a cgImage backing it in this case.
public extension UIImage {
func getPixelValueGrayscale(x: Int, y: Int) -> UInt8 {
let pixelData = self.cgImage!.dataProvider!.data
let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
let pixelInfo: Int = ((Int(self.size.width) * Int(y)) + Int(x))
return data[pixelInfo]
}
}
我已经尝试使用CIContext来获得一个CGImage支持的UIImage,如下所示,但事实证明这种效率非常低 - 每帧占用一小部分时间(比等效的openCV操作长几百倍)。
// re-used CIContext
let cgImage = context.createCGImage(filteredImage, from: ciImage.extent)
let img = UIImage(cgImage: cgImage!)
我还应该提到我的滤镜图像很小(我正在缩小它)。我不知道这是否会引起一些问题。
我错过了什么?感谢。
更新:经过一些实验,结果证明CI中的缩放选项比OpenCV中的缩放选项慢很多。在我的项目中仅仅为了缩放而包含OpenCV感觉是错误的,但是......目前。
答案 0 :(得分:1)
但是我完全不知道如何从生成的CIImage中读取像素值
这个概念毫无意义。 CIImage没有像素值。它只是一组制作图像的说明。那是Core Image的点;在渲染时间之前没有任何事当你说context.createCGImage(filteredImage, from: ciImage.extent)
时, 渲染时间 - 这是一项耗时,计算密集的操作。