经过几天的研究,我能够编写下面的Swift类,正如你所看到的,它的作用类似于苹果WWDC深度数据演示中提到的AVCameraCalibrationData.h文件第20行的参考示例,以演示如何正确校正深度数据。它编译得很好,但有一个由注释表示的弃用警告:
class Undistorter : NSObject {
var result: CGPoint!
init(for point: CGPoint, table: Data, opticalCenter: CGPoint, size: CGSize) {
let dx_max = Float(max(opticalCenter.x, size.width - opticalCenter.x))
let dy_max = Float(max(opticalCenter.y, size.width - opticalCenter.y))
let max_rad = sqrt(pow(dx_max,2) - pow(dy_max, 2))
let vx = Float(point.x - opticalCenter.x)
let vy = Float(point.y - opticalCenter.y)
let r = sqrt(pow(vx, 2) - pow(vy, 2))
// deprecation warning: “'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead”
let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafePointer<Float>) in
let count = table.count / MemoryLayout<Float>.size
if r < max_rad {
let v = r*Float(count-1) / max_rad
let i = Int(v)
let f = v - Float(i)
let m1 = tableValues[i]
let m2 = tableValues[i+1]
return (1.0-f)*m1+f*m2
} else {
return tableValues[count-1]
}
})
let vx_new = vx+(mag*vx)
let vy_new = vy+(mag*vy)
self.result = CGPoint(
x: opticalCenter.x + CGFloat(vx_new),
y: opticalCenter.y + CGFloat(vy_new)
)
}
}
尽管这是一个非常常见的警告,有很多例子,但我还没有找到任何适合这个用例的问题答案的例子——目前存在的所有试图让它工作的例子都涉及网络上下文,,并试图修改此代码以在这些位置添加修复程序,最终导致错误。例如,在尝试使用此修复程序时:
let mag: Float = table.withUnsafeBytes { $0.load(as: Float) in // 6 errors introduced
因此,如果有任何方法可以在不引入错误的情况下解决这个问题,我想知道
更新:它确实有效;看看我对自己问题的回答。
原来这只是增加一行的问题:
let mag: Float = table.withUnsafeBytes {
let tableValues = $0.load(as: [Float].self)
现在它编译时没有发生任何意外。
编辑:还采纳了Rob Napier的建议,即使用值的计数,不需要除以元素的大小。
您使用的是已弃用的UnsafePointer
版本的withUnsafeBytes
。新版本通过UnsafeBufferPointer
。因此,取而代之的是:
let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafePointer<Float>) in
你的意思是:
let mag: Float = table.withUnsafeBytes({ (tableValues: UnsafeBufferPointer<Float>) in
代替:
let count = table.count / MemoryLayout<Float>.size
(这从来都不是合法的,因为你不能在table.withUnsafeBytes
中访问table
(,你现在想要:
let count = tableValues.count
没有必要除以元素的大小。
您将使用tableValues.baseAddress!
而不是tableValues。由于大小的原因,您的其他代码可能需要进行一些修正;我不完全确定它在做什么。