前言
在上一篇中已经完成了从图像到点云的转换,但是只针对单个相机,在这一篇中将再进一步,从两个相机拍摄图像,然后做点云的生成及拼接。
一、相机标定原理
相机标定的原理我们上一篇章中也提到了一些(内参矩阵、外参矩阵),而相机标定需要用到的信息包含有内部参数(焦距、光学中心等)、外部参数(旋转、平移矩阵)以及畸变系数。
其中畸变主要指的是径向畸变和切向畸变,径向畸变导致直线呈曲线状,距离图像中心越远,径向失真越大;切向畸变发生是因为摄像透镜没有与成像平面完全平行,图像中的某些区域看起来可能比预期的要近。
更为详细的原理步骤叙述可以参考:https://blog.csdn.net/lql0716/article/details/71973318。
二、关键代码
2.1 相机标定代码1
因为Azure-Kinect-Sensor-SDK中有提供Kinect标定代码,这里可以直接参考。
这里就简单说一下大致步骤:
(1) 使用相机在近距离、远距离和多个指向角度拍摄标定板图像
运行以下命令以捕获相机0的视频:
k4arecorder --device 0 -c 3072p -d PASSIVE_IR -l 20 ./device0/device0.mkv
运行以下命令以捕获相机1的视频:
k4arecorder --device 1 -c 3072p -d PASSIVE_IR -l 20 ./device1/device1.mkv
(2) 使用ffmpeg获取视频帧:
ffmpeg -i ./device0/device0.mkv -vf fps=1 ./device0/color_%d.jpg
ffmpeg -i ./device1/device1.mkv -vf fps=1 ./device1/color_%d.jpg
(3) 从每个相机拍摄的图像中产生标定文件calib.yaml:
python calibrate.py --dataset-dir ./device0 --template ./PlaneFiles/plane.json
python calibrate.py --dataset-dir ./device1 --template ./PlaneFiles/plane.json
(4) 同时拍摄固定形态的标定板(一个相机一张即可),产生双目标定的信息calibration_blob.json:
python register.py --img-a <full_path_img_b> --img-b <full_path_img_b> --template ./PlaneFiles/plane.json --calib-a <full_path_calibration_a> --calib-b <full_path_calibration_b> --out-dir <out_dir>
2.2 相机标定代码2
还可以利用Matlab相机标定获取相机的标定信息。
2.3 点云拼接代码
从上一步中可以得到从相机1到相机0的旋转矩阵和平移矩阵(我这里利用的是从Matlab中获取到的标定信息),因此点云根据这两个矩阵进行变换即可,将两个相机的点云数据变换到同一个世界坐标系下。
这里仅供参考的关键代码:
class Reconstruction{
private:
vector<Eigen::Isometry3d, Eigen::aligned_allocator<Eigen::Isometry3d>> _poses;//相机标定外参
pcl::PointCloud<pcl::PointXYZRGB>::Ptr _pointcloud; //三维重建拼接点云
int _camera_num; //相机数目
double _cx; //光心
double _cy;
double _fx; //焦距
double _fy;
double _depthScale;
public:
//构造函数
Reconstruction(){
_pointcloud.reset( new pcl::PointCloud<pcl::PointXYZRGB>() );