如何检测 ARKit 中的垂直平面?

How to detect vertical planes in ARKit?

如何实现垂直平面检测(即对于墙壁)?

let configuration = ARWorldTrackingSessionConfiguration()
configuration.planeDetection = .horizontal //TODO

编辑: 从 ARKit 1.5 (iOS 11.3) 开始支持。只需使用 .vertical。出于历史目的,我保留了之前的 post。


TL;DR

垂直平面检测(还)不是 ARKit 中存在的功能。 .horizontal 表明此功能可能正在开发中,并可能在将来添加。如果它只是一个布尔值,这表明它是最终的。

确认

我在 WWDC17 上与 Apple 工程师的谈话证实了我的怀疑。

说明

你可能会争辩说,为此创建一个实现会很困难,因为垂直平面的方向比水平平面多得多,但正如 rodamn 所说,这可能不是这样。

来自 rodamn 的 评论: 在最简单的情况下,一个平面被定义为三个共面点。一旦沿表面(垂直、水平或任意角度)检测到足够多的共面特征,您就有了一个候选表面。只是水平方向的法线将沿着 up/down 轴,而垂直方向的法线将平行于地平面。挑战在于,未经装饰的石膏板往往会产生很少的视觉特征,而素面墙可能常常未被发现。我强烈怀疑这就是 .vertical 功能尚未发布的原因。

但是,对此有相反的说法。有关详细信息,请参阅 rickster 的评论。

据说 Apple 正在为新 iPhone 开发额外的 AR 功能,即相机的额外传感器。当这些设备功能已知时,这可能会成为一项功能。这里有一些猜测。 http://uk.businessinsider.com/apple-iphone-8-rumors-3d-laser-camera-augmented-reality-2017-7 and another source https://www.fastcompany.com/40440342/apple-is-working-hard-on-an-iphone-8-rear-facing-3d-laser-for-ar-and-autofocus-source

由于 iPhone X 配备前置深度摄像头,我怀疑下一个版本会配备后置摄像头,并且 .vertical 功能可能会被委派到那时。

我是用 Unity 做的,但我需要做数学题。

我使用 Random Sample Consensus 从 ARkit returned 的点云中检测垂直平面。这就像有一个循环随机选择 3 个点来创建一个平面并计算匹配它的点数,然后看看哪个尝试是最好的。

它正在工作。但是因为当墙壁是素色时,ARkit 不能 return 很多点。所以它在很多情况下都不起作用。

iOS 11.3:

将支持此功能

static var vertical: ARWorldTrackingConfiguration.PlaneDetection

The session detects surfaces that are parallel to gravity (regardless of other orientation).

https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration.planedetection https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration.planedetection/2867271-vertical

Apple 已发布 iOS 11.3,其中包含 ARKit 1.5 等各种 AR 更新。在此更新中,ARKit 包括 ARKit 识别虚拟对象并将其放置在垂直表面(如墙壁和门)上的功能。

ARWorldTrackingConfiguration 现在支持垂直方向

let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = [.horizontal, .vertical]
sceneView.session.run(configuration)

In ARKit 1.0 there was just .horizontal enum's case for detecting horizontal surfaces like a table or a floor. In ARKit 1.5 and higher there are .horizontal and .vertical type properties of a PlaneDetection struct that conforms to OptionSet protocol.

要在 ARKit 2.0+ 中实现垂直平面检测,请使用以下代码:

configuration.planeDetection = .vertical

或者您可以对两种类型的检测平面使用值:

private func configureSceneView(_ sceneView: ARSCNView) {

    let configuration = ARWorldTrackingConfiguration()
    configuration.planeDetection = [.horizontal, .vertical]    //BOTH TYPES
    configuration.isLightEstimationEnabled = true
    sceneView.session.run(configuration)
}

您还可以添加 class 的扩展来处理委托调用:

extension ARSceneManager: ARSCNViewDelegate {

    func renderer(_ renderer: SCNSceneRenderer, 
                 didAdd node: SCNNode, 
                  for anchor: ARAnchor) {

        guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
        print("Found plane: \(planeAnchor)")
    }
}