以下内容由公众号:三次方AIRX(国内领先的AI、AR、VR技术学习与交流平台) 整理

在iOS 11.3或更高版本中,开发者可以通过在ARKit中启用图像识别功能。camera扫描识别图片,然后显示一些AR内容(比如3D物体、视频、图片、音频,跳转URL等),这是最基本也是最原始的AR功能。本部分教程通过一个小案例了解ARKit的2D Image Recognition特性。

前提:需要在9.3或更高版本上运行Xcode,并且在iOS 11.3或更高版本上测试。

在开始之前先下载基础工程(https://pan.baidu.com/s/1JnBBYytgCtoMj8y9jS8fPw  密码:rj8w),我们在此基础上进行开发(一些UI控件已经准备好)。

Step 1:启用图像识别功能

在Xcode打开刚刚下载的工程,效果如下图:

为了使用ARKit的Image Recognition功能,我们首先需要:

1.准备好被识别的图像

2.设置好image的物理size

点击Assets.xcassets,然后你会看到AR Resources,操作如下图:

也可以将自己的图像拖放到这个组中。但是要确保给图片命名。

接下来需要设置图片的物理size。ARKit需要知道现实世界的图像大小来确定图像到相机的距离。输入不正确的物理图像大小将导致ARImageAnchor与相机的距离错误。

需要记住的是每次添加要识别的新图像时,都要提供物理图像大小。例如,“Book”图像的物理尺寸如下:

这是在15.4英寸MacBook Pro显示屏上打开图像文件时的物理图像大小属性。

Step 2:图像属性

ARKit的图像识别能力可能会随着图像的性质而变化。在AR Resources组中的图像会看到“Book”图像有两个质量评估。当图像对比度高时,图像检测效果最好。如下图所示:

“Snow Mountain”和“Trees In The Dark”图片没有黄色警告。这意味着ARKit认为这些图像很容易识别。

Step 3:编写代码

打开ViewController.swift文件,将以下方法插入View Controller class:

func resetTrackingConfiguration() {
    guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else { return }
    let configuration = ARWorldTrackingConfiguration()
    configuration.detectionImages = referenceImages
    let options: ARSession.RunOptions = [.resetTracking, .removeExistingAnchors]
    sceneView.session.run(configuration, options: options)
    label.text = "Move camera around to detect images"
}

接下来,在viewWillAppear(_:)和resetButtonDidTouch(_:)方法中调用resetTrackingConfiguration()方法。

使用ARImageAnchor识别图像:现在我们要将一个透明的白色平面覆盖到检测到的图像上。白色平面反映了新检测到的参考图像的形状和大小,以及图像与设备摄像头的距离。

更新renderer(_:didAdd:for:) 方法:


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"
        
    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
    
    planeNode.runAction(imageHighlightAction)
}

现在我们已经有了平面节点和检测到的图像的名称,我们将把平面节点添加到节点参数中,并设置标签的文本来显示识别的图像的名称。在planeNode.runAction(imageHighlightAction)之后插入以下代码:


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

接下来我们先测试一些我们目前实现的功能,效果如下图:

Step 4:显示3D物体

首先注释掉下面的代码:


let planeNode = self.getPlaneNode(withReferenceImage: imageAnchor.referenceImage)
planeNode.opacity = 0.0
planeNode.eulerAngles.x = -.pi / 2
planeNode.runAction(self.fadeAction)

node.addChildNode(planeNode)

用以下代码替换TODO: Overlay 3D Object comment:

let overlayNode = self.getNode(withImageName: imageName)
overlayNode.opacity = 0
overlayNode.position.y = 0.2
overlayNode.runAction(self.fadeAndSpinAction)

node.addChildNode(overlayNode)

接下来测试运行效果如下图:

完整项目链接:

https://github.com/appcoda/ARKitImageRecognition

参考资料:

https://www.appcoda.com/arkit-image-recognition/

公众号[三次方AIRX]:三次方•数字化人才在线教育平台。帮助Z时代大学生和0-5年职场人获得混合现实、人工智能、游戏开发、大数据等能力。

更多推荐