Skip to content

ArUco 模块常见问题

这是一份问题汇编,对那些想要使用 aruco 模块的人可能很有用。

  • 我只想给一些物体打标签,应该用什么?

在这种情况下,你只需要单个 ArUco 标记。你可以在每个想要识别的物体上放置一个或多个具有不同 id 的标记。

  • 标记检测使用的是什么算法?

aruco 模块基于原始的 ArUco 库。检测过程的完整描述可以在以下文献中找到:

S. Garrido-Jurado, R. Muñoz-Salinas, F. J. Madrid-Cuevas, and M. J. Marín-Jiménez. 2014. “Automatic generation and detection of highly reliable fiducial markers under occlusion”. Pattern Recogn. 47, 6 (June 2014), 2280-2292. DOI=10.1016/j.patcog.2014.01.005

  • 我的标记没有被正确检测,我该怎么办?

可能有许多因素阻碍标记的正确检测。你可能需要调整 cv::aruco::DetectorParameters 对象中的某些参数。你可以做的第一件事是检查你的标记是否被 cv::aruco::ArucoDetector::detectMarkers() 函数作为被拒绝的候选项返回。根据这一点,你应该尝试修改不同的参数。

如果你使用的是 ArUco 标定板,你还可以尝试 cv::aruco::ArucoDetector::refineDetectedMarkers() 函数。如果你使用大标记(400x400 像素及以上),请尝试增大 cv::aruco::DetectorParameters::adaptiveThreshWinSizeMax 的值。此外,还要避免在 ArUco 标记周围有狭窄的边框(占标记周长的 5% 或更少,由 cv::aruco::DetectorParameters::minMarkerDistanceRate 调整)。

  • ArUco 标定板有什么好处?有什么缺点?

使用标记标定板,你可以从一组标记而不是单个标记获取相机位姿。这样,检测就能处理标定板局部视图的遮挡,因为只需一个标记即可获得位姿。

此外,由于在大多数情况下你使用了更多的角点进行位姿估计,它将比使用单个标记更精确。

主要缺点是标定板不如单个标记通用。

  • ChArUco 标定板相对于 ArUco 标定板有什么好处?有什么缺点?

ChArUco 标定板将棋盘与 ArUco 标定板结合在一起。得益于此,ChArUco 标定板提供的角点比 ArUco 标定板(或单个标记)提供的角点更精确。

主要缺点是 ChArUco 标定板不如 ArUco 标定板通用。例如,ChArUco 标定板是具有特定标记布局的平面标定板,而 ArUco 标定板可以有任何布局,甚至是三维的。此外,ChArUco 标定板中的标记通常更小、更难检测。

  • 我不需要位姿估计,应该使用 ChArUco 标定板吗?

不需要。ChArUco 标定板的主要目标是为位姿估计或相机标定提供高精度的角点。

  • ArUco 标定板中的所有标记都需要放置在同一平面上吗?

不需要,ArUco 标定板中的标记角点可以放置在其三维坐标系中的任何位置。

  • ChArUco 标定板中的所有标记都需要放置在同一平面上吗?

是的,ChArUco 标定板中的所有标记都需要在同一平面上,并且它们的布局由棋盘形状固定。

  • cv::aruco::Board 对象和 cv::aruco::GridBoard 对象之间有什么区别?

cv::aruco::GridBoard 类是继承自 cv::aruco::Board 类的一种特定类型的标定板。cv::aruco::GridBoard 对象是其标记放置在同一平面并呈网格布局的标定板。

  • 什么是菱形标记(Diamond markers)?

菱形标记非常类似于由 3x3 方格组成的 ChArUco 标定板。然而,与 ChArUco 标定板相反,菱形的检测基于标记的相对位置。 当你想为菱形中的任何(或所有)标记赋予某种概念含义时,它们很有用。例如,使用其中一个标记来提供菱形的尺度。

  • 在进行标定板检测、ChArUco 标定板检测或菱形检测之前,我需要先检测标记吗?

是的,单个标记的检测是 aruco 模块中的一个基本工具。它使用 cv::aruco::DetectorParameters::detectMarkers() 函数完成。其余功能都从该函数接收检测到的标记列表。

  • 我想标定我的相机,可以使用这个模块吗?

