【问题标题】:Coordinates of ARImageAnchor transform matrix are way too different from the ARPlaneAnchor onesARImageAnchor 变换矩阵的坐标与 ARPlaneAnchor 的坐标相差太大
【发布时间】:2018-08-21 23:16:57
【问题描述】:

我正在做这个简单的事情:

  1. 垂直平面检测
  2. 垂直平面上的图像识别

图像挂在检测到的平面上(在我的墙上)。在这两种情况下,我都从ARSCNViewDelegate 实现了renderer:didAddNode:forAnchor: 函数。我站在垂直平面检测和图像识别的地方。

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let shipScene = SCNScene(named: "ship.scn"), let shipNode = shipScene.rootNode.childNode(withName: "ship", recursively: false) else { return }
    shipNode.position = SCNVector3(anchor.transform.columns.3.x, anchor.transform.columns.3.y, anchor.transform.columns.3.z)
    sceneView.scene.rootNode.addChildNode(shipNode)
    print(anchor.transform)
}

在垂直平面检测的情况下,anchor 将是ARPlaneAnchor。在图像识别的情况下,anchor 将是 ARImageAnchor

为什么这两个锚的变换矩阵如此不同?我正在打印anchor.transform,我得到了这些结果:

1.

simd_float4x4([
    [0.941312,  0.0,        -0.337538,  0.0)],
    [0.336284,  -0.0861278, 0.937814,   0.0)],
    [-0.0290714,-0.996284,  -0.0810731, 0.0)],
    [0.191099,  0.172432,   -1.14543,   1.0)]
])

2.

simd_float4x4([
    [0.361231,  0.10894,    0.926093,   0.0)],
    [-0.919883, -0.121052,  0.373049,   0.0)],
    [0.152743,  -0.986651,  0.0564843,  0.0)],
    [75.4418,   10.9618,    -14.3788,   1.0)]
])

所以如果我想在检测到的垂直平面上放置一个 3D 对象,我可以简单地使用[x = 0.191099, y = 0.172432, z = -1.14543] 作为坐标来设置我的节点(myNode)的位置,然后使用@987654334 将此节点添加到场景中@ 但是如果我想在检测到的图像的锚点上放置一个 3D 对象,我不能使用[x = 75.4418, y = 10.9618, z = -14.3788]

如何将 3D 对象放置在检测到的图像的锚点上?我真的不明白 ARImageAnchor 的变换矩阵。

【问题讨论】:

    标签: ios swift augmented-reality arkit


    【解决方案1】:

    这是我使用func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) 方法的示例:

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    
        //1. If Out Target Image Has Been Detected Than Get The Corresponding Anchor
        guard let currentImageAnchor = anchor as? ARImageAnchor else { return }
    
        let x = currentImageAnchor.transform
        print(x.columns.3.x, x.columns.3.y , x.columns.3.z)
    
        //2. Get The Targets Name
        let name = currentImageAnchor.referenceImage.name!
    
        //3. Get The Targets Width & Height In Meters
        let width = currentImageAnchor.referenceImage.physicalSize.width
        let height = currentImageAnchor.referenceImage.physicalSize.height
    
        print("""
        Image Name = \(name)
        Image Width = \(width)
        Image Height = \(height)
        """)
    
        //4. Create A Plane Geometry To Cover The ARImageAnchor
        let planeNode = SCNNode()
        let planeGeometry = SCNPlane(width: width, height: height)
        planeGeometry.firstMaterial?.diffuse.contents = UIColor.white
        planeNode.opacity = 0.25
        planeNode.geometry = planeGeometry
    
        //5. Rotate The PlaneNode To Horizontal
        planeNode.eulerAngles.x = -.pi/2
    
        //The Node Is Centered In The Anchor (0,0,0)
        node.addChildNode(planeNode)
    
    
        //6. Create AN SCNBox
        let boxNode = SCNNode()
        let boxGeometry = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
    
        //7. Create A Different Colour For Each Face
        let faceColours = [UIColor.red, UIColor.green, UIColor.blue, UIColor.cyan, UIColor.yellow, UIColor.gray]
        var faceMaterials = [SCNMaterial]()
    
        //8. Apply It To Each Face
        for face in 0 ..< 5{
            let material = SCNMaterial()
            material.diffuse.contents = faceColours[face]
            faceMaterials.append(material)
        }
        boxGeometry.materials = faceMaterials
        boxNode.geometry = boxGeometry
    
        //9. Set The Boxes Position To Be Placed On The Plane (node.x + box.height)
        boxNode.position = SCNVector3(0 , 0.05, 0)
    
        //10. Add The Box To The Node
        node.addChildNode(boxNode)
    
    
    }
    

    根据我的理解(我当然可以错)你会知道你的放置区域是referenceImage.physicalSize的宽度和高度,以米表示:

    let width = currentImageAnchor.referenceImage.physicalSize.width
    let height = currentImageAnchor.referenceImage.physicalSize.height
    

    因此,您需要在这些边界内缩放您的内容(如果需要适合),假设您希望它看起来覆盖图像。

    【讨论】:

    • 你回答的这一部分做了一切:".. 以米表示"。实际上,我将图像大小设置为米而不是厘米,这就是我的矩阵如此之大的原因。图像被检测为 14 米高(而不是 14 厘米),因此距离很远。谢谢!
    猜你喜欢
    • 2012-02-07
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多