相机标定
相机内参标定
- 首先采集不同位置的标定板照片
- matlab工具箱选择
Camera Calibrator工具
- 导入采集好的标定图片
- 输入标定板尺寸
- 检查每个图片的坐标系是否一致,剔除不一致的图片
- 检查完之后,选择这几个按钮,点击标定
- 剔除误差大的值,直到所有误差值均小于0.5
- 导出内参
相机单应矩阵标定
标定世界坐标系
在相机画面中选择四个标定点,测得四个标定点的真实距离,如下示例:
测量示例中 1、2、3、4 位置的像素坐标以及各个点之间的真实距离,调用 cv::findHomography 方法获取单应矩阵。
homographyMatrix = cv::findHomography(pixelCoords, worldCoords, 0);
其中 pixelCoords 为 1、2、3、4 位置像素坐标:worldCoords = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};
worldCoords 为 1、2、3、4 位置对应的世界坐标信息,怎样生成worldCoords 数组?
此处假设 1、2、3、4 点构成矩形,且矩形宽高为L、H,将坐标原点建立在位置 1 处,则 1、2、3、4 位置的世界坐标为:worldCoords = {{0, 0}, {L, 0}, {L, H}, {H, 0}};
当然坐标原点也可以选择其他位置,worldCoords 内的位置信息改距坐标原点的信息即可。
也可以实现像素坐标转GPS坐标,不需要建立原点,只需将 worldCoords 中四个点的位置坐标改为对应的GPS坐标即可。
雷达相机联合标定
LIDAR2Camera 手动标定
标定工具:https://github.com/PJLab-ADG/SensorsCalibration/tree/master/lidar2camera
依赖库:
- Pangolin(0.6版本):https://github.com/stevenlovegrove/Pangolin/tree/v0.6
# PCL(1.9.1版本)
sudo apt remove libpcl-dev
# 避免版本冲突
git clone -b pcl-1.9.1 https://github.com/PointCloudLibrary/pcl.git
cd pcl
mkdir build
cd build
cmake ..
make -j$(nproc)
sudo make install
然后编译 /lidar2camera/manual_calib/ 程序就好了。
autoware标定工具
安装标定工具
git clone https://github.com/FENGZHANG123/autoware_camera_lidar_calibrator
catkin_make
source devel/setup.bash
rosrun calibration_camera_lidar calibration_toolkit
安装依赖库
sudo apt install ros-noetic-jsk-recognition-msgs
sudo apt install ros-noetic-jsk_footstep_msgs
安装nlopt
# 下载:
https://github.com/stevengj/nlopt/archive/v2.7.1.tar.gz
cmake .. && make && sudo make install
修改 calibration_camera_lidar/CMakeLists.txt
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories( /usr/local/include)
link_directories(/usr/local/lib)
matlab标定
- 采集同一时刻雷达与图像的标定板数据
- 与相机内参标定类似,导入图片与pcd点云文件,并设置棋盘格大小
- 绘制感兴趣区域,这样可以降低雷达检测范围,可以通过
Dimension Tolerance、Cluster Threshold控制标定板检测结果,然后点击Calibrate标定,将旋转、平移与重投影误差误差降低到设定范围内,导出外参即可。
标定板标定
此处简要记录雷视标定流程,使用 cv::aruco::DICT_6X6_250 二维码标定板。
相机端流程:
- 采集图像,检测图中二维码角点坐标(亚像素级精度),得到一组2D坐标;
- 利用
cv::aruco::estimatePoseSingleMarkers函数计算每个2D坐标相对于相机光心的3D姿态,每个2D坐标得到相对应的3D旋转向量与平移向量;因为我们知道二维码的长度,所以二维码的四个角的像素坐标与世界坐标相当于都有了,所以可以计算出3D姿态; - 将得到的3D旋转向量与平移向量加权求平均,得到标定板的一个全局姿态 T(x,y,z),R(r,p,y);
- 以全局姿态 T、R为初始姿态,和2D角点坐标、相机内参与畸变系数,利用
cv::aruco::estimatePoseBoard函数计算标定板在相机前方极其精确的“位置和倾斜角”(3D姿态);此处相当于计算出了标定板局部坐标系(以质心为原点)到相机全局坐标系(以光心为原点)的刚体变换矩阵(包含旋转 R 和平移 t); - 利用圆孔物理设计图,得到四个圆心在标定板局部坐标系下的 3D 坐标,将圆孔的局部坐标左乘这个刚体变换矩阵R、t得到相机坐标系下的圆心3D坐标,该坐标即为雷视标定中相机端的3D坐标,校验坐标的精准度得到最终图像坐标;
- 然后利用相机内参与外参将相机坐标系下的圆心3D坐标重投影至像素坐标系,得到图像上的像素坐标;
雷达端流程:
- 采集一帧点云,X、Y、Z轴滤波,截取感兴趣区域(ROI ,Region of Interest );
- 利用 RANSAC 算法对截取出来的点云进行平面分割,得到平面点云与平面方程参数
[A, B, C, D],数学表达式为Ax + By + Cz + D = 0,其中[A, B, C]是平面法向量; - 利用平面法向量得到一个旋转矩阵R,通过R将平面点云旋转并降到2维平面(Z=0),过程中记录点云的Z轴平均值
average_z,这个average_z就是标定板原来的真实高度; - 对二维平面的点云进行边缘提取,利用角度间隙边界检测 (Boundary Estimation) 算法得到边缘点云;
- 对边缘点进行聚类,得到一组聚类簇,然后对每个聚类簇进行圆拟合得到圆心坐标;然后再将圆心坐标反变换回到原始坐标系,得到圆心坐标点云;
结果计算:
- 利用奇异值分解
svd.estimateRigidTransformation计算最终外参;
结果展示: