国际惯例:贴出InfiniTAM的github地址https://github.com/victorprad/InfiniTAM,在此感谢他们的great work!
最近需要做点云的数据融合(把点素变为体素),经过一番搜寻从DynSLAM(https://github.com/AndreiBarsan/DynSLAM)找到了InfiniTAM的开源实现。(DynSLAM不知什么原因,编译通过后无法运行。)我打算像DynSLAM那样把InfiniTAM融合到我们自己的三维重建系统中。
深度计算部分由我的同学负责,我只负责获得深度之后的工作。step1:先从深度图入手,生成了Infinitam所需的ppm和pgm图片。但不是所有的pgm图片都能胜任,第一次遇到错误不能读取深度图且报了一系列测试的错误,分析如下:
- 进入main函数之后先存储传入的参数(calib.txt文件 ppm图片 pgm图片 IMU<这里我没有使用IMU所以略过这个>);
- 进入到函数CreateDefaultImageSource(imageSource, imuSource, arg1, arg2, arg3, arg4) 经过判断是否传入了深度图,创建一个ImageMaskPathGenerator类对象pathGenerator(filename1, filename2);紧接着用new申请ImageFileReader的类对象赋值给imageSource,该类继承了基类BaseImageSourceEngine(public方式)。
- 那么就需要看看ImageFileReader类的私有函数。果然,找到了函数声明void loadIntoCache() const;进入定义,在此发现了报错的输出printf("error reading file '%s'\n", rgbPath.c_str());而该输出以来if的条件!ReadImageFromFile(cached_rgb, rgbPath.c_str()成立,也就是ReadImageFromFile返回false
- 进入ReadImageFromFile函数,该函数先进入FormatType type = pnm_readheader(f, &xsize, &ysize, &binary);先将图片用pnm_readheader打开读取图片头信息,返回图片的格式。如果判断图片不是MONO_16s&&MONO_16u,则再判断是否为RGB_8u||MONO_8u,若该条件成立则输出fprintf(stderr, "8-bit files are not supported by InfiniTAM. Culprit: [%s]\n", fileName);
- 否则再使用png_readheader打开读取图片信息进一步判断,我们没有使用png的图片在此不细说了。总之这两个判断得到的结论是:只有MONO_16s&&MONO_16u类型是受支持的类型。
- 接下来,让我们回到pnm_readheader的函数定义中,在该函数中发现:只有条件(max_i <= (1 << 15)) && (type == MONO_8u)满足才会将type赋值为MONO_16s,条件(max_i <= (1 << 16)) && (type == MONO_8u)满足才会将type赋值为MONO_16u。而在作者的变量定义中可以看到这两个条件满足的条件是:pgm图片头文件信息为:P2 x_size y_size 2^15 或 2^16 才是受支持的图片格式。
至此解决了因图片格式不对带来的无法读取图片的错误。下面会更加艰辛。在读取图片后发现不能建图。这一部分且见下回分解。希望有人来捧场啊,第一次发csdn。