使用ARKit的图像识别功能,可以两次或更多次检测同一幅图像吗?

时间:2018-12-11 11:10:33

标签: swift arkit

我正在尝试构建一个应用程序,该应用程序可以检测两次或更多次相同的图像,并将这些检测到的图像添加到数组中,以便稍后对其进行处理。

我将我的图像和尺寸添加到Assets.xassets的AR Resources文件夹中。图像被识别,效果很好。但是,当我想扫描同一张图像两次时,它只能识别一张图像。

我在互联网上找不到有关此问题的任何特定文档。我还怀疑ARKit无法实现这一点,我可能需要使用机器学习模型。

如果任何人遇到此问题,并且有没有CoreML和Vision的解决方案,将不胜感激。否则,我将尝试使其与视觉和CoreML一起使用。

下面是用于识别图像并在其上方投放透明平面的代码。

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let imageAnchor = anchor as? ARImageAnchor else { return }
    let referenceImage = imageAnchor.referenceImage
    let imageName = referenceImage.name ?? "no name"

    print("Image Anchor: ", imageAnchor)

    let plane = SCNPlane(width: referenceImage.physicalSize.width, height: referenceImage.physicalSize.height)
    let planeNode = SCNNode(geometry: plane)
    planeNode.opacity = 0.20
    planeNode.eulerAngles.x = -.pi / 2
    node.addChildNode(planeNode)

    detectedImages.append(imageAnchor)

    DispatchQueue.main.async {
        self.label.text = "Image detected: \"\(imageName)\""
    }
}

2 个答案:

答案 0 :(得分:0)

您发布的代码无法识别任何内容,当ARKit已经为锚添加默认节点时调用该代码,该默认节点是为可识别图像添加的,实际上仅发生一次。为了避免这种限制,请遵循手册-

  

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

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

答案 1 :(得分:0)

是的,有可能。 您需要添加一个额外的变量来存储先前检测到的图像,然后将其与当前图像进行比较。 如果它们不匹配,它将用新图像替换先前检测到的图像信息。这样,如果您有一个以上的图像,则可以继续查看另一个图像,并且始终显示内容。

 last detected Image storage
    var lastImageAnchor: ARAnchor!

    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)
        }
        let referenceImage = imageAnchor.referenceImage
        let imageName = referenceImage.name ?? "no name"

        ... (insert the rest of your code here)...

        }
        self.lastImageAnchor = imageAnchor
    }

这应该有效。