欢迎回到我们的AR系列。上一章介绍了整个项目。本章将介绍列表中的第一个主题:平面检测和跟踪。在本文的末尾,您将能够以正确的顺序从输入图像中识别 A4 纸张的角点,以便可以在那里绘制矩形轮廓。本章的示例结果如下图所示。
完整的实施可在随附的项目中提供。你可以通过原始文章下载它。本文的主要类是 WhiteMarkerTracker
。我鼓励您在阅读本文时查看源代码。现在,让我们进入它。
预处理
预处理是图像处理的第一阶段。预处理的目标是清理图像,并仅提取在后续阶段可用的信息。因为在许多情况下,此阶段必须经过图像的每个像素,因此只能执行相对简单的操作。结果是一个”功能”列表(您将在一点一点中看到这个单词的含义)对于更详细的处理很有用。很多时候,最好有比像素数量少得多的要素。
在我们的例子中,目标是识别白色矩形。好的开始方法是识别位于白色区域边缘的像素。该像素是此特定上下文中的”功能”。它们可以通过以下过程提取。
- 阈值像素按颜色(白色必须具有足够高的红色、绿色和蓝色分量)。
- 标识所有连接的区域(blob)。
- 拾取最大的斑点(假设标记纸是图像中占主导地位的白色对象),然后扔掉所有其他斑点。这将清除某些工件。
- 如果最大的 blob 没有足够的卷(表示像素数),则退出。
- 识别 blob 的轮廓点。这些是黑色像素旁边的白色像素。
结果是一组等值点,如下图所示。为了给您粗略的数字,输入图像有 640×480 像素,总共略高于 300,000 像素。预处理选择在给定合理输入的情况下小于 3,000 像素。这会将数据量减少 1,000 倍。
让我再补充一点。根据获取输入图像的方式,您可能需要应用其他操作(如高斯平滑)以获得合理的轮廓。我使用了视频序列中的图像,压缩算法已经做了类似的工作。因此,就我而言,这是没有必要的。
选择等高线像素后,下一阶段即可开始。
检测
现在,您有一组等值像素。那么,如何处理它们呢?虽然你可以看到他们大多形成标记纸的边缘,仍然有一些错误。此外,它们只是像素,不能告诉角点的位置如下图所示。
检测算法首先识别四条边缘线,然后从交点计算拐角位置。请注意,算法在途中有几个点无法检测到某些内容。在这种情况下,它报告说,没有检测到任何东西。
边缘线
识别边缘线的好方法是 RANSAC(随机样本共识),而其中存在错误和异常值。遵循一般 RANSAC 工作流。
- 重复 N 次(N 由您决定)
- 随机选择构建模型所需的最小点数
- 从所选点生成模型
- 将模型与其他采样点进行比较,并计算良好拟合数(内距或足够接近预期位置的点)
- 如果内向数足够高,则接受模型并终止循环
- 您要么有一个模型,要么很可能该模型不存在
现在,它更具体的边缘标记纸。主要区别是,我们希望找到四条线,尽可能多地躺在轮廓点上。为此,有必要选择我们愿意采取的最大迭代次数 (N),最小点数”足够接近”线以接受 minAccept
线(* 好是使用样本点总数的百分比),以及与被视为”足够近”( ) 的直线的距离。 dstThres
完整的算法是在 Fitting
类, linesRansac
方法。这里只是一个简短的描述。
- 从空结果列表开始
- 重复最大 N 次,如果结果列表需要多行(本例中为 4 行),请停止
- 从样本集中选取两个不同的随机点
- 构建线
- 计算内列数(与直线的最大距离
dstThres
为) - 如果 inlier 的数量大于或等于
minAccept
参数,则- 将行添加到结果列表
- 从样本集中移除等值器(以防止再次检测到同一行)
- 返回结果列表
如果运行此算法,则您将”理想”(我将回到本章后面的单词”理想”)结尾有此图像中的行。
你看,RANSAC是容忍各种形式的分心。您只需有足够的采样点数量才能”足够接近”。现在,一旦边缘线被知道,最终的形状就可以被提取。
纸张形状
从边到角点是识别哪些线是垂直的,计算交点并逆时针排序。完全实现是在 WhiteMarkerTracker
类、方法 extractPoints
中。
通过角度检查可以识别垂直线,因为我们知道矩形有两组两条平行线。如果选择任何边线,则平行线之间始终具有最小角度。两条垂直线是剩余的线,不是平行线。线之间的角度可以从线方程中计算。对于交叉点也是如此。点的顺序只需要使用一点点的矢量代数和乱搞
那么,我们完成了吗?不是那么快…
RANSAC 问题
记得在我提到”理想”这个词之前吗?这部分是关于这一点。
让我们做个小实验吧。让我们从本章中举出示例图像,并从中制作一个 200 帧的视频。在每个帧中,让我们执行到目前为止描述的平面检测,并通过估计 AR 参数并在平面顶部绘制 3D 立方体进行后续操作(如果您还不知道如何执行此操作,请不要担心)。这就是结果:
立方体在晃动,尽管它应该保持静止。此外,有几个帧是完全错误的。这是由 RANSAC 方法的性质引起的。RANSAC 是一种概率方法,它随机选择点来创建模型。这有两个后果。
- 每个估计都略有不同,尽管大多数都相当好。这就是摇晃的原因。特别是因为错误是总结的方式。
- 有一个小的机会,一些模型是错误的,但仍然适合足够的点被接受。这是几个帧完全错误的原因。
为了更说明一下,让我们看看当前线路检测的外观。
在此图像中,您可以清楚地看到,同一行的两个 RANSAC 检测可能都相当好,但略有不同。这是上一视频中抖动立方体的根本原因。此外,随着时间的推移,您可以看到检测错误导致检测到两次单边。这是多维数据集呈现在错误位置的根本原因。
如何改进?
稳定与跟踪
虽然简单的RANSAC方法不够好,无法产生好的结果,但它仍然是一个合理的开始。因此,让我们使用初始检测并增强它。
有两个增强功能(两者都在 WhiteMarkerTracker
类、方法 )内 trackMarker
实现。
- 跟踪以前检测到的形状
- 通过平均平滑估计
首先,让我们讨论跟踪。逐帧跟踪完成。在每个帧中,算法知道旧对象的参数(本例中为四个角点)和新观测值(本例中为轮廓点)。结果是更新的参数集或报告对象已丢失。
此实现的工作原理是逐个跟踪边,然后将它们放在一起。假设边在两个帧之间移动不会显著变化。角点用于定义一个区域,其中的边缘应为。这减少了等值点的数量,因此,允许我们为 RANSAC 估计要求更高的等值百分比。如下图所示。
现在关于平滑。平滑通常通过平均来实现。因此,对于每条跟踪的行,让 RANSAC 估计 M 适合该行,而不仅仅是一条。然后采取一组点,其中每个足够接近至少一个这些良好的适合
当您将所有内容放在一起时,结果将类似于此视频。
总结
本章解释了如何在视频中跟踪 A4 标记纸。下一章将使用结果来建立同源。敬请期待!