【问题标题】:ARKit image detected reappear检测到的 ARKit 图像再次出现
【发布时间】:2019-01-09 04:49:19
【问题描述】:

我目前正在使用 ARKit 2.0(测试版)进行一些图像识别,但我正在为一件事而苦苦挣扎。 当我检测到我的图像时,我会在它旁边放一个对象(不管是什么对象,它只是一个节点,其材质基于我找到的图像)。

我的问题是:当找到的图像重新出现时是否触发了 ARKit 函数(因此节点也与 imageanchor 相关联)?我正在搜索正确的知道,但我没有找到任何好东西

【问题讨论】:

    标签: ios swift arkit ios12


    【解决方案1】:

    当您为检测图像配置 ARKit 会话时,会在检测到图像并调用 renderer(renderer: nodeFor anchor:) 方法时将锚点添加到场景中。

    当图像被隐藏并“重新出现”在屏幕上时,我猜应该调用 renderer(renderer: didUpdate node: for anchor:)

    如果不是,那么它会再次调用 renderer(renderer: nodeFor anchor:) 方法,你可以插入一些简单的基于布尔的逻辑来检查它是否是第一次检测。

    编辑:

    我是用纸牌游戏做到的。 您有一个带有某个名称的 ARReferenceImage 存储。 当你呈现目标时,renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode?被调用。

    将其名称作为可选项存储在 foundImagesNames: [String] 中。

    然后将其从相机中删除,将其显示回来,再次调用它。 然后,您只需检查它是否已被检测到。

    if let imageAnchor = anchor as? ARImageAnchor,
       let name = imageAnchor.referenceImage.name {
    
    if self.foundImagesNames.contains(name) {
        //already presented
    }
    else {
        //first time presenting
        self.foundImagesNames.append(name)
    }
    }
    

    【讨论】:

    • 我目前正在使用 renderer(renderer: nodeFor anchor:) 方法,它只在会话第一次检测到图像时调用一次。我尝试使用渲染器(渲染器:didUpdate node:for anchor:) 但是这个被称为我认为找到我的图像时的每一帧,我找不到知道我的图像何时重新出现并再次消失的方法跨度>
    • 我完全明白你在做什么,我的问题是渲染器(_渲染器:SCNSceneRenderer,nodeFor anchor:ARAnchor)-> SCNNode?仅在我检测到新图像时调用,而不是在我显示检测到的图像时调用
    • 那我不知道:/当我测试它被调用了两次。您必须在那些渲染的(_:) 方法中放置断点以找到适合您需要的回调。您还可以在渲染器更新方法中实现自定义逻辑,以检测是否可以从相机中看到节点位置。
    【解决方案2】:

    我只是要把我的两分钱扔在这里。

    如果您查看 ARKit 文档 - 它说:

    https://developer.apple.com/documentation/arkit/recognizing_images_in_an_ar_experience

    考虑何时允许检测每个图像来触发(或重复) AR交互。 ARKit 将图像锚点添加到会话中恰好一次 对于会话配置中的每个参考图像 检测图像数组。如果您的 AR 体验将虚拟内容添加到 检测到图像时的场景,默认情况下该动作将 只发生一次。让用户再次体验该内容 无需重新启动您的应用程序,调用会话的 remove(anchor:) 方法 删除相应的 ARImageAnchor。锚定后 移除后,ARKit 将在下次检测到 图片。

    我还想指出,ARkit 中有两个不同的 ARConfiguration 子类允许图像检测:

    ARWorldTracking 配置: https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration

    ARImageTracking配置: https://developer.apple.com/documentation/arkit/arimagetrackingconfiguration

    我不知道这是否对你有帮助,但我只是想我会为这篇文章的未来读者指出这一点。

    我们都通过分享我们所知道的来学习

    智能狗

    【讨论】:

      【解决方案3】:

      尝试在func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) 的末尾使用self.session.remove(anchor: imageAnchor)。在func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) 函数之后将被调用。这个答案并不完美,但您可以使用它来使其适合您。

      我的解决方案:

      在我的应用程序中,我确实喜欢这样。创建var lastImageAnchor: ARAnchor!。在func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) 中添加了self.lastImageAnchor = imageAnchor。在这个函数之后:

      func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
              updateQueue.async {
                  if let imageAnchor = anchor as? ARImageAnchor {
                      guard let lastAnchor = self.lastImageAnchor else { return }
                      if imageAnchor != lastAnchor {
                          self.session.remove(anchor: lastAnchor)
                      }
                  }
              }
          }
      

      【讨论】:

        【解决方案4】:

        我从上面回答的内容和我已经拥有的内容中得到了一些指导,这对我有用:

        //add a variable to store the last image detected
        var lastImageAnchor: ARAnchor!
        
        //at every frame, detect image, compare with the last image stored, and show the node corresponding with the image
        func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
            guard let imageAnchor = anchor as? ARImageAnchor else { return }
            if self.lastImageAnchor != nil && self.lastImageAnchor != imageAnchor {
                self.sceneView.session.remove(anchor: self.lastImageAnchor)
            }
            //add whatever code you need to have your nodes appear
        
            //lastly change the lastImageAnchor to the one what you just detected
            self.lastImageAnchor = imageAnchor
        }
        

        希望这会有所帮助;)

        【讨论】:

          【解决方案5】:

          在 ARKit 3 中,我设法使用 renderer(_:didUpdate:for) 检测图像何时从视图中消失,并检查锚点的 isTracked 属性何时设置为 false

          func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
              if let imageAnchor = anchor as? ARImageAnchor, imageAnchor.isTracked == false {
                  view?.sceneView.session.remove(anchor: anchor)
              }
          }
          

          【讨论】:

          • 这应该是认可的答案
          猜你喜欢
          • 1970-01-01
          • 2019-10-10
          • 2018-07-30
          • 2018-11-27
          • 2020-10-05
          • 2020-03-10
          • 2019-05-12
          • 1970-01-01
          • 2020-09-21
          相关资源
          最近更新 更多