Ios Swift中的快速UInt到浮点转换

Ios Swift中的快速UInt到浮点转换,ios,swift,histogram,vdsp,vimage,Ios,Swift,Histogram,Vdsp,Vimage,我正在现场视频流上做一些实时图像分析。我正在使用vImage计算直方图和vDSP,以便进行进一步处理。我有Objective-C代码,多年来一直运行良好。我现在要把它转换成Swift。虽然它能工作,但速度太慢了。我发现主要问题是将vImage直方图(即UInt(vImagePixelCount))转换为vDSP可以处理的浮点值。在Objective-C中,我使用vDSP进行转换: err = vImageHistogramCalculation_Planar8(&vBuffY,his

我正在现场视频流上做一些实时图像分析。我正在使用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多倍。有更快的替代方法吗?

VimageHistorogramCalculation\u Planar8()
将直方图写入包含256个元素的缓冲区,类型为
vImagePixelCount
,这是C中的
unsigned long
的类型别名,在64位平台上是64位整数

在调用
vDSP\u vfltu32()
并将步长设置为
2
时,您的Objective-C代码通过将无符号长指针投射到无符号int指针来“作弊”。因此,这里发生的事情是,每个
无符号long
的低位32位被转换为
浮点值。只要计数不超过值232-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);
}

为什么不使用swift版本?尝试
vDSP\u vfltu32(historogramy,2,&histFloatY,1256)
其中
histFloatY
是一个
var
。如问题中所述,vDSP\u vfltu32是否希望UInt32而不是UInt。首先转换到UInt32同样缓慢。谢谢,这可能是朝着正确方向迈出的一步。但“withMemoryRebound”仅在参数具有相同内存大小时才起作用(文档中有注释)。因此,代码在64位设备上因“致命错误”而崩溃。@Sten:你说得对(该约束是新的,或者在以前的Swift版本中没有强制执行,所以我错过了)。我已更新代码以使用bindMemory,请再次检查。谢谢!它工作良好,性能与Objective-c代码相同。它与原始代码具有相同的2^32限制,但在我的情况下这绝对没有问题。