生成.sens格式数据集用于BundleFusion重建

BundleFusion算法离线重建输入为.sens格式数据集,这里我测试了官网的数据和两款深度相机采集的数据去进行格式转换,一个是Intel RealSense D435,一个是KinectDK。

1. 利用官网数据转换为.sens格式

  • 前提:首先保证之前的BundleFusion代码可以在Wondows上跑通,还未成功的可以参考我的另一篇博客[Link];
  • 环境:Windows10 +VS2013 + CUDA10.1 + 显卡RTX2070;
  • 主要参考教程
    • https://blog.csdn.net/weixin_38636815/article/details/106466406
    • https://blog.csdn.net/Wuzebiao2016/article/details/94426905
1.1 数据准备
  • 文件夹中准备深度图、彩色图和位姿三类数据,但经过测试,pose.txt对结果没有影响,只要深度图和彩色图是正确对齐的即可,命名格式如下:生成.sens格式数据集用于BundleFusion重建_第1张图片
1.2 替换源代码
  • 将工程中原始的main函数注释掉,然后换成下面的main函数调用工程下的loadFromImages()和saveToFile();
int main()
{
    ml::SensorData sd;
    sd.loadFromImages("D:/Compressed/BundleFusionData", "frame-", "jpg");
    sd.saveToFile("D:/Compressed/test.sens");
    return 0;
}
1.3 关于压缩类型
  • 为了能让代码正常运行,生成可用的.sens文件,则需要对sensorData.h进行修改。
  • 位置:\external\mLib\include\ext-depthcamera\sensorData.h
//1. 在下面五个函数的开头加上语句指定type,"type = TYPE_ZLIB_USHORT;"
void compressDepth(const unsigned short* depth, unsigned int width, unsigned int height, COMPRESSION_TYPE_DEPTH type)

unsigned short* decompressDepthAlloc(unsigned int width, unsigned int height, COMPRESSION_TYPE_DEPTH type)

unsigned short* decompressDepthAlloc_stb(COMPRESSION_TYPE_DEPTH type) 

unsigned int short* decompressDepthAlloc_occ(unsigned int width, unsigned int height, COMPRESSION_TYPE_DEPTH type)

unsigned short* decompressDepthAlloc_raw(COMPRESSION_TYPE_DEPTH type) const
//2. 在#define M_SENSOR_DATA_VERSION 4下面,将彩色图和深度图的压缩类型进行初始化,初始化制定类型。
m_colorCompressionType = TYPE_JPEG;// TYPE_PNG;
m_depthCompressionType = TYPE_ZLIB_USHORT;
  • 修改完毕后重新编译,用bundlefusion官网的数据集测试,可以成功生成.sens文件,并成功重建得到.ply结果。

2. Intel RealSense D435采集数据转换为.sens格式

  • 参考教程:[Link1]、[link2];

2.1 录制数据集

  • 采集数据时利用Intel RealSense Viewer录制,windows和Ubuntu下均可,在主页面设置参数,rgb和depth的分辨率都是640×480,帧率30fps,保存为.bag数据包;

2.2 解析.bag文件,提取depth和rgb

  • Realsense viewer录制的bag包,利用教程1提取的rgb和深度图不是对齐的(没有逐像素对齐),会导致重建一卡一卡的,最后失败。
    • 解决方法:需要根据教程2从bag包提取对齐的rgb和深度图;

2.3 生成.sens文件

  • 准备好rgb和深度图,再按照命名格式要求准备pose.txt。准备完毕后根据1中的代码,成功生成.sens文件,便可成功重建。如下是对我的桌面简单采集并重建的结果。
    生成.sens格式数据集用于BundleFusion重建_第2张图片

3. Kinect DK采集数据转换为.sens格式

3.1 使用kinect dk录制视频流体

  • 教程:参考官网,录制的mkv格式文件存储了颜色、深度、IR 图像和 IMU 的轨道。
  • 建议:使相机朝着obstacles(墙面或者物体)扫描,kinect相机运动不能过快,深度不能超kinect量程,因为Kinect相机的有效工作距离比较短一般在3-4米。
    生成.sens格式数据集用于BundleFusion重建_第3张图片

3.2 从mkv文件解析出depth和rgb图片

  • 参考官网,将自己采集的数据格式向BundleFusion需要的格式对齐,如彩色图的命名格式是frame-000000.color.jpg,深度图的命名格式是frame-000000.depth.png,主要命令如下:
ffmpeg -i output.mkv -map 0:1 -vsync 0 depth%04d.png //提取深度图
ffmpeg -i output.mkv -map 0:0 -vsync 0 rgb%04d.png //提取彩色图
3.3 kinect采集的数据集制作.sens格式并重建
  • 关键:代码不需要改,只需要根据你的数据集修改info.txt,关于info.txt中各参数含义如下;
m_versionNumber = 4 //都用4就行
m_sensorName = StructureSensor
m_colorWidth = 1920 //你采集的实际数据的分辨率,这里我的彩色图分辨率1920*1080,深度图分辨率640*480
m_colorHeight = 1080
m_depthWidth = 640
m_depthHeight = 576
m_depthShift = 1000 //深度,realsense深度为10m,kinectDK不超过6m
m_calibrationColorIntrinsic = 914.95 0 958.53 0 0 914.70 552.57 0 0 0 1 0 0 0 0 1 //彩色相机内参
m_calibrationColorExtrinsic = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 
m_calibrationDepthIntrinsic = 502.43 0 336.56 0 0 502.51 321.38 0 0 0 1 0 0 0 0 1 //深度相机内参
m_calibrationDepthExtrinsic = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 
m_frames.size = 1575 //帧数
  • Azure Kinect DK相机内参:在Intel RealSense相机中采集的是640*480分辨率的图片,深度和彩色图分辨率相同,内参也相同。而我们这里如果用Azure Kinect DK,也需要查看其对应的相机内参,官网已给出了SDK,主要教程如下:Azure Kinect获取相机内参、VS2019配置Azure Kinect SDK、官网SDK,这里给出我自己跑出来的一些Azure Kinect相机内参的值:
生成.sens格式数据集用于BundleFusion重建_第4张图片 生成.sens格式数据集用于BundleFusion重建_第5张图片
生成.sens格式数据集用于BundleFusion重建_第6张图片 生成.sens格式数据集用于BundleFusion重建_第7张图片
生成.sens格式数据集用于BundleFusion重建_第8张图片 生成.sens格式数据集用于BundleFusion重建_第9张图片
  • 一个小问题:我这里设置好后,运行主程序读取.sens文件,但读取的内参不准,索性在sensorData.h中的loadFromImages函数中直接指定内参是什么,这样生成的.sens文件是正确的的,可以成功重建,但重建结果不如RealSense,不知道是不是rgb和depth图像对齐出了问题;

你可能感兴趣的:(稠密SLAM,算法)