Skip to content

创建标定图案

本教程介绍了 OpenCV 支持的用于相机(单目或多目)标定和位姿估计的所有图案类型,以及它们各自的优势、缺陷和实用建议。

什么是标定图案?为什么需要它?

Section titled “什么是标定图案?为什么需要它?”

平面可打印图案可用于:

  1. 相机内参(内部参数)标定。参见相机标定教程。
  2. 双目或多相机系统的外参(外部参数:各相机的旋转与平移)标定。详见 cv::stereoCalibrate。
  3. 相机相对于三维世界中某个已知点的位姿配准。参见 OpenCV 5.x 中的多视图标定教程。

棋盘格(Chessboard)。经典的黑白方格标定图案。所有标定算法都使用棋盘格的内部角点作为特征。参见 cv::findChessboardCorners 和 cv::cornerSubPix,用于检测棋盘并以亚像素精度精化角点坐标。棋盘的大小定义为内部角点的数量,而不是黑色或白色方格的数量。还要注意,边长为偶数的棋盘是对称的:如果棋盘在某一方向上的角点数量为偶数,那么它的位姿有 180 度的歧义(2 个解);如果棋盘是 N x N 的正方形,那么它的位姿有 90 度的歧义(4 个解)。后两种情形不适合用于标定。

用于生成标定特征坐标(目标点)的示例代码:

std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < boardSize.height; ++i) {
for (int j = 0; j < boardSize.width; ++j) {
objectPoints.push_back(Point3f(j*squareSize, i*squareSize, 0));
}
}

可打印的棋盘格图案:pattern.png (9x6 棋盘格,页面宽 210 mm,页面高 297 mm(A4))

圆点网格(Circles Grid)。圆点网格是白色背景上的黑色圆点(或反之)构成的对称或不对称(每个偶数行有偏移)网格。使用 cv::findCirclesGrid 函数可用 OpenCV 检测该图案。检测器直接输出圆心的亚像素坐标,无需额外精化。网格大小定义为 x 与 y 轴方向上的圆点数量;对于不对称网格,偏移的行也要计入。该图案适用于内参标定。对称网格存在与偶数尺寸棋盘格相同的问题:其位姿有 180 度的歧义。

对称网格的标定特征坐标(目标点)生成示例代码:

std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < boardSize.height; ++i) {
for (int j = 0; j < boardSize.width; ++j) {
objectPoints.push_back(Point3f(j*squareSize, i*squareSize, 0));
}
}

不对称网格的标定特征坐标(目标点)生成示例代码:

std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < boardSize.height; i++) {
for (int j = 0; j < boardSize.width; j++) {
objectPoints.push_back(Point3f((2 * j + i % 2)*squareSize, i*squareSize, 0));
}
}

可打印的不对称圆点网格图案:acircles_pattern.png (11x4 不对称圆点网格,页面宽 210 mm,页面高 297 mm(A4))

ChArUco 板。嵌入了 ArUco 标记的棋盘格。棋盘的每个内部角点都由相邻的 2 个 ArUco 标记描述,因而具有唯一性。板的大小以单元格数量定义,而不是内部角点数量。N x M 大小的 ChArUco 板等效于 N-1 x M-1 大小的棋盘格图案。OpenCV 提供 cv::aruco::CharucoDetector 类用于检测该板。检测算法先找到 ArUco 标记,然后利用关于 ArUco 标记对的知识「组装」出整个板。与前面的图案不同,部分被遮挡的板也可以使用,因为所有角点都有标记。该板具有旋转不变性,但检测器必须预先知道 ArUco 标记的集合及其顺序;它无法检测尺寸已预定但标记集合随机的 ChArUco 板。

以单元格数量定义板大小时,生成标定特征坐标(目标点)的示例代码:

std::vector<cv::Point3f> objectPoints;
for (int i = 0; i < boardSize.height-1; ++i) {
for (int j = 0; j < boardSize.width-1; ++j) {
objectPoints.push_back(Point3f(j*squareSize, i*squareSize, 0));
}
}

可打印的 ChArUco 板图案:charuco_board_pattern.png (7X5 ChArUco 板,方格尺寸 30 mm,标记尺寸 15 mm,ArUco 字典:DICT_5X5_100,页面宽 210 mm,页面高 297 mm(A4))

如果现成的图案不能满足你的需求,你可以自己生成。OpenCV 在源码仓库(或你的二进制发行版)的 apps/pattern-tools 目录中提供了 generate_pattern.py 工具,唯一的要求是 Python 3。

示例:

在文件 chessboard.svg 中创建一个 9 行、6 列、方格尺寸 20 mm 的棋盘格图案:

Terminal window
python generate_pattern.py -o chessboard.svg --rows 9 --columns 6 --type checkerboard --square_size 20

在文件 circleboard.svg 中创建一个 7 行、5 列、半径 15 mm 的圆点板图案:

Terminal window
python generate_pattern.py -o circleboard.svg --rows 7 --columns 5 --type circles --square_size 15

在文件 acircleboard.svg 中创建一个 7 行、5 列、方格尺寸 10 mm、圆点间距更小的(不对称)圆点板图案:

Terminal window
python generate_pattern.py -o acircleboard.svg --rows 7 --columns 5 --type acircles --square_size 10 --radius_rate 2

为 findChessboardCornersSB() 创建一个 radon 棋盘格,标记位于 (7 4)、(7 5)、(8 5) 单元格:

Terminal window
python generate_pattern.py -o radon_checkerboard.svg --rows 10 --columns 15 --type radon_checkerboard -s 12.1 -m 7 4 7 5 8 5

在 charuco_board.svg 中创建一个 7 行、5 列、方格尺寸 30 mm、ArUco 标记尺寸 15 mm 的 ChArUco 板图案,并使用 DICT_5X5_100 作为 ArUco 标记字典(该字典包含在 DICT_ARUCO.json 文件中):

Terminal window
python generate_pattern.py -o charuco_board.svg --rows 7 --columns 5 -T charuco_board --square_size 30 --marker_size 15 -f DICT_5X5_100.json.gz

如果你想更改度量单位,使用 -u 选项(例如 mm、inches、px、m)。

如果你想更改页面大小,使用 -w(宽度)和 -h(高度)选项。

如果你想为 ChArUco 板使用自己的字典,指定你的字典文件名。例如:

Terminal window
python generate_pattern.py -o charuco_board.svg --rows 7 --columns 5 -T charuco_board -f my_dictionary.json

你可以使用 samples/cpp/aruco_dict_utils.cpp 中提供的工具,生成一个包含 30 个标记、标记大小为 5 比特的字典文件 my_dictionary.json:

Terminal window
bin/example_cpp_aruco_dict_utils.exe my_dict.json -nMarkers=30 -markerSize=5

图案由其实际物理尺寸、元素(方格或圆点)的物理尺寸以及元素数量定义。影响标定质量的因素:

  • 特征数量。OpenCV 中大多数处理检测图案的函数内部使用优化或某种随机一致性策略。板上的特征越多,可用于优化的点就越多,估计质量就越好。标定过程需要多幅图像,这意味着在大多数情况下,图案特征较少可以用更多的帧数来补偿。

  • 元素尺寸。元素的物理尺寸与拍摄距离和像素尺寸相关。每种检测器都定义了可靠检测所需的最小尺寸:圆点网格是圆点半径,棋盘格是方格尺寸,ChArUco 板是 ArUco 标记的元素尺寸。一般建议:更大的元素(以帧内像素计)可以降低检测的不确定性。

  • 板尺寸。图案板应当完整可见、清晰,并能被 OpenCV 算法可靠检测。因此,在典型目标距离下使用时,板尺寸应满足前面两条要求。通常更大的板更好,但更小的板可以更好地标定图像四角区域。

  1. 最终的图案应尽可能平整,这能提高标定精度。
  2. 光面图案不如哑光图案。光面上的反光和阴影会显著降低图案检测的效果。
  3. 大多数检测算法期望标记周围留有白色(或黑色)边框。请不要裁掉或遮挡它们。