【问题标题】:Flip ARFaceAnchor from left-handed to right-handed coordinate system将 ARFaceAnchor 从左手坐标系翻转到右手坐标系
【发布时间】:2020-11-11 08:03:09
【问题描述】:

通过打印faceAnchor.transform.columns.3 进行一些测试后,挖掘SO:ARFaceAnchor have negative Z position? 和Apple 的文档:ARFaceAnchor,我意识到z 轴实际上是翻转的,它不是文档中的右手坐标系. ARFaceAnchor 声明坐标:

x 正方向指向观察者的右侧(即人脸自身的左侧),y 正方向指向上方(相对于人脸本身,而不是世界),z 正方向指向从面对(朝向观察者)


Sarasvati 提出了关于进行改造的建议:

    func faceAnchorPoseToRHS(_ mat: float4x4) -> float4x4 {
    let correctedPos = float4(x: mat.columns.3.x, y: mat.columns.3.y, z: -mat.columns.3.z, w: 1)

    let quat = simd_quatf(mat)
    let newQuat = simd_quatf(angle: -quat.angle, axis: float3(quat.axis.x, quat.axis.y, -quat.axis.z))
    var newPose = float4x4(newQuat)
    newPose.columns.3 = correctedPos

    return newPose
}

基于 Andy Fedoroff 的更新:

extension ViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let faceAnchor = anchor as? ARFaceAnchor else { return }
        currentFaceAnchor = faceAnchor
        if node.childNodes.isEmpty, let contentNode = selectedContentController.renderer(renderer, nodeFor: faceAnchor) {
            node.addChildNode(contentNode)
        }
        selectedContentController.session = sceneView?.session
        selectedContentController.sceneView = sceneView
    }
    /// - Tag: ARFaceGeometryUpdate
    func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
        guard anchor == currentFaceAnchor,
            let contentNode = selectedContentController.contentNode,
            contentNode.parent == node
            else { return }
        sceneView.session.currentFrame!.anchors.first!.transform
        print(currentFaceAnchor!.transform.columns.3)
        selectedContentController.session = sceneView?.session
        selectedContentController.sceneView = sceneView
        selectedContentController.renderer(renderer, didUpdate: contentNode, for: anchor)
    }
}

但是,我打印了faceAnchor.transform.columns.3 并使用 True Depth 相机获得了 z 负片。下图显示 x,y,z,w 轴:

关于如何校正 z 轴的任何建议?提前谢谢你

【问题讨论】:

    标签: swift xcode augmented-reality scenekit arkit


    【解决方案1】:

    首先,让我们看看默认矩阵值是什么。


    恒等矩阵

    这是一个带有默认值的Identity 4x4 matrix

    如果您需要有关4x4 matrices 元素的更多信息,请阅读this post

     // 0  1  2  3
     ┌              ┐
     |  1  0  0  0  |  x
     |  0  1  0  0  |  y
     |  0  0  1  0  |  z
     |  0  0  0  1  |
     └              ┘
    


    位置镜像

    要翻转实体的Z axisX axis,以便将轴从人脸跟踪环境重新定向到世界跟踪环境,请使用4x4 transform matrix 的以下形式。

     // 0  1  2  3
     ┌              ┐
     | -1  0  0  0  |  x
     |  0  1  0  0  |  y
     |  0  0 -1  0  |  z
     |  0  0  0  1  |
     └              ┘
    


    旋转镜像

    4x4 transform matrices 中,旋转是一个combination of scale and skew。要选择正确的旋转方向,顺时针 (CW) 或逆时针 (CCW) 使用 +- 表示 cos 表达式。

    这是一个正 Z 旋转表达式 (CCW)。

    正面+cos(a)

     ┌                    ┐
     | cos -sin   0    0  |
     | sin  cos   0    0  |
     |  0    0    1    0  |
     |  0    0    0    1  |
     └                    ┘
    


    这是一个负 Z 旋转表达式 (CW)。

    否定-cos(a)

     ┌                    ┐
     |-cos -sin   0    0  |
     | sin -cos   0    0  |
     |  0    0    1    0  |
     |  0    0    0    1  |
     └                    ┘
    

    【讨论】:

    • 是的,在会话的 ARFrame 中。与sceneView.session.currentFrame!.anchors.first!.transform 相同,但您需要在 renderer(...) 或 session(...) 委托方法中使用此行。
    • 你能告诉我你到底想要什么吗?是否要重新定位人脸锚点?
    • 相对于观察者来说它是右手的,但相对于世界空间来说它是左手的。
    • 我认为这就是我相信的文档。如果是这种情况,当我使用真值深度进行面部跟踪时,我是否应该看到正 z 轴?当我打印 transform.columns.3 时,它显示的是负 z 轴(如上图所示的 simd4 图片)。我只是无法直接在这里。谢谢你的耐心! @安迪费多罗夫!
    • 我认为你在这里解释得很好。但我只是不确定 TrueDepth 相机是镜像是什么意思,根据右手坐标的定义,我认为我们应该看到正 z 轴。
    猜你喜欢
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 2017-01-05
    相关资源
    最近更新 更多