重新检测到ARKit图像

时间:2018-08-01 14:46:46

标签: ios swift arkit ios12

我目前正在使用ARKit 2.0(测试版)来进行一些图像识别,而我正在努力解决一件事。 当我检测到图像时,会在其旁边放置一个对象(无论是哪个对象,它只是一个节点,其中包含基于所找到图像的材质)。

我的问题是:当重新找到找到的图像时(是否该节点也与imageanchor关联),是否会触发ARKit函数?我正在寻找正确的信息,但没有找到任何好的方法

5 个答案:

答案 0 :(得分:4)

在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)
    }
}

答案 1 :(得分:1)

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

当图像隐藏并“重新出现”在屏幕上时,我猜应该调用 renderer(renderer:didUpdate节点:用于锚点:)

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

编辑:

我是通过纸牌游戏做到的。 您有一个带有名称的ARReferenceImage存储。 当您呈现目标时,renderer(_ renderer:SCNSceneRenderer,nodeFor锚点: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)
}
}

答案 2 :(得分:1)

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

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

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

  

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

我还要指出,ARkit中有两个不同的ARConfiguration子类可以进行图像检测:

ARWorldTrackingConfiguration: https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration

ARImageTrackingConfiguration: https://developer.apple.com/documentation/arkit/arimagetrackingconfiguration

我不知道这是否对您有帮助,但我只是想为以后的读者指出这一点。

我们所有人都通过分享我们所学的知识来学习

智能狗

答案 3 :(得分:1)

尝试在{ "schema": "https://developer.microsoft.com/json-schemas/sp/view-formatting.schema.json", "hideSelection": "true", "hideColumnHeader": "true", "rowFormatter": { "elmType": "a", "attributes": { "href": "[$FileRef]", "target": "'_blank'" }, "style": { "float": "left" }, "children": [ { "elmType": "div", "attributes": { "class": "ms-bgColor-themeLighterAlt ms-bgColor-themePrimary--hover ms-fontColor-white--hover" }, "style": { "display": "flex", "flex-wrap": "wrap", "min-width": "180px", "min-height": "150px", "margin-right": "10px", "margin-top": "10px", "box-shadow": "2px 2px 4px darkgrey" }, "children": [ { "elmType": "div", "style": { "text-align": "center", "margin": "auto" }, "children": [ { "elmType": "div", "attributes": { "class": "sp-row-title " }, "txtContent": "[$Title]" }, { "elmType": "div", "attributes": { "iconName": "Test", "class": "ms-fontSize-su" } } ] } ] } ] } } 的末尾使用self.session.remove(anchor: imageAnchor)func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)之后,将调用函数。这个答案并不完美,但是您可以使用它来使其更适合您。

我的解决方案:

在我的应用中,我确实喜欢这样。已创建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

答案 4 :(得分:0)

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

//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
}

希望这会有所帮助;)