![]() |
OpenCV 4.11.0
开源计算机视觉
|
上一教程: ChArUco 棋盘格检测
下一教程: 使用 ArUco 和 ChArUco 进行标定
ChArUco 菱形标记(或简称为菱形标记)是一个由 3x3 个方格和 4 个 ArUco 标记组成的棋盘格。它在外观上类似于 ChArUco 棋盘格,但它们在概念上是不同的。
在 ChArUco 棋盘格和菱形标记中,它们的检测都基于先前检测到的 ArUco 标记。在 ChArUco 的情况下,使用的标记是通过直接查看它们的标识符来选择的。这意味着,如果在图像中找到一个标记(包含在棋盘格中),它将被自动认为属于该棋盘格。此外,如果在图像中多次找到一个标记棋盘格,则会产生歧义,因为系统无法知道应该使用哪个棋盘格。
另一方面,菱形标记的检测不是基于标识符。相反,它们的检测是基于标记的相对位置。因此,可以在同一个菱形标记或不同的菱形标记中重复使用标记标识符,并且可以同时检测它们而不会产生歧义。但是,由于基于其相对位置查找标记的复杂性,菱形标记的大小限制为 3x3 个方格和 4 个标记。
与单个 ArUco 标记一样,每个菱形标记都由 4 个角点和一个标识符组成。四个角点对应于标记中的 4 个棋盘格角点,标识符实际上是一个包含 4 个数字的数组,这些数字是菱形内四个 ArUco 标记的标识符。
菱形标记在允许重复标记的场景中非常有用。例如:
此外,由于它的角点是棋盘格角点,因此它们可以用于精确的位姿估计。
菱形标记功能包含在 `<opencv2/objdetect/charuco_detector.hpp>` 中
可以使用 `cv::aruco::CharucoBoard::generateImage()` 函数轻松创建菱形标记图像。例如:
这将创建一个方格大小为 200 像素,标记大小为 120 像素的菱形标记图像。标记 ID 以第二个参数的形式给出,作为一个 `cv::Vec4i` 对象。菱形布局中标记 ID 的顺序与标准 ChArUco 棋盘格中的顺序相同,即顶部、左侧、右侧和底部。
生成的图像将是:
完整的运行示例包含在 `samples/cpp/tutorial_code/objectDetection/` 文件夹内的 `create_diamond.cpp` 中。
示例 `create_diamond.cpp` 现在通过 `cv::CommandLineParser` 从命令行接收输入。对于此文件,示例参数如下所示:
在大多数情况下,菱形标记的检测需要先检测 ArUco 标记。检测到标记后,使用 `cv::aruco::CharucoDetector::detectDiamonds()` 函数检测菱形标记。
`cv::aruco::CharucoDetector::detectDiamonds()` 函数接收原始图像和先前检测到的标记角点和 ID。如果 markerCorners 和 markerIds 为空,则该函数将检测 ArUco 标记和 ID。输入图像对于在 ChArUco 角点执行亚像素细化是必要的。它还接收方格大小与标记大小之间的比率,这对于从标记的相对位置检测菱形标记和插值 ChArUco 角点都是必需的。
该函数在两个参数中返回检测到的菱形标记。第一个参数 `diamondCorners` 是一个数组,包含每个检测到的菱形标记的四个角点。其格式类似于 `cv::aruco::ArucoDetector::detectMarkers()` 函数检测到的角点,并且对于每个菱形标记,角点的顺序与 ArUco 标记中的顺序相同,即从左上角开始顺时针顺序。第二个返回参数 `diamondIds` 包含 `diamondCorners` 中返回的菱形标记角点的所有 ID。每个 ID 实际上是一个可以由 `cv::Vec4i` 表示的包含 4 个整数的数组。
可以使用 `cv::aruco::drawDetectedDiamonds()` 函数可视化检测到的菱形标记,该函数只需接收图像和菱形标记角点和 ID。
结果与 `cv::aruco::drawDetectedMarkers()` 生成的结果相同,但会打印菱形标记的四个 ID。
完整的运行示例包含在 `samples/cpp/tutorial_code/objectDetection/` 文件夹内的 `detect_diamonds.cpp` 中。
示例 `detect_diamonds.cpp` 现在通过 `cv::CommandLineParser` 从命令行接收输入。对于此文件,示例参数如下所示:
由于 ChArUco 菱形由其四个角点表示,因此其位姿的估计方法与单个 ArUco 标记相同,即使用cv::solvePnP() 函数。例如
该函数将获得每个菱形标记的旋转向量和平移向量,并将它们存储在rvecs 和 tvecs 中。请注意,菱形角点是棋盘格方块角点,因此必须提供正方形长度才能进行位姿估计,而不是标记长度。还需要相机校准参数。
最后,可以使用drawFrameAxes() 绘制坐标轴来检查估计的位姿是否正确。
菱形位姿的坐标系位于标记中心,Z 轴指向外,如同简单的 ArUco 标记位姿估计。
示例视频
ChArUco 菱形位姿也可以作为 ChArUco 棋盘进行估计
完整的运行示例包含在 `samples/cpp/tutorial_code/objectDetection/` 文件夹内的 `detect_diamonds.cpp` 中。
示例 `detect_diamonds.cpp` 现在通过 `cv::CommandLineParser` 从命令行接收输入。对于此文件,示例参数如下所示: