OpenCalib静态外参标定-圆形标定板部分论文+源码阅读笔记
1.1 环境配置
-
Cmake
-
opencv 2.4
-
eigen 3
apt-get install libeigen3-dev # 检查eigen3是否安装成功:cd /usr/include/eigen3/Eigen/src/Core/util,查看是否存在Macros.h文件
-
PCL 1.9
apt-get install libpcl-dev #检查PCL是否安装成功:apt-cache show libpcl-dev
1.2 复现OpenCalib相机标定部分源码
Part1 圆形标定板检测
1. 检测圆形轮廓
前置参数:标定板上圆的行数和列数
pipline:
a) 对标定image执行自适应阈值二值化;
b) 检测并校准二值图像轮廓:
- 构建与原图同等大小的background_mask:遍历灰度图,将原图8邻域像素值均为黑色0的位置在background_mask中设置为255
- 求轮廓集:遍历background_mask,以某个像素值为0的像素点为起点,通过深搜收集所有在圆上的像素点并求圆心;若单次收集到的像素点数量小于最大像素点数量和最小轮廓像素点数量,则将本次深搜结果放入轮廓集,开始下一次深搜
深搜的具体流程:起始点入栈,while(栈不为空),将栈顶点弹出,判断其四邻域像素值是否为0,是则压入栈中,不断迭代。Center_x = 搜集到的所有点x坐标之和/像素点总数 Centor_y = 搜集到的所有点y坐标之和/像素点总数 min_contour_pt_num_ = 80 * img_w / 1920; max_contour_pt_num_ = 900 * img_w / 1920;
c)从轮廓集中提取圆
-
判断轮廓是圆:计算轮廓集中像素点到轮廓中心的最大距离和最小距离,若差值满足给定阈值(0.25),则保留该轮廓
轮廓存储格式:Circle(中心坐标, 半径, 轮廓上像素点的位置集合) // 圆中心点的颜色记录检测到的圆是黑还是白
-
异常像素点处理:轮廓像素到轮廓中心的某个距离小于最大圆半径或最小圆半径,丢弃该像素点。
min_radius_ = 10.0 * img_w / 1920; max_radius_ = 100.0 * img_w / 1920;
2. 确定标定板上所有圆的中心位置
a) 通过Ransac提取所有圆心的线段,提取垂直线,并根据斜率范围获得垂直线。
max_iter = 圆心数目 * 10
b) 根据四个约束过滤条件,计算黑色圆的线段确定标定板中心的位置。
- 两条线段应平行;
- 对应的黑色圆半径相似;
- 对应黑色圆到对面直线的投影是重合的;
- 两条线段间距和黑色圆半径大小的约束。
min_line_dist_ = circle_detector.min_radius_ * 4; max_line_dist_ = circle_detector.max_radius_ * 6;
c) 计算标定板上所有圆的中心位置:
标定板中心的位置+黑色圆的半径+白色圆的半径,计算线段的圆间距,进一步计算得到标定板上所有圆的中心。
Part2 摄像机标定
摄像机标定方法包括:消失点的标定、摄像机对地单应矩阵的标定、摄像机-车外参标定三种
2.1 摄像机-车外参标定
坐标系原点确定:参考资料-坐标系转换
- 世界坐标系(黄色):以车身中心为原点
- 相机坐标系(红色):以光心为原点
- 图像坐标系(绿色):成像平面中点为原点
- 像素坐标系(黑色):左上角为原点
输入:
- 摄像机内参矩阵
- 摄像机畸变矩阵
- 世界坐标系下的所有圆心的3d坐标
- 所有圆心的2d像素坐标
pipline:
通过四轮定位确定车辆位置,标定板相对于车身中心的坐标固定,已知空间中30个点的世界坐标和相机图像中的像素坐标,利用点和点之间的对应关系求解相机的外参数矩阵(即摄像头相对于车身坐标系的旋转矩阵和平移矩阵)
输出:旋转矩阵R和平移矩阵T
具体计算为PnP算法:指通过多对3D与2D匹配点,在已知或者未知相机内参的情况下,利用最小化重投影误差来求解相机外参的算法
- DLT:根据n个点的世界坐标和相机归一化平面坐标,最后一行用于消去深度,得到n个约束方程,利用SVD求解超定方程并得到位姿矩阵的估计。
- P3P:根据3个点的世界坐标和相机归一化平面坐标,利用余弦定理几何关系,得到3个点的相机坐标,将问题转化为3D-3D位姿估计并利用ICP求解,最后还需要一对点用于验证。
- EPnP:根据n个点的世界坐标选择4个控制点并计算加权系数,通过相机模型和n个点的像素坐标求解4个控制点在相机坐标系下的坐标,进而得到n个点在相机坐标系下的坐标,将问题转化为3D-3D位姿估计并利用ICP求解。
- BA(Opencalib包使用的方法):根据对应点的重投影误差构建非线性优化问题,利用李代数得到误差关于位姿的导数以指导优化方向,不断迭代求得所有对应点重投影误差之和最小的位姿估计。
参考资料:
2.2 消失点的标定
前置参数:
- 标定板高度; 1.2
- 两个圆心之间的距离; 1.5
- 竖直方向的点对点距离;0.2,水平方向的点与点距离默认为2*竖直方向距离
- 相机到标定板的距离;5
- 相机高度;1.2
- 相机水平偏移; 0
- 相机垂直偏移; 0
- 相机像素焦距x; 1100
- 相机像素焦距y; 1100
- 标定板类型;{0,1,2,3}
- 图像宽高
输入:标定板图像路径,参数,结果保存路径,
Pipline:
- 定义圆形标定板
col = 6;row=5;big_r=10.5; small_r = 9.8; pt_dist=28(垂直方向上的圆心距离)
- 标定板圆心位置检测(30个点的图像坐标img_pt)
- 计算30个点在标定板坐标系下(以标定板中心为坐标原点)的坐标(board_pt) (i,j)
// 标定板中心的位置: mid_width = (c_board.width - 1) * lateral_dist / 2.0; mid_height = (c_board.height - 1) * vertical_dist / 2.0; // 遍历每一个圆心所在的行列位置求对应的新坐标 board_pt_x = j * lateral_dist - mid_width; board_pt_y = mid_height - i * vertical_dist;
- 依据30个点的图像坐标和标定板系下的坐标,计算图片到标定板的单应性矩阵
- 计算消失点在标定板坐标系下的位置:
- 相机垂直位置坐标 = 相机高度-标定板的高度;
相机水平位置坐标 = 0即默认相机位于标定板的中心
假设:- 道路是平面;
- 相机光轴与路面平行
- 消失点的定义:摄像机通过标定板的与车身平行的直线和标定板的交点
2.3 基于消失点摄像机对地单应矩阵的标定
理论基础
测距公式:
相机焦距f/相机到物体的距离D= (像素宽/高)/(实际宽/高)
假设随机车道点pL 的投影像素坐标(px,py),根据透视原理,纵向和横向摄像机对点 pL 的测距可以分别定义如下:
pipline
- 求AB两点的像素坐标:
假设AB为图像中标定板出发的垂线与地面的交点,已知标定板到地面的高度;标定板到相机的距离
从而得到图像中AB两点的位置 - 求AB两点的真实坐标
- 求CD两点的像素坐标和真实坐标:
连接图像中消失点VP和AB两点,按某个比例取横坐标相同的C,D两点,可通过比例关系确定C、D两点的像素坐标,通过测距公式可计算C、D的真实坐标 - 依据四个点的像素坐标和真实坐标计算相机到地面的单应性矩阵