OpenCV 4.11.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
对象是一个棋盘,其标记放置在同一个平面上并采用网格布局。
钻石标记非常类似于 3x3 方格的 ChArUco 棋盘。但是,与 ChArUco 棋盘相反,钻石的检测是基于标记的相对位置。当你想为钻石中的任何(或所有)标记提供概念意义时,它们很有用。一个例子是使用其中一个标记来提供钻石的比例。
是的,单个标记的检测是 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() 进行姿态估计。更多信息请参见此问题。