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。