使用ARKit获取房间计划(大小很重要的情况)

故事作者:nomtek的iOS开发人员Przemek Olszacki

两年前,我写了一篇有关“用iPhone扫描房间”的文章,您可以在这里阅读。 我尝试使用三个内置传感器(加速度计,陀螺仪和磁力计)来测量墙壁的长度并绘制房间的平面图。 我处理了从这些传感器接收到的原始数据,并根据将加速度转换为距离的自写代码计算了墙之间的距离。 结果令人鼓舞,表明可以实现,但需要更高级的计算(或更精确的传感器)才能获得所需的精度。

回去工作!

自从我看到ARKit的发布以来,我一直在等待机会尝试一下。 这是两年前返回原型的好机会。 从公告和WWDC谈话中,ARKit看起来很有希望:它的准确性,实时渲染性能和易于实现。 现在该进行测试了。

返回测量室的另一个原因是运动传感器本身已更新。 从iPhone 5S开始,使用单独的协处理器收集和处理传感器数据。 自2013年以来,每年都会更新该芯片,并在iPhone 8、8 Plus和X上推出最新的M11。从理论上讲,这三款设备的结果应该是最准确的。

科学的力量!

在衡量最重要的帮助时,我们从ARKit获得的就是设备在太空中的放置。 使用相机图像和运动传感器,它可以确定手机的位置,方向以及与某些物体和表面的距离。

无需复杂且容易出错的代码即可根据传感器提供的原始数据来计算设备的运动。 苹果为我们完成了所有这一切。 唯一困难的部分是我们如何使用它。 我尝试了几种方法来找到最准确的一种。 让我引导您完成我的过程。

你在看什么?

在我的第一次尝试中,我只是尝试重新构建两年前的应用程序-通过在手机接触墙壁时获得其位置来测量墙壁之间的距离。 不同之处在于,我不是使用自写代码来计算距离,而是使用ARKit中的数据。 简而言之,它没有用。 ARKit使用相机图像来帮助确定手机在太空中的位置,并且当手机接触墙壁时,相机会被遮挡。 如果没有相机,数据将无法可靠使用。

需要进一步实验

下一个方法基于另一个ARKit组件-通过相交最近的特征点进行命中测试。 ARKit能够通过检测相机图像中的显着特征来找到物体的表面和轮廓。

从理论上讲,将击中测试与启用的检测特征点一起使用可以允许测量从手机到相机所指向的对象的距离。 用户将站在房间的中央,并将手机的摄像头对准墙壁。 来自ARKit的数据将用于确定3D空间中的墙位置。 设备的方向将用于获取墙的方向。

不幸的是,它不适用于墙壁,因为大多数墙壁没有明显的特征并且是单色的单色表面。

下一个。

要解决以前方法中的问题,必须更改测量点。 至少要考虑两个选项。

首先是打印可以被应用识别并用作功能点的特定图案。 例如,必须将打印内容粘贴在墙上,以便应用程序能够识别出来,而不是尝试在图像中查找平整的墙。 它可能会起作用,但对用户而言将非常不便,因此未实现该想法。

第二种选择是使用ARKit提供的其他类型的点击测试。 它基于对水平面的检测。 初始化AR世界追踪时,我们可以启用水平面检测。 启用此选项后,ARKit会不断寻找可用作跟踪锚点的水平面。 好了,所以我们可以检测到水平面,但是与找到显然是垂直表面的墙又有什么关系呢?

好吧,由于我们不需要墙的高度,因此可以通过在与墙连接的地方对地板进行碰撞测试来测量其位置。

与采用特征点的方法一样,墙壁的方向由手机的方向确定。 这次,距离精度令人满意,在良好的照明条件下,我们可以获得单个墙壁位置的可用测量值。 测量多个墙壁以绘制房间平面图时会出现问题。 检测到的墙壁方向取决于用户将手机与墙壁平行放置。 在所有测量中,墙壁和电话之间几乎都不会保持相同的角度,这会导致墙壁的长度和房间形状的准确性降低。

需要第二意见?

最终迭代在前一个迭代的基础上有所改进。 这次,为了解决角度问题,该应用程序一次在两个地方对地板和墙壁之间的连接进行了碰撞测试。 当我们有两个点时,我们不需要获取手机的方向,因为我们可以画出穿过这两个点的代表墙壁的线。 实际上,要确定平面,我们需要三个点,但是在这种情况下,我们假定墙始终垂直于地板。

测量两次,切一次

所有测量准备就绪后,就该制定计划了。 在此步骤中,我们必须弄清楚如何使用每堵墙两个3D点来绘制房间平面图。

首先,通过删除不需要的高度值,将3D点转换为2D。 然后,对于每对点,我们定义一条代表无限墙的线。

当我们具有无限线时,我们可以确定代表房间角落的那些线之间的交点。

画完所有线后,我们得到了房间计划。 不幸的是,即使每面墙有两个测量点,墙之间的角度仍然不准确。 这些不准确性会影响相交点,从而导致长度相同的墙体不同。 为了改善结果,我添加了另一个在绘图之前执行的步骤-圆角。 在不同的房间测试应用程序后,将角度舍入到10度可获得最佳结果。

不断追求进步

为了确定测量的准确性,我在多个房间和光照条件下对其进行了测试。

呈现的结果基于将手动测量的壁长与使用该应用收到的结果进行比较。 我们可以看到,精度为3–20厘米(1–8英寸),平均为8.5厘米(3.3英寸)。 绝对是两年前该应用程序准确性的改进,
20–40厘米(8–16英寸)。 值得注意的是,大多数测量结果的误差都在10厘米(4英寸)以下。

厨房的测量精度最低。 原因是由于橱柜的原因,厨房墙壁在地板上不直接可见。 在这种情况下,在测量期间,我不得不猜测墙壁会在哪里接触地板。

还有很多事情要做

我创建的应用只是一个概念证明,可能不适用于某些房间形状,但是它可以作为更高级应用的基础。 有很多改进的空间,例如,更高级的角度计算,更易于使用的测量指示器。 我已经对获得的结果感到满意,并且期待ARKit的更新,使它更加可靠。