如何在AR中检测多个图像?

时间:2019-04-23 03:01:05

标签: ios swift augmented-reality arkit

我正在使用ARKit创建此实时报纸应用程序,该应用程序可以将报纸上的图像转换为视频。我能够检测到一张图像并在其上播放视频,但是当我尝试对两张图像进行处理并在该图像上播放相应的视频时我收到类似的错误     Attempted to add a SKNode which already has a parent

我尝试通过检查跟踪的图像并将它们与参考图像进行比较,但是我认为我的逻辑有问题。

这是我的ViewDidAppear()方法

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Create a session configuration
    let configuration = ARImageTrackingConfiguration()

    if  let trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "NewsPaperImages", bundle: Bundle.main) {

        configuration.trackingImages = trackedImages
        configuration.maximumNumberOfTrackedImages = 20



    }

    // Run the view's session
    sceneView.session.run(configuration)
}

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    let node = SCNNode()

    if let imageAnchor = anchor as? ARImageAnchor {

        if(imageAnchor.referenceImage == UIImage(named: "Image2_River")) {
            self.videoNode = SKVideoNode(fileNamed: "riverBeauty.mp4")
        }

        print("Yes it is an image")
        self.videoNode.play()

        let videoScene = SKScene(size: CGSize(width: 480, height: 360))

        videoNode.position = CGPoint(x: videoScene.size.width/2, y: videoScene.size.height/2)
        videoNode.yScale = -1.0
        videoScene.addChild(videoNode)

        let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width, height: imageAnchor.referenceImage.physicalSize.height)


        plane.firstMaterial?.diffuse.contents = videoScene

        let planeNode = SCNNode(geometry: plane)
        planeNode.eulerAngles.x = -.pi/2

        node.addChildNode(planeNode)

        }
    return node

}

它应该在每个检测到的图像上播放视频,但是它崩溃了。

1 个答案:

答案 0 :(得分:0)

看看您的代码,从您所说的来看,我认为您需要更改逻辑,而是使用name的{​​{1}}属性创建视频节点。

静态(在ARReferenceImage内)或动态创建ARReferenceImage时,您可以为其指定一个名称,例如:

enter image description here

然后,您可以使用名称添加逻辑,以便为检测到的每个ARResourceBundle分配不同的视频。

为了保留代码referenceImage,您可以创建一个可重用的函数来创建视频节点。

如此简单的示例可能看起来像这样:

DRY

您可以看到,我选择使用 //------------------------- //MARK: - ARSCNViewDelegate //------------------------- extension ViewController: ARSCNViewDelegate{ func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { //1. Check We Have Detected An ARImageAnchor guard let validAnchor = anchor as? ARImageAnchor else { return } //2. Create A Video Player Node For Each Detected Target node.addChildNode(createdVideoPlayerNodeFor(validAnchor.referenceImage)) } /// Creates An SCNNode With An AVPlayer Rendered Onto An SCNPlane /// /// - Parameter target: ARReferenceImage /// - Returns: SCNNode func createdVideoPlayerNodeFor(_ target: ARReferenceImage) -> SCNNode{ //1. Create An SCNNode To Hold Our VideoPlayer let videoPlayerNode = SCNNode() //2. Create An SCNPlane & An AVPlayer let videoPlayerGeometry = SCNPlane(width: target.physicalSize.width, height: target.physicalSize.height) var videoPlayer = AVPlayer() //3. If We Have A Valid Name & A Valid Video URL The Instanciate The AVPlayer if let targetName = target.name, let validURL = Bundle.main.url(forResource: targetName, withExtension: "mp4", subdirectory: "/art.scnassets") { videoPlayer = AVPlayer(url: validURL) videoPlayer.play() } //4. Assign The AVPlayer & The Geometry To The Video Player videoPlayerGeometry.firstMaterial?.diffuse.contents = videoPlayer videoPlayerNode.geometry = videoPlayerGeometry //5. Rotate It videoPlayerNode.eulerAngles.x = -.pi / 2 return videoPlayerNode } } 作为我的视频内容,尽管您可以根据需要继续使用videoScene。

希望它会为您指明正确的方向...