Link Search Menu Expand Document

Camera Calibration

这部分文档包含相机标定的内容,以及多个场景下的相机标定。

  1. Camera Calibration
    1. Some Tips
    2. 0. Prepare your chessboard
    3. 1. 相机内参标定
      1. 1.1 获取图像
      2. 1.2 检测棋盘格
      3. 1.3 内参标定
    4. 2. 相机外参标定
      1. 2.1 使用棋盘格
        1. LightStage
        2. Hikvision
      2. 2.2 使用标志点
      3. 2.3 使用人体关键点
      4. 2.4 BA优化
      5. 单目情况
    5. 3. 检查
      1. 可视化检查
      2. 定量结果

Before reading this document, you should read the OpenCV-Python Tutorials of Camera Calibration carefully.

Some Tips

  1. Use a chessboard as big as possible.
  2. Use a chessboard as rigid as possible.
  3. You must keep the same resolution during all the steps.

0. Prepare your chessboard

下载OpenCV官网上的棋盘格,或自己生成一个,去附近的文印店,告诉老板需要打到一个大的KT板上。并告诉老板需要一格有多长。

1. 相机内参标定

1.1 获取图像

文件目录组织保持树状结构,所有的图片都保存在images目录下

<seq>
└── images
    ├── 1
    │   ├── 000000.jpg
    │   ├── 000001.jpg
    │   ├── 000002.jpg
    │   └── ...
    ├── 2
    │   ├── 000000.jpg
    │   ├── 000001.jpg
    │   ├── 000002.jpg
    │   └── ...
    ├── ...
    ├── ...
    ├── 8
    │   ├── 000000.jpg
    │   ├── 000001.jpg
    │   ├── 000002.jpg
    │   └── ...
    └── 9
        ├── 000000.jpg
        ├── 000001.jpg
        ├── 000002.jpg
        └── ...

1.2 检测棋盘格

首先需要检测棋盘格,对于一个(9, 6)的棋盘格,每一个格子的长度为0.1m,使用以下命令创建与检测棋盘格:

# detect chessboard
python3 apps/calibration/detect_chessboard.py ${data} --out ${data}/output/calibration --pattern 9,6 --grid 0.1 --seq
参数名称 可选值 含义
pattern 9,6 棋盘格的角点数
grid 0.1 棋盘格的每格的长度
seq bool, 默认False 如果拍的是一段视频,那么使用这个选项可以加速棋盘格的检测,会通过二分法去查找棋盘格

棋盘格并不是一个中心对称图形,其中的(9, 6)指的是角点的数目,而不是格子的数目。如果打印的棋盘格是中心对称的,那么肯定打印错了。

对于一张有棋盘格的图像,检测会比较快,如果图像中没有棋盘格,那么检测会很慢,所以需要尽量保证需要检测的图像中包含棋盘格

检测结果会以json格式存在${data}/chessboard中,可视化的结果会存在${data}/output/calibration中。


棋盘格检测结果

1.3 内参标定

棋盘格提取之后,计算相机内参。

python3 apps/calibration/calib_intri.py ${data} --num 200 --share_intri
参数名称 可选值 含义
ext .jpg, .png 图像后缀
num >0 使用的图像数量
share_intri bool, 默认False 是否共享所有相机的内参

运行完成后,程序会输出intri.yml${data}/output目录。

这一步如果使用200张图需要花费大概2小时

2. 相机外参标定

相机外参标定步骤用于确定各个相机的在世界坐标中的位置。通常会使用一些标志点来确定世界坐标。最简单的方式是使用棋盘格,对于大场景无法使用棋盘格的,可以使用场景中的标志点,并测量其实际物理坐标。

2.1 使用棋盘格

对于多个相机可以拍到地面的情况,首先将棋盘格放置到地面,确保每一个相机都能看到。接着抓取一帧图片,如图所示。


将棋盘格放置在地面

检测棋盘格:

python3 apps/calibration/detect_chessboard.py ${data} --out ${data}/output/calibration --pattern 9,6 --grid 0.1 --debug

使用标注工具检查检测的棋盘格是否有问题:

python3 apps/annotation/annot_calib.py ${data} --annot chessboard --mode chessboard
按键 功能
q/Q 退出标注/不保存直接退出
空格 切换到下一个点
b 切换到上一个点
e 对于选定的矩形框,进行检测

标定外参,注意在这里需要指定之前标定的相机内参的路径:

python3 apps/calibration/calib_extri.py ${data} --intri <path/to/intri>/intri.yml

相机外参将会输出到${data}目录下。

LightStage

对于LightStage数据,需要使用2048分辨率下的图片

python3 apps/calibration/calib_extri.py ${data} --intri data/camera/intri_lightstage_2048.yml
# 对输出的相机参数缩小一半,得到1024分辨率下的相机参数
python3 apps/calibration/transform_camera.py ${data} ${data}/1024 --scale 0.5

此时的${data}/1024目录下即为所需的输出。

Hikvision

2.2 使用标志点

创建标志点

python3 apps/calibration/create_marker.py ${data} --N 100

手动标注:

python3 apps/annotation/annot_calib.py ${data} --annot chessboard --mode marker
按键 功能
单击 点中一个点
空格 确认当前选中的点,并切换到下一个点
b 切换到上一个点

此时的可视化为5个点为1组,依次连接。

标定外参,使用BA

2.3 使用人体关键点

TODO

2.4 BA优化

在多相机的情况下,可以利用多视角的一致性信息。


棋盘格在至少三个相机内可见
data=/path/to/img
# 以下三种情况选择其中一个
# 1. 只优化相机的RT
python3 apps/calibration/calib_ba.py ${data} --init ${data}/../ground --ground ${data}/../ground --out ${data}/output-ba
# 1. 优化相机的RT,同时优化K
python3 apps/calibration/calib_ba.py ${data} --init ${data}/../ground --ground ${data}/../ground --out ${data}/output-ba-optK --optK
# 1. 优化相机的RT,同时优化K, D
python3 apps/calibration/calib_ba.py ${data} --init ${data}/../ground --ground ${data}/../ground --out ${data}/output-ba-optKD --optK --optD
参数名称 可选值 含义
init path 初始化的相机内参与外参的路径
ground path 拍摄的棋盘格放在地面的文件路径
out path 标定结果输出路径
optK bool 是否优化相机的焦距、光心,默认False
optD bool 是否优化相机的畸变参数,默认False

单目情况

对于单目的情况,无法使用多视角标定,可直接创建空白的相机,这个相机的焦距会根据输入的图像形状指定,光心在图像中心,旋转为单位阵,位置为0。注意,这样指定的相机无法用于多视角重建的代码,只能用于单视角重建。

python3 apps/calibration/create_blank_camera.py ${data} --shape 2160 3840

3. 检查

可视化检查

cube:

out=/path/to/output
python3 apps/calibration/check_calib.py ${data} --out ${out} --mode grid --show

可视化虚拟的立方体

立方体的顶点0坐标为(0, 0, 0),顶点1坐标为(1, 0, 0),顶点3坐标为(0, 1, 0),顶点4坐标为(0, 0, 1)

human:

设置data为人体Tpose的数据,检查人体重投影误差

python3 apps/calibration/check_calib.py ${data} --out ${data} --mode human --show

如果检测了手的关键点,可以增加--hand标志来加入手部关键点。


可视化关键点重投影;绿色的为检测的位置,红色的为重投影的位置

定量结果

如果使用了BA来进行标定,可以通过这一步定量计算所有帧的平均标定误差。

out=/path/to/output
python3 apps/calibration/check_calib.py ${data} --out ${out} --mode match --show

Table of contents