我正在将ARKit与CNN结合起来,以便在它们漂移时不断更新ARKit节点。所以:
问题在于#2需要0.3秒左右。因此我无法使用[
{
"outputFile": "assets/scss/test-page.css",
"inputFile": "assets/scss/test-page.scss"
}
]
,因为该点将对应于设备从#1开始的世界位置的3D点。
如何计算从旧位置到CNN 2D点的3D矢量?
答案 0 :(得分:2)
unprojectPoint
只是一个矩阵数学便利函数,类似于许多面向图形的库(如DirectX,旧式OpenGL,Three.js等)中的函数。在SceneKit中,它作为视图的方法提供,这意味着它使用模型/视图/投影矩阵和视口当前用于渲染的视图。但是,如果您知道该功能的工作原理,您可以自己实现它。
Unproject功能通常会做两件事:
将视口坐标(像素)转换为剪辑空间坐标系(所有方向的-1.0到1.0)。
反转投影变换(假设剪辑空间中有一些任意Z值)和视图(相机)变换以获得3D世界空间坐标。
鉴于这些知识,我们可以建立自己的功能。 (警告:未经测试。)
func unproject(screenPoint: float3, // see below for Z depth hint discussion
modelView: float4x4,
projection: float4x4,
viewport: CGRect) -> float3 {
// viewport to clip: subtract viewport origin, divide by size,
// scale/offset from 0...1 to -1...1 coordinate space
let clip = (screenPoint - float3(viewport.x, viewport.y, 1.0))
/ float3(viewport.width, viewport.height, 1.0)
* float3(2) - float3(1)
// apply the reverse of the model-view-projection transform
let inversePM = (projection * modelView).inverse
let result = inversePM * float4(clip.x, clip.y, clip.z, 1.0)
return float3(result.x, result.y, result.z) / result.w // perspective divide
}
现在,要使用它...您传递给此函数的modelView
矩阵与ARCamera.transform
相反,您也可以直接从projectionMatrix
获取ARCamera
。因此,如果您在某个时间点抓取2D位置,那么也可以抓住相机矩阵,这样您就可以在此时向后工作3D。
我还提到了“Z深度提示”的问题:当渲染器将3D投影到2D时,它会丢失信息(实际上是其中一个D')。因此,当您转换回3D时,您必须恢复或猜测该信息 - 传递给上述函数的screenPoint
是x和y像素坐标,加上0到1之间的深度值.Zo更接近于相机,1更远。如何使用这种方式取决于算法的其余部分是如何设计的。 (至少,您可以取消投影Z = 0和Z = 1,并且您将获得3D线段的端点,原点某处沿着该线。)
当然,这是否真的可以与你的新颖的基于CNN的方法放在一起完全是另一个问题。但至少你学到了一些有用的3D图形数学!