【OpenCV】相机标定之利用棋盘格信息标定

这里介绍下基于棋盘格的相机参数标定。接上文说到的《【OpenCV】相机标定之棋盘格角点检测与绘制》,可以获取图像中的角点信息,再结合世界坐标点,就可以完成相机标定,将相机的图像坐标与世界坐标之间的转换关系建立起来,从而实现相机的三维重建、姿态估计等应用。

首先介绍下calibrateCamera() 函数

**calibrateCamera() **是 OpenCV 中用于相机标定的核心函数,它通过多张从不同角度拍摄的棋盘格图像,使用已知的物体的3D坐标和对应的图像点,来计算相机的内参(如焦距、主点位置等)和外参(如相机的旋转和平移向量)和畸变系数。

函数原型

cpp 复制代码
double cv::calibrateCamera(
    InputArrayOfArrays objectPoints,
    InputArrayOfArrays imagePoints,
    Size imageSize,
    InputOutputArray cameraMatrix,
    InputOutputArray distCoeffs,
    OutputArrayOfArrays rvecs,
    OutputArrayOfArrays tvecs,
    int flags = 0,
    TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON)
)

参数说明
objectPoints : 世界坐标系中的3D点集,通常使用棋盘格的角点坐标(z=0)

类型: vector<vector>

每个元素是棋盘格角点的3D坐标

imagePoints : 图像中对应的2D点集

类型: vector<vector>

每个元素是检测到的棋盘格角点的像素坐标

imageSize: 图像尺寸(宽度,高度)

cameraMatrix: 输出相机内参矩阵(3×3)

cpp 复制代码
[fx  0 cx]
[ 0 fy cy]
[ 0  0  1]

distCoeffs: 输出畸变系数向量(通常为5个元素: k1, k2, p1, p2, k3)。径向畸变和切向畸变。如果没有畸变,可以设置为 None 或者是一个全零的数组。

rvecs: 输出每幅图像的旋转向量(Rodrigues表示)。旋转向量与旋转矩阵是等效的,但旋转向量更为紧凑。通过它,可以了解相机相对于标定板的旋转情况。旋转向量是轴角表示,方向表示旋转轴,长度表示旋转角度(弧度)

tvecs: 输出每幅图像的平移向量。平移向量描述了标定板在相机坐标系中的位置。

flags : 标定标志位(可选):

CALIB_USE_INTRINSIC_GUESS: 使用输入的cameraMatrix作为初始值

CALIB_FIX_PRINCIPAL_POINT: 固定主点

CALIB_FIX_ASPECT_RATIO: 固定fx/fy比值

CALIB_ZERO_TANGENT_DIST: 设置切向畸变系数p1,p2为零

CALIB_FIX_K1,...,CALIB_FIX_K6: 固定对应的径向畸变系数

CALIB_RATIONAL_MODEL: 使用有理函数模型计算畸变

//下面几个用的少

CALIB_THIN_PRISM_MODEL系数s1、s2、s3和s4已启用。为了提供向后兼容性,应明确指定此额外标志,使校准函数使用薄棱镜模型并返回12个或更多系数。

CALIB_FIX_S1_S2_S3_S4在优化过程中,薄棱镜的畸变系数保持不变。如果设置了CALIB_USE_INTRINSIC_GUESS,则使用提供的distCoeffs矩阵中的系数。否则,它将设置为0。

CALIB_TILTED_MODEL系数tauX和tauY已启用。为了提供向后兼容性,应明确指定此额外标志,使校准函数使用倾斜的传感器模型并返回14个系数。

CALIB_FIX_TAUX_TAUY在优化过程中,倾斜传感器模型的系数保持不变。如果设置了CALIB_USE_INTRINSIC_GUESS,则使用提供的distCoeffs矩阵中的系数。否则,它将设置为0。

criteria: 迭代优化终止条件

返回值

返回所有图像的重投影误差的RMS(均方根)值,表示标定的精度。

使用示例

cpp 复制代码
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main() {
    // 准备棋盘格角点的世界坐标(假设棋盘格在z=0平面)
    vector<vector<Point3f>> objectPoints;
    vector<vector<Point2f>> imagePoints;
    
    // 假设我们有多张标定图像
    vector<String> imageNames;
    glob("calibration_images/*.jpg", imageNames);
    
    // 棋盘格尺寸(内角点数量)
    Size boardSize(9, 6);
    float squareSize = 1.0f;  // 棋盘格方块的物理尺寸(单位任意)
    
    // 生成世界坐标点
    vector<Point3f> obj;
    for(int i = 0; i < boardSize.height; i++)
        for(int j = 0; j < boardSize.width; j++)
            obj.push_back(Point3f(j*squareSize, i*squareSize, 0));
    
    // 检测每张图像的角点
    for(size_t i = 0; i < imageNames.size(); i++) {
        Mat img = imread(imageNames[i], IMREAD_GRAYSCALE);
        vector<Point2f> corners;
        bool found = findChessboardCorners(img, boardSize, corners);
        
        if(found) {
            // 亚像素精确化
            cornerSubPix(img, corners, Size(11,11), Size(-1,-1),
                         TermCriteria(TermCriteria::EPS+TermCriteria::COUNT, 30, 0.1));
            
            imagePoints.push_back(corners);
            objectPoints.push_back(obj);
        }
    }
    
    // 相机标定
    Mat cameraMatrix, distCoeffs;
    vector<Mat> rvecs, tvecs;
    Size imageSize = imread(imageNames[0]).size();  
    double rms = calibrateCamera(objectPoints, imagePoints, imageSize,
                               cameraMatrix, distCoeffs, rvecs, tvecs);
   
    cout << "重投影误差: " << rms << endl;
    cout << "相机内参:\n" << cameraMatrix << endl;
    cout << "畸变系数: " << distCoeffs.t() << endl;
    
    return 0;
}

注意事项

1、通常需要15-20张不同角度的棋盘格图像才能获得良好的标定结果

2、棋盘格应覆盖图像的各个区域(中心、边缘、角落)

3、棋盘格应有不同的倾斜角度

4、重投影误差(RMS)越小越好,一般应小于0.5像素

5、标定完成后,可以使用undistort()函数校正图像畸变

相关推荐
凡达Ai派1 分钟前
AI画布里的文字总是错位或乱码?把生成、排版和校对拆成三段
图像处理·人工智能·深度学习·神经网络·自然语言处理·知识图谱
桃西西呀5 分钟前
LangChain 之九:一个能检索又会调工具的流式问答助手
人工智能·langchain·llm
Martina_03219 分钟前
AI生成的模块场景一烘焙就有黑边?用6步检查Lightmap UV、纹素密度与Padding
人工智能·游戏·3d·aigc·uv·游戏策划·关卡设计
熊猫钓鱼>_>16 分钟前
从闲置平板到家里的“控制大脑“:鸿蒙智慧中控面板完整实战
运维·人工智能·华为·自动化·电脑·ai编程·harmonyos
accept 99%30 分钟前
拆开Jev 的原理和本地跑法 Jev科普(二)
人工智能·机器学习
johnsong34 分钟前
125B模型装上桌面:AI推理主权革命与治理悖论
人工智能
库拉镜像AI牛牛38 分钟前
漫剧工作室量产方案:依托知漫剧 AI 短剧降本增效
大数据·服务器·前端·人工智能·语音识别
狂野小白兔40 分钟前
AI游戏制作04——Codex 搭配 Godot MCP 全流程教程
人工智能·游戏·godot
skywalk816344 分钟前
deepseek harness 官方已经更新到新版:v0.2.1-alpha.1 Pre-release请把咱们的FreeBSD版本也同步更新到新版本!
人工智能·freebsd·实践·deepseek·harness
软件派1 小时前
2026国外主流AI工具Top5深度对比!含官网、优缺点、适用场景与定价(干货收藏)
人工智能