Swift 中的快速 UInt 到 Float 转换

Fast UInt to Float conversion in Swift

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

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

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

您的 Objective-C 代码通过在对 vDSP_vfltu32 () 的调用中将 unsigned long 指针转换为 unsigned int 指针并将步幅设置为 2 来“作弊”。所以这里发生的是每个 unsigned long 的低 32 位被转换为 float。只要计数不超过值 232-1.

您可以在 Swift 中执行完全相同的操作,只是这里的类型转换是通过“重新绑定”内存来完成的:

let err = vImageHistogramCalculation_Planar8(&vBuffY, &histogramY, 0)
histogramY.withUnsafeBytes {
    let uint32ptr = [=10=].bindMemory(to: UInt32.self)
    vDSP_vfltu32(uint32ptr.baseAddress!, 2, &histFloatY, 1, 256);
}