ARKit - Projection of ARAnchor to 2D space

大城市里の小女人 提交于 2019-11-30 15:15:21

I found a solution to get corner 3D points of an ARImageAnchor depending on the anchor.transform and project them to 2D space:

extension simd_float4 { 
    var vector_float3: vector_float3 { return simd_float3([x, y, z]) } 
}

    /// Returns the projection of an `ARImageAnchor` from the 3D world space
    /// detected by ARKit into the 2D space of a view rendering the scene.
    ///
    /// - Parameter from: An Anchor instance for projecting.
    /// - Returns: An optional `CGRect` corresponding on `ARImageAnchor` projection.
    internal func projection(from anchor: ARImageAnchor) -> CGRect? {
        guard let camera = session.currentFrame?.camera else {
            return nil
        }

        let refImg = anchor.referenceImage
        let transform = anchor.transform.transpose


        let size = view.bounds.size
        let width = Float(refImg.physicalSize.width / 2)
        let height = Float(refImg.physicalSize.height / 2)

        // Get corner 3D points
        let pointsWorldSpace = [
            matrix_multiply(simd_float4([width, 0, -height, 1]), transform).vector_float3, // top right
            matrix_multiply(simd_float4([width, 0, height, 1]), transform).vector_float3, // bottom right
            matrix_multiply(simd_float4([-width, 0, -height, 1]), transform).vector_float3, // bottom left
            matrix_multiply(simd_float4([-width, 0, height, 1]), transform).vector_float3 // top left
        ]

        // Project 3D point to 2D space
        let pointsViewportSpace = pointsWorldSpace.map { (point) -> CGPoint in
            return camera.projectPoint(point,
                                orientation: .portrait,
                                viewportSize: size)
        }

        // Create a rectangle shape of the projection
        // to calculate the Intersection Over Union of other `ARImageAnchor`
        let result = CGRect(origin: pointsViewportSpace[3],
                            size: CGSize(width: pointsViewportSpace[0].distance(point: pointsViewportSpace[3]),
                                         height: pointsViewportSpace[1].distance(point: pointsViewportSpace[2])))


        return result
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!