是的,aruco 模块提供了使用 ArUco 标定板和 ChArUco 标定板来标定相机的功能。

  • 我应该使用 ChArUco 标定板还是 ArUco 标定板进行标定?

强烈建议使用 ChArUco 标定板进行标定,因为其精度很高。

  • 我应该使用预定义字典还是生成自己的字典?

通常,使用预定义字典之一更容易。然而,如果你需要更大的字典(就标记数量或比特位数而言),你应该生成自己的字典。如果你想最大化标记间距离以在识别步骤中获得更好的错误纠正,字典生成也很有用。

  • 我正在生成自己的字典,但耗时太长。

字典生成应当只在应用开始时进行一次,并且应当花费几秒钟的时间。如果你在检测循环的每次迭代中都生成字典,那么你的做法是错误的。

此外,建议使用 cv::aruco::Dictionary::writeDictionary() 将字典保存到文件,并在每次执行时使用 cv::aruco::Dictionary::readDictionary() 读取它,这样你就不需要每次都生成它。

  • 我想使用一些我已经打印好的原始 ArUco 库的标记,可以使用它们吗?

可以,预定义字典之一是 cv::aruco::DICT_ARUCO_ORIGINAL,它会检测原始 ArUco 库的标记,并使用相同的标识符。

  • 我可以在该模块中使用原始 ArUco 库的标定板配置文件吗?

不能直接使用,你需要将 ArUco 文件中的信息适配为 aruco 模块的 Board 格式。

  • 我可以使用该模块检测其他基于二值基准标记的库的标记吗?

可能可以,但是你需要将原始库的字典移植为 aruco 模块格式。

  • 我需要将字典信息存储在文件中以便在不同执行中使用吗?

如果你使用的是预定义字典之一,则没有必要。否则,建议将其保存到文件。

  • 我需要将标定板信息存储在文件中以便在不同执行中使用吗?

如果你使用的是 cv::aruco::GridBoard 或 cv::aruco::CharucoBoard,你只需要存储提供给 cv::aruco::GridBoard::GridBoard() 构造函数或 cv::aruco::CharucoBoard 构造函数的标定板尺寸。如果你手动修改了标定板的标记 id,或者你使用了不同类型的标定板,则应当将你的标定板对象保存到文件。

  • aruco 模块是否提供将字典或标定板保存到文件的函数?

对于 cv::aruco::Dictionary,你可以使用 cv::aruco::Dictionary::writeDictionary() 和 cv::aruco::Dictionary::readDictionary()。标定板类的数据成员是公开的,可以轻松存储。

  • 好的,但是如何渲染三维模型来创建增强现实应用?

为此,你需要使用外部渲染引擎库,例如 OpenGL。aruco 模块只提供获取相机位姿的功能,即旋转和平移向量,这是创建增强现实效果所必需的。然而,你需要将旋转和平移向量从 OpenCV 格式适配为你的三维渲染库所接受的格式。原始 ArUco 库包含了针对 OpenGL 和 Ogre3D 如何执行此操作的示例。

  • 我在我的研究工作中使用了该模块,该如何引用它?

你可以引用原始的 ArUco 库:

S. Garrido-Jurado, R. Muñoz-Salinas, F. J. Madrid-Cuevas, and M. J. Marín-Jiménez. 2014. “Automatic generation and detection of highly reliable fiducial markers under occlusion”. Pattern Recogn. 47, 6 (June 2014), 2280-2292. DOI=10.1016/j.patcog.2014.01.005

  • 用于位姿估计的标记没有被正确检测,我该怎么办?

需要强调的是,仅使用 4 个共面点进行位姿估计会受到歧义的影响。通常,如果相机靠近标记,歧义可以解决。然而,随着标记变小,角点估计中的误差会增加,歧义就成了一个问题。尝试增大你所用标记的尺寸,你也可以尝试非对称(aruco_dict_utils.cpp)标记以避免冲突。使用多个标记(ArUco/ChArUco/菱形标定板),并使用 cv::SOLVEPNP_IPPE_SQUARE 选项进行 solvePnP() 位姿估计。更多信息见此 issue。