1.简介
本文使用手机采集视频数据,制作TUM通用格式的数据集,并用ORB-SLAM2系统运行测试了该数据。需要注意的是,由于无法获得手机相机的真实轨迹,故所制作数据集不包含Groundtruth.txt。将录制好的视频制作成数据集的格式调用,也可以:1.调用ROS接口获取电脑相机的图像topic话题实时运行(需要安装相机的ROS驱动);2.直接用opencv调用电脑相机实时运行(需要在主函数mono_tum.cc中做相应修改);3.用opencv获取mp4视频中的图像数据运行(需要在主函数mono_tum.cc中做相应修改)。
相关链接:
TUM数据集格式介绍: https://www.guyuehome.com/35828
rosbag数据集转TUM格式: https://www.guyuehome.com/35920
ROS下使用电脑相机运行ORB-SLAM2: https://blog.csdn.net/qinqinxiansheng/article/details/107079265
opencv调用相机运行ORB-SLAM2: https://blog.csdn.net/zhangqian_shai/article/details/88406981
2.TUM数据集制作
首先用手机相机录制一段视频,用下列C++程序将mp4视频转换成TUM数据集的格式,以供ORB-SLAM2调用。之前的博文 https://www.guyuehome.com/35828 已经介绍了TUM数据集的格式,我们需要提取视频中的图片,以其时间戳命名并保存图片,最后将图像的路径记录在rgb.txt文件中。
该程序和之前博文有些类似https://www.guyuehome.com/35920 。程序中首先加载了mp4格式的手机视频,然后获取了图像的尺寸信息;然后对于每一帧图像,获取图像拍摄的时间信息,以其作为名称将图像保存,并将图像的路径保存在rgb.txt文件中。
#include <iostream>
#include <fstream>
#include <string>
#include <opencv2\opencv.hpp>
#include <stdio.h>
using namespace cv;
using namespace std;
int main()
{
Mat frame;
double time;
int width, high;
VideoCapture capture("test.mp4");//录制的视频,注意文件的路径
//获取图像的尺寸
width = capture.get(CV_CAP_PROP_FRAME_WIDTH);
high = capture.get(CV_CAP_PROP_FRAME_HEIGHT);
cout<<"原图像宽度width: "<<width<<endl;
cout<<"原图像高度high: "<<high<<endl;
//文件输出流
ofstream of;
of.open("rgb.txt", std::ios_base::app);
if(of.fail()){
cout<<"Fail to opencv file!!";
return 0;
}else{
of<<"#------------------start a new video------------------------"<<endl;
}
while (true)
{
//获取图片帧
capture >> frame;
if(frame.empty()) break;
time = capture.get(CV_CAP_PROP_POS_MSEC);//获取图像的拍摄时间
cout<< std::fixed <<"time:"<<time<<endl;
//对视频进行降采样
//resize(frame, frame, Size(frame.cols*0.5, frame.rows*0.5));//降采样
//imshow("手势识别结果",frame);
//waitKey(10);
//保存图片与路径
std::ostringstream osf;
osf<< "rgb/" <<std::fixed <<time << ".png";//图像以时间戳命名
cv::imwrite(osf.str(), frame);
of<<std::fixed<< time <<" "<< "rgb/" <<time<<".png"<<endl;
}
of.close();//关闭视频流
capture.release();//释放资源
system("pause");
return 0;
}
所生成的rgb.txt文件如图所示,左侧一些为图像的时间信息,右侧一列为图像的路径。需要指出的是,在使用前需要先建立rbg文件夹,使用过程中rgb.txt文件不会被覆盖,也就是每运行一次程序,都会向文件末尾添加这些。所以运行程序之前记得包上次的结果删除或者剪切到其他位置。
图1 生成的rgb.txt文件
3.相机内参标定
1.参考网上其他博文的教程,制作一个标定板,板子越大越好。
2.用手机从各个角度录制一段标定板的视频,然后用上面的程序保存成图片。记住不要直接用手机进行拍照,否则相机参数会发生变化。
3.认真挑选一些不同视角下的图片15-30张左右,这里我挑选了45张图片。有些图片比较模糊,Matlab相机工具会自动剔除一些质量的高的图片。
图2 用于相机标定的图像集合
4.打开Matlab应用程序中的相机标定工具。
图3 打开Matlab相机标定工具
5.点击添加图片,导入所挑选的图片,并设置标定板方格的尺寸,这里我的网格尺寸为31.8mm。
图4 加载图像并设置标定板尺寸
6.点击Calibrate按钮进行标定。左边区域为检测角点成功的图像列表,中间区域为图像角点的检测结果,右下角区域为估计的图像拍摄位置(即相机的外参)右上角区域为每张图像的误差,可以通过少出误差特别大的图像来提高相机参数标定的精度,比如这里需要将误差为0.5的图像删去。
图5 相机标定结果
7.在工作空间中,cameraParams中的IndexMatrx即为相机内参(R的转置,包括fx, fy, cx, cy),除了相机内参外,还可以对相机的畸变参数进行标定(包括k1, k2 ,k3, p1 ,p2)。
图7 相机内参标定结果
4.运行ORB-SLAM2系统
在运行ORB-SLAM2系统之前,要根据根据相机标定的结果制作我们的yaml参数文件,修改相应相机内参、相机畸变参数、图像尺寸等信息。
图8 修改.yaml相应参数
由于手机相机拍摄的图像为单目图像,所以运行单目的样例。我的运行命令如下所示,所保存的相机参数文件为Honor10.yaml,所制作的数据集吗,名为test。
./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/Honor10.yaml datasets/test
然后根据数据集和相机参数的路径运行ORB-SLAM2即可。有很多人运行的过程中,可视化界面会卡在第一帧,这是由于手机相机的频率问题,我们需要将读取的时间戳做相应的调整即可,比如我将时间乘以了十倍。
for(int ni=0; ni<nImages-1; ni++)
{
//Read image from file
im = cv::imread(string(argv[3])+"/"+vstrImageFilenames[ni], CV_LOAD_IMAGE_UNCHANGED);
//double tframe = vTimestamps[ni];//原始代码
double tframe = vTimestamps[ni]*10;//时间调整后的代码
}
最后系统的运行效果如下图所示。
评论(2)
您还未登录,请登录后发表或查看评论