CIImage像素的RGB值

时间:2019-12-18 16:35:41

标签: swift arkit core-image ciimage cvpixelbuffer

我想实时访问从CVPixelBuffer获得的ARFrame特定区域的平均颜色值。我设法裁剪图像,使用滤镜计算平均颜色,转换为CGImage后,我从像素获得了值,但是不幸的是,它影响了我的应用程序的性能(FPS降至30fps以下)。我认为这样做的原因是使用CGContext。是否可以在不将CIImage转换为CGImage的情况下访问颜色? 这是我目前正在使用的代码:

func fun() {
  let croppVector = CIVector(cgRect: inputImageRect)

  guard let filter = CIFilter(
    name: "CIAreaAverage",
    parameters: [kCIInputImageKey: image, kCIInputExtentKey: croppVector]
  ),
    let outputImage = filter.outputImage,
    let cgImage = context.createCGImage(
      outputImage,
      from: CGRect(x: 0, y: 0, width: 1, height: 1)
    ),
    let dataProvider = cgImage.dataProvider,
    let data = CFDataGetBytePtr(dataProvider.data) else { return nil }

  let color = UIColor(
    red: CGFloat(data[0]) / 255,
    green: CGFloat(data[1]) / 255,
    blue: CGFloat(data[2]) / 255,
    alpha: CGFloat(data[3]) / 255
  )
}

1 个答案:

答案 0 :(得分:0)

我认为您在这里不能做太多–这样的还原操作非常昂贵。

您可以尝试一些操作:

  • 通过将CIContext.workingColorSpace选项设置为.outputColorSpace,将NSNull()设置为执行任何颜色管理。
  • 直接渲染到内存中,而不用经过CGImage。上下文具有您可以使用的方法render(_ image: CIImage, toBitmap data: UnsafeMutableRawPointer, rowBytes: Int, bounds: CGRect, format: CIFormat, colorSpace: CGColorSpace?)。还要在此处传递nil作为色彩空间。您应该可以在此处将“指针”传递为simd_uchar4data变量。我认为,在这种情况下,rowBytes为4,格式为.BGRA8
  • 您还可以在进行平均计算之前尝试按比例缩小图像(这已经是缩小操作)。它的值不是相同的,而是一个近似值–可能会更快。