相机标定
标定目的:建立摄像机图像像素位置(像素坐标系)与场景点位置之间(世界坐标系)的关系
方法:据摄像机模型,由已知特征点的像素坐标求解摄像机的模型参数,从而从图像出发恢复出空间点三维坐标,即三维重建。期间需要通过标定求解
- 内参 4 个 :fx fy cx cy (对应下面所述 kx ky u0 v0)
- 畸变系数 5个:k1 k2 k3(径向畸变 对应下面的 kc(1)、kc(2)、kc(5) 表现形式拍摄出来的图片表现为 桶形 枕形) p1 p2(切向畸变 对应下面的 kc(3)、kc(4)
) - 外参 6个: 旋转矩阵 Rx Ry Rz 平移向量 tx ty tz
(荐)相机标定数学计算公式推导 (知乎)
(荐) 从零开始学习「张氏相机标定法」(五)优化算法正传(微信)
注意事项
内参标定需要注意问题
-
制作棋盘格靶标时,黑白方格尺寸大小需要相同,且尺寸严格保持一致。靶标方格数量不宜太小,行列数大于10为宜,方格尺寸不宜太大或太小,采集的靶标图像中方格边长尺寸不小于20个像素
eg 图片分辨率 640360,棋盘格(阵列26 * 26)占图片的⅓,则每个边长尺寸像素 p i x e l = 640 ∗ 480 3 ∗ 1 26 ∗ 26 2 ≈ 10 pixel=\sqrt[2]{\frac{640*480}{3}*\frac{1}{26*26}}\approx10 pixel=23640∗480∗26∗261≈10 不满足棋盘格方格子像素大于20的条件* -
建议在摄像头视野内五个不同位置上(左上、右上、左下、右下、正中心)分别拍摄图片。
-
标定时用的标定板最好选择x方向与y方向棋盘格不同的,便于标定程序识别标定板方向(选择长方形标定板)
-
标定板的焦点数目影响标定的精度,(一般50个 9*10)视野范围内,标定点个数越多越好
-
棋盘格标定板需放在摄像头的主要工作距离(摄像头的焦距范围内)
-
靶标相对于摄像机的角度应有较大范围的变化,应包含绕三个轴(X、Y、Z轴)较大角度的旋转,最好不小于30°
-
标定图片数量10~20副最好
-
拍摄时 不能动调整好的摄像头(有一些摄像头 如做成一体的双目摄像头 定焦 可以动)
-
用MATLAB工具箱标定时,在画棋盘格四个角时,要求相邻两个角点应处于同一网格线上,最后点完四个角所形成的的四边形应与棋盘格靶标网格线基本平行
-
拍摄的图片保持清晰(理论上分辨率越高越好,但是分辨率高 会导致标定时因图片太大而处理速度慢的问题)
-
采集图像过程中,摄像机的焦距不能调整。因为焦距属于摄像机的内参数,不同焦距下采集的图像隐含了不同的内参数,这些图像放在一起进行标定不能得到正确的结果
-
摄像机的实际 y 轴与理想 y 轴之间的夹角 c 是否标定,由 est_alpha 标志位设定。est_alpha=1 时对 alpha_c 进行标定,est_alpha=0 时不对 alpha_c 进行标定,即是下图中红框部分:
![](https://i-blog.csdnimg.cn/blog_migrate/acfefae28994724b152bb804eac12b4c.png)
- 数组 est_dist(1:5)是畸变系数 kc(1:5)是否标定的标志,只对标志取值为 1 的畸变系数标定,标志取值为 0 的畸变系数不标定。默认值为 est_dist(1:5)=[1 1 1 1 0],即对畸变系数 k c1 ~k c4 进行标定,对 k c5 不进行标定,k c5 =0
- 运行 calib_gui 指令后,Matlab 处于 busy 状态,Matlab 命令窗口不再响应其它命令。只有在点击标定工具箱的“Exit”键退出标定后,Matlab 命令窗口才能恢复响应其它命令(即在标定过程中,任意一步错误时,只能重新标定,此时只能点“Exit”键强行退出)
外参标定注意问题
- 方格尺寸必须输入实际尺寸
- 提取角点时,在图形窗口利用鼠标点击的第一个角点作为靶标坐标系的原点,得到的外参数是靶标坐标系在摄像机坐标系中的位姿。
- rodrigues 旋转向量 omc_ext 与姿态矩阵 Rc_ext 可以利用 rodrigues 函数进行转换。omc_ext=rodrigues(Rc_ext),Rc_ext=rodrigues(omc_ext)。omc_ext是31矩阵,Rc_ext是33矩阵
立体视觉标定需要注意的问题
- 提取角点时,在图形窗口利用鼠标点击的第一个角点作为靶标坐标系的原点,左右摄像机对应的靶标图像对需要选择相同的第一个角点作为原点。其他的 3 个角点在左右摄像机的靶标图像中也应相同。
- 左右摄像机采集的图像数量必须相同。相同的编号的左右摄像机采集的图像是靶标,在同一位姿时左右摄像机采集的图像,构成一组立体视觉的靶标图像对。
- 得到的外参数是左摄像机相对于右摄像机的位姿,即左摄像机坐标系在右摄像机坐标系中的位姿。
- 运行 stereo_gui 指令后,Matlab 命令窗口可以响应其它命令
打印棋盘格(c++)
#include <opencv2/opencv.hpp>
#include <iostream>
/** 输出指定格式的棋盘图
@param width 棋盘的宽度,不要超过10000.
@param height 棋盘的高度,不要超过10000.
@param pixel 每个格子的大小,建议行和列的格子数一个为奇数一个为偶数
@param fileName 输出的文件名,支持相对路径和绝对路径,支持png、jpg、bmp等.
*/
static int checkerboard(int width, int height, int pixel, const char* fileName)
{
if (width > 0 && height > 0 && pixel > 0 && width <= 10000 && height <= 10000 && pixel <= width && pixel <= height && fileName)
{
cv::Mat image = cv::Mat::zeros(cv::Size(width, height), CV_8U);
uchar* uc = image.data;
for (size_t j = 0; j < height; j++)
{
for (size_t i = 0; i < width; i++)
{
if ((i / pixel + j / pixel) % 2)
{
uc[j * width + i] = 255;
}
}
}
imwrite(fileName, image);
return 0;
}
return