1

我正在对实时视频流进行一些实时图像分析。我正在使用 vImage 来计算直方图和 vDSP 以进行进一步处理。我有多年来一直运行良好的 Objective-C 代码。我现在要把它转换成 Swift。虽然它有效,但它太慢了。我发现主要问题是将 vImage 直方图(即 UInt (vImagePixelCount))转换为 vDSP 可以处理的浮点数。在 Objective-C 中,我使用 vDSP 进行转换:

  err = vImageHistogramCalculation_Planar8(&vBuffY,histogramY, 0);
  vDSP_vfltu32((const unsigned int*)histogramY,2,histFloatY,1,256);

但是,vImage 直方图是 UInt,而不是 UInt32,所以我不能在 Swift 中使用 vDSP_vfltu32。相反,我正在使用

  let err = vImageHistogramCalculation_Planar8(&vBuffY, &histogramY, 0)
  let histFloatY = histogramY.compactMap{ Float($0) }

问题是这段代码比 Objective-C 版本慢了 100 多倍。有没有更快的替代品?

4

1 回答 1

3

vImageHistogramCalculation_Planar8()将直方图写入具有 256 个类型元素的缓冲区,vImagePixelCount这是 C 中的类型别名,unsigned long在 64 位平台上是 64 位整数。

您的 Objective-C 代码通过在调用中将 unsigned long 指针转换为 unsigned int 指针vDSP_vfltu32 ()并将步幅设置为2. 所以这里发生的事情是每个的低 32 位unsigned long都转换为float. 只要计数不超过值 2 32 -1,它就可以工作。

你可以在 Swift 中做同样的事情,只是这里的类型转换是通过“重新绑定”内存来完成的:

let err = vImageHistogramCalculation_Planar8(&vBuffY, &histogramY, 0)
histogramY.withUnsafeBytes {
    let uint32ptr = $0.bindMemory(to: UInt32.self)
    vDSP_vfltu32(uint32ptr.baseAddress!, 2, &histFloatY, 1, 256);
}
于 2020-10-09T16:35:25.090 回答