![]() |
OpenCV 4.12.0
开源计算机视觉
|
上一教程: 使用 ArUco 和 ChArUco 进行标定
这是对想要使用 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 调整)。
使用标记板,您可以从一组标记中获取相机位姿,而不是从单个标记中获取。 这样,检测就能够处理对板的部分视角的遮挡,因为只需要一个标记即可获得位姿。
此外,在大多数情况下,您使用更多的角点进行位姿估计,因此它将比使用单个标记更准确。
主要的缺点是板不如单个标记那样通用。
ChArUco 板将棋盘与 ArUco 板结合在一起。 因此,ChArUco 板提供的角点比 ArUco 板(或单个标记)提供的角点更准确。
主要的缺点是 ChArUco 板不如 ArUco 板那样通用。 例如,ChArUco 板是一个平面板,具有特定的标记布局,而 ArUco 板可以具有任何布局,甚至可以是 3D 布局。 此外,ChArUco 板中的标记通常更小,更难以检测。
不。ChArUco 板的主要目标是为位姿估计或相机标定提供高精度的角点。
不,ArUco 板中的标记角点可以放置在其 3D 坐标系中的任何位置。
是的,ChArUco 板中的所有标记都需要在同一平面上,并且它们的布局由棋盘形状固定。
cv::aruco::Board 对象和 cv::aruco::GridBoard 对象之间有什么区别?cv::aruco::GridBoard 类是一种特定的板类型,它继承自 cv::aruco::Board 类。 cv::aruco::GridBoard 对象是一个板,其标记放置在同一平面上并且以网格布局排列。
Diamond 标记与 3x3 方格的 ChArUco 板非常相似。 但是,与 ChArUco 板相反,Diamond 标记的检测基于标记的相对位置。 当您想要为 Diamond 标记中的任何(或所有)标记提供概念意义时,它们非常有用。 一个示例是使用其中一个标记来提供 Diamond 标记的比例。
是的,单个标记的检测是 aruco 模块中的基本工具。 它使用 cv::aruco::DetectorParameters::detectMarkers() 函数完成。 其余功能接收来自此函数的检测到的标记列表。
是的,aruco 模块提供了使用 ArUco 板和 ChArUco 板标定相机的功能。
强烈建议使用 ChArUco 板进行标定,因为它具有很高的精度。
一般来说,使用预定义的字典更容易。 但是,如果您需要更大的字典(就标记数量或位数而言),您应该生成自己的字典。 如果您想最大化标记间的距离,以在识别步骤中实现更好的纠错,那么生成字典也很有用。
字典生成应该只在应用程序开始时执行一次,并且应该花费几秒钟的时间。 如果您在检测循环的每次迭代中都生成字典,那么您就做错了。
此外,建议使用 cv::aruco::Dictionary::writeDictionary() 将字典保存到文件中,并使用 cv::aruco::Dictionary::readDictionary() 在每次执行时读取字典,这样您就不需要生成它。
是的,预定义的字典之一是 cv::aruco::DICT_ARUCO_ORIGINAL,它以相同的标识符检测原始 ArUco 库的标记。
不能直接使用,您需要将 ArUco 文件的信息适配到 aruco 模块的板格式。
可能可以,但是您需要将原始库的字典移植到 aruco 模块格式。
如果您使用的是预定义的字典之一,则不需要。 否则,建议您将其保存到文件中。
如果您使用的是 cv::aruco::GridBoard 或 cv::aruco::CharucoBoard,您只需要存储提供给 cv::aruco::GridBoard::GridBoard() 构造函数或 cv::aruco::CharucoBoard 构造函数的板测量值。 如果您手动修改板的标记 ID,或者如果您使用不同类型的板,您应该将您的板对象保存到文件中。
您可以使用 cv::aruco::Dictionary::writeDictionary() 和 cv::aruco::Dictionary::readDictionary() 处理 cv::aruco::Dictionary。 板类的数据成员是公共的,可以轻松存储。
为此,您需要使用外部渲染引擎库,例如 OpenGL。 aruco 模块仅提供获取相机位姿的功能,即旋转和平移向量,这对于创建增强现实效果是必需的。 但是,您需要将旋转和平移向量从 OpenCV 格式调整为您 3D 渲染库接受的格式。 原始 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/Diamonds 板)并使用 cv::SOLVEPNP_IPPE_SQUARE 选项使用 solvePnP() 进行位姿估计。 更多信息请参见此问题。