MATLAB 单目相机标定

MATLAB 单目相机标定

Write by Champrin on 2023-06-10
GUET Evolution Team Visual Group
Reference article:
MATLAB 双目相机标定

本文使用 MATLAB R2022b 进行单目标定,MATLAB R2021版本还未有非对称圆形的标定方法。

采用本文的一些标定选项以及结果数据处理,在 C++ OpenCV 4.5.3 及其单目视觉的相关方法,是能够得到预期的结果的。

标定操作流程

1. 打开标定工具

  • 命令行窗口输入 cameraCalibrator
  • 或在APP中找到图像处理和计算机视觉,点击Camera Calibrator

2. 添加标定图片

  • 点击 Add Images

若标定图为非对称圆形:

  • Center-to-center distance 填入相邻圆之间的实际间隔长度(mm)
  • Dim1 填入圆的组数
  • Dim2 填入一组中圆的数量

若标定图为棋盘格:

  • Size of checkerboard square 填入每个棋盘格实际长度(mm)
  • 点击 确定

3. 等待完成筛选有效标定图

  • Total ... processed 为总计标定图数量
  • Added ... 为有效标定图数量
  • Rejected ... 为无效标定图数量
  • 点击 确定

有效标定图数量较少时(小于20张),表示无法成功检测标定图,需要调整光圈或增益或曝光时间,或者在光照良好的环境下(灯下)重新标定

4. 设置标定参数

  • CAMERA MODEL 栏中
    • Camera Model:选择 Standard
    • Options
      • 选择 2 Coefficients3 Coefficients 一般用于鱼眼相机,工业相机一般不选择此项
      • 勾选 Tangential Distortion,用以计算切向畸变
      • 不勾选 Skew,若勾选,标定相机内参结果将出现参数 s ,即内参的第一行是 [fx, s, u0] ,这将会与我们使用的 OpenCV 进行测距的参数不同
  • 点击 Calibrate

5. 查看校正效果,筛去误差大的标定图

  • 筛去误差大的标定图,鼠标点击选择或者拖拽红线选择,使得重投影误差小于等于 0.2 pixels(在左下角图例中 Overall Mean Error 后的数值)
  • 误差尽量越小越好,筛去之后若还是有较大误差,可以选择重新拍摄标定图,或者自行调整标定文件

6. 导出标定结果

  • 点击 Export Camera Parameters
  • 设置结果变量名(默认即可),但同时标定多个相机时注意区分
  • 点击 确定

7. 回到工作区查看标定结果

最终单目相机标定结果,后续使用OpenCV做单目测距所需参数: 假设结果变量名设置为 `cameraParams`
  • K 相机内参矩阵
  • RadialDistortion 相机径向畸变参数 k1,k2,k3,由于第 4 步选择了 2 Coefficients,因此 k3 填为 0.0
  • TangentialDistortion 相机切向畸变参数 p1,p2

OpenCV 相机内参矩阵:\(\begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}\)

OpenCV 相机畸变向量:\(\begin{pmatrix} k_1 & k_2 & p_1 & p_2 & k_3 \end{pmatrix}\)

8. 保存标定结果为代码读取格式

假设结果变量名设置为 cameraParams,将以下代码放入 Matlab 中运行

% 保存标定结果为代码读取格式

k = cameraParams.RadialDistortion;
p = cameraParams.TangentialDistortion;
i = cameraParams.K;

fprintf('\n标定结果为:\n\n')

fprintf('%%YAML:1.0\n')
fprintf('---\n')
fprintf('IntrinsicParameters_fx: %.16e\n', i(1,1))
fprintf('IntrinsicParameters_fy: %.16e\n', i(2,2))
fprintf('IntrinsicParameters_u0: %.16e\n', i(1,3))
fprintf('IntrinsicParameters_v0: %.16e\n', i(2,3))
fprintf('DistortionFactor_k1: %.16e\n', k(1))
fprintf('DistortionFactor_k2: %.16e\n', k(2))
fprintf('DistortionFactor_p1: %.16e\n', p(1))
fprintf('DistortionFactor_p2: %.16e\n', p(2))

if size(k, 2) == 3
    fprintf('DistortionFactor_k3: %.16e\n', k(3))
else
    fprintf('DistortionFactor_k3: %.16e\n', 0.0)
end

fprintf('\n\n')

读取格式结果将在 命令行窗口 中显示,复制后,将其保存为 相机序列号.yml 文件。

附:标定棋盘图拍摄规范

  1. 在一次标定的整个过程中,不能调节相机的光圈、焦距,要保证在标定中摄像头进光量与焦距的一致,改变需要重新标定
  2. 把相机图像分成四个象限(如图1所示),应保证拍摄的标定板图像均匀分布在五个位置(四个象限以及正中心)中,且在每个位置进行不同方向的两次倾斜,参考图2;同时,可以固定住标定板,在不同角度拍摄。
  3. 标定板的成像应大致占摄像头视野的1/4左右
  4. 标定板成像不能过曝,过曝会导致特征轮廓的提取的偏移
  5. 拍摄过程中可以对标定板适当的进行补光,调节标定板到镜头的距离,以便于排出清晰的图片
  6. 标定图片数量通常在15~25张之间,数量太少,标定的参数会不准确
  7. 标定时用的标定板最好选择x方向与y方向棋盘格不同的,便于标定程序识别标定板方向
posted @ 2023-06-10 21:53  Champrin  阅读(1349)  评论(0编辑  收藏  举报