gpt4 book ai didi

来自 ARKit 深度缓冲区的 SceneKit 点云

转载 作者:行者123 更新时间:2023-12-04 07:55:59 25 4
gpt4 key购买 nike

我试图在 SceneKit 中找到一种简单的方法来计算 SceneKit 中的像素深度和 LiDAR 数据sceneView.session.currentFrame?.smoothedSceneDepth?.depthMap

理想情况下,我不想使用金属着色器。我更愿意在我的 currentFrame 中找到一个点及其相应的深度图,以获取 SceneKit 中的一个点的深度(理想情况下是在世界坐标中,而不仅仅是那个时间点的局部视锥体)。

不需要快速性能,因为它不会在捕获时计算。

我在 link 知道 Apple 项目,但这对我的需求来说太复杂了。

作为起点,我的代码是这样工作的:

    
guard let depthData = frame.sceneDepth else { return }
let camera = frame.camera

let depthPixelBuffer = depthData.depthMap
let depthHeight = CVPixelBufferGetHeight(depthPixelBuffer)
let depthWidth = CVPixelBufferGetWidth(depthPixelBuffer)
let resizeScale = CGFloat(depthWidth) / CGFloat(CVPixelBufferGetWidth(frame.capturedImage))
let resizedColorImage = frame.capturedImage.toCGImage(scale: resizeScale);
guard let colorData = resizedColorImage.pixelData() else {
fatalError()
}

var intrinsics = camera.intrinsics;
let referenceDimensions = camera.imageResolution;
let ratio = Float(referenceDimensions.width) / Float(depthWidth)

intrinsics.columns.0[0] /= ratio
intrinsics.columns.1[1] /= ratio
intrinsics.columns.2[0] /= ratio
intrinsics.columns.2[1] /= ratio

var points: [SCNVector3] = []

let depthValues = depthPixelBuffer.depthValues()

for vv in 0..<depthHeight {
for uu in 0..<depthWidth {
let z = -depthValues[uu + vv * depthWidth]
let x = Float32(uu) / Float32(depthWidth) * 2.0 - 1.0;
let y = 1.0 - Float32(vv) / Float32(depthHeight) * 2.0;
points.append(SCNVector3(x, y, z))
}
}

生成的点云看起来不错,但在 Z 轴上严重弯曲。我意识到这段代码也没有针对屏幕方向进行调整。

最佳答案

一位库比蒂诺人在 developer.apple.com 的论坛上回复了我:

无论是在 CPU 端还是 GPU 端,非投影计算本身都是相同的。

CPU 方面,计算看起来像这样:

/// Returns a world space position given a point in the camera image, the eye space depth (sampled/read from the corresponding point in the depth image), the inverse camera intrinsics, and the inverse view matrix.

func worldPoint(cameraPoint: SIMD2<Float>, eyeDepth: Float, cameraIntrinsicsInversed: simd_float3x3, viewMatrixInversed: simd_float4x4) -> SIMD3<Float> {
let localPoint = cameraIntrinsicsInversed * simd_float3(cameraPoint, 1) * -eyeDepth
let worldPoint = viewMatrixInversed * simd_float4(localPoint, 1);
return (worldPoint / worldPoint.w)[SIMD3(0,1,2)];
}

实现了,这看起来像

for vv in 0..<depthHeight {
for uu in 0..<depthWidth {
let z = -depthValues[uu + vv * depthWidth]
let viewMatInverted = (sceneView.session.currentFrame?.camera.viewMatrix(for: UIApplication.shared.statusBarOrientation))!.inverse
let worldPoint = worldPoint(cameraPoint: SIMD2(Float(uu), Float(vv)), eyeDepth: z, cameraIntrinsicsInversed: intrinsics.inverse, viewMatrixInversed: viewMatInverted * rotateToARCamera )
points.append(SCNVector3(worldPoint))
}
}

点云非常困惑,需要确定置信度,在发生 Int 舍入的垂直方向上存在间隙,但这是一个良好的开端。缺少的功能来自上述问题中指向 Apple 演示项目的链接。

关于来自 ARKit 深度缓冲区的 SceneKit 点云,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66705267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com