【问题标题】:How to get the value of kCVPixelFormatType_DepthFloat16 (half-point float)?如何获取kCVPixelFormatType_DepthFloat16(半点浮点数)的值?
【发布时间】:2020-06-13 06:43:03
【问题描述】:

我正在使用 swift 处理 iOS 前置深度摄像头的项目。根据苹果文档,媒体类型为kCVPixelFormatType_DepthFloat16,半点浮点数为 640*360 尺寸,30fps。我被困在如何逐个像素地进一步检索和处理值。

let buffer:CVPixelBuffer = depthData.depthDataMap //depthData is AVDepthData type
CVPixelBufferLockBaseAddress(buffer, CVPixelBufferLockFlags(rawValue: 0))
let width = CVPixelBufferGetWidth(buffer)
let height = CVPixelBufferGetHeight(buffer)
for y in 0 ..< height {
  for x in 0 ..< width {
    let pixel = ?? //what should I do here?
  }
}

【问题讨论】:

  • 找同样的资料,不能帮你atm~
  • @itMaxence 我已经解决了!你可以看看我自己的答案。

标签: ios swift half-precision-float


【解决方案1】:

我已经解决了我的问题。这可以通过两种方式完成。

  1. 使用kCVPixelFormatType_DepthFloat32而不是kCVPixelFormatType_DepthFloat16,它将与之前的深度图具有相同的维度和fps。然后你可以将它转换为 Swift Float 类型,如下所示:
let width = CVPixelBufferGetWidth(buffer)
let height = CVPixelBufferGetHeight(buffer)

CVPixelBufferLockBaseAddress(buffer, CVPixelBufferLockFlags(rawValue: 0))
let floatBuffer = unsafeBitCast(CVPixelBufferGetBaseAddress(buffer), to: UnsafeMutablePointer<Float>.self)

for y in 0 ..< height {
    for x in 0 ..< width {
        let pixel = floatBuffer[y*width+x]
    }
}
CVPixelBufferUnlockBaseAddress(self, CVPixelBufferLockFlags(rawValue: 0))
  1. 第二种方法是先转换成UInt16,然后在它前面加两个零字节
// to access the point height = y, width = x, thanks to this project https://github.com/edvardHua/Articles/tree/master/%5BAR:MR%20%E5%9F%BA%E7%A1%80%5D%20%E5%88%A9%E7%94%A8%20iPhone%20X%20%E7%9A%84%E6%B7%B1%E5%BA%A6%E7%9B%B8%E6%9C%BA(TruthDepth%20Camera)%E8%8E%B7%E5%BE%97%E5%83%8F%E7%B4%A0%E7%82%B9%E7%9A%84%E4%B8%89%E7%BB%B4%E5%9D%90%E6%A0%87/Obtain3DCoordinate
let rowData = CVPixelBufferGetBaseAddress(buffer)! + Int(y) *  CVPixelBufferGetBytesPerRow(buffer)
var f16Pixel = rowData.assumingMemoryBound(to: UInt16.self)[x]
var f32Pixel = Float(0.0)
var src = vImage_Buffer(data: &f16Pixel, height: 1, width: 1, rowBytes: 2)
var dst = vImage_Buffer(data: &f32Pixel, height: 1, width: 1, rowBytes: 4)
vImageConvert_Planar16FtoPlanarF(&src, &dst, 0)
let depth = f32Pixel //depth in cm

【讨论】:

  • 我发现的更多信息:1. 字节缓冲区是“ROW 主要”,2. 平面用于不同的颜色(因此没有平面用于深度数据) 3. Float16 与 GPU 和 Float32 一起使用与 CPU 一起工作。 4. 如果您从事计算机视觉工作,请使用 cameraCalibrationData 标准化您的 3D 深度图。最佳链接:developer.apple.com/videos/play/wwdc2017/507
  • 还有一个link to better understand image formats在CVPixelBuffer中使用。
猜你喜欢
  • 1970-01-01
  • 2020-04-15
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多