3 编译配置
3.1 环境和工具
- Win10 64bit
- VS 2019 社区版 (地址: Download Visual Studio Tools - Install Free for Windows, Mac, Linux)
- CMake 解压版 (地址: Download | CMake)
3.2 文件准备
- OpenMVG,地址:https://github.com/openMVG/openMVG/releases
注意:上述地址下载的压缩包,最终编译有时会报错,不如在 PowerShell 中 Git 下载的稳定
1 | $ git clone --recursive https://github.com/openMVG/openMVG.git |
- 依赖项,下载 glfw,osi_clp 和 cereal,解压后放在 openMVG\src\dependencies 中,此目录内已有对应文件夹,但里面的内容是空的
osi_clp,可直接下载 OpenMVG 提供的地址: GitHub - openMVG-thirdparty/osi_clp: Osi (Open Solver Interface) and Clp (Coin-or linear programming) library from COIN-OR.
或者利用上述链接下载的 CMakeLists.txt 文件,再单独下载文件 Osi/Clp/CoinUtils,放在 osi_clp 文件夹中
https://github.com/coin-or/Osi/tags;https://github.com/coin-or/Clp/tags; https://github.com/coin-or/CoinUtils/tags
*OpenMVS* relies on a number of open source libraries, some of which are optional. For details on customizing the build process, see the compilation instructions.
* [Eigen](http://eigen.tuxfamily.org) version 3.4 or higher
* [OpenCV](http://opencv.org) version 2.4 or higher
* [Ceres](http://ceres-solver.org) version 1.10 or higher
* [CGAL](http://www.cgal.org) version 4.2 or higher
* [Boost](http://www.boost.org) version 1.56 or higher
* [VCG](http://vcg.isti.cnr.it/vcglib)
* [GLFW](An OpenGL library | GLFW)
CMakeLists.txt加上
SET(Boost_DEBUG ON)
SET(BOOST_ROOT "D:\\workspace\\Study\\thirdPart\\boost_1_76_0\\vc142")
SET(BOOST_LIBRARYDIR "D:\\workspace\\Study\\thirdPart\\boost_1_76_0\\vc142\\lib")
CGAL
Release CGAL-5.3 · CGAL/cgal · GitHub
GMP and MPFR libraries, for Windows 64bits
GMP
在上面的下载界面下载GMP and MPFR libraries, for Windows 64bits
VCG
Visual Computing Group @ Harvard · GitHub
下载编译
下载vcpkg
.\bootstrap-vcpkg.bat
vcpkg integrate install
vcpkg install zlib:x64-windows boost:x64-windows eigen3:x64-windows ceres:x64-windows opencv:x64-windows cgal:x64-windows glew:x64-windows glfw3:x64-windows
严重性 | 代码 | 说明 | 项目 | 文件 | 行 | 禁止显示状态 |
错误 | LNK1104 | 无法打开文件“libboost_zlib-vc142-mt-gd-x64-1_76.lib” | RefineMesh | D:\workspace\Study\OpenMVG\openMVS-2.0.1\build\apps\RefineMesh\LINK | 1 |
安装pcl1.12.0,里面有
严重性 | 代码 | 说明 | 项目 | 文件 | 行 | 禁止显示状态 |
错误 | LNK2001 | 无法解析的外部符号 "public: static void __cdecl boost::iostreams::zlib_error::check(int)" (?check@zlib_error@iostreams@boost@@SAXH@Z) | DensifyPointCloud | D:\workspace\Study\OpenMVG\openMVS-2.0.1\build\apps\DensifyPointCloud\MVS.lib(Scene.obj) | 1 |
严重性 | 代码 | 说明 | 项目 | 文件 | 行 | 禁止显示状态 |
错误 | LNK2001 | 无法解析的外部符号 "int const boost::iostreams::zlib::no_flush" (?no_flush@zlib@iostreams@boost@@3HB) | DensifyPointCloud | D:\workspace\Study\OpenMVG\openMVS-2.0.1\build\apps\DensifyPointCloud\MVS.lib(Scene.obj) | 1 | |
严重性 | 代码 | 说明 | 项目 | 文件 | 行 | 禁止显示状态 |
错误 | LNK2019 | 无法解析的外部符号 "protected: int __cdecl boost::iostreams::detail::zstd_base::inflate(int)" (?inflate@zstd_base@detail@iostreams@boost@@IEAAHH@Z),函数 "public: bool __cdecl boost::iostreams::detail::zstd_decompressor_impl<class std::allocator<char> >::filter(char const * &,char const *,char * &,char *,bool)" (?filter@?$zstd_decompressor_impl@V?$allocator@D@std@@@detail@iostreams@boost@@QEAA_NAEAPEBDPEBDAEAPEADPEAD_N@Z) 中引用了该符号 | DensifyPointCloud | D:\workspace\Study\OpenMVG\openMVS-2.0.1\build\apps\DensifyPointCloud\MVS.lib(DepthMap.obj) | 1 |
解决方法:
MVS项目中:Types.ini
#if BOOST_VERSION >= 107800//修改2022 原来是106900
OpenMVS中DensifyPointCloud支持jepg
头文件目录
D:\workspace\Study\OpenMVG\openMVG-2.0\src\third_party\jpeg
D:\workspace\Study\OpenMVG\openMVG-2.0\src\build\third_party\jpeg\config
库文件
D:\workspace\Study\OpenMVG\openMVG-2.0\src\build\Windows-AMD64-Release\Release\openMVG_jpeg.lib
所有命令
python tutorial_demo.py
python SfM_SequentialPipeline.py /xx/dog_pic /xx/dog_result
python SfM_GlobalPipeline.py /xx/pig_pic2 /xx/pig_result2
openMVG_main_openMVG2openMVS.exe -i tutorial_out\reconstruction_global\sfm_data.bin -o tutorial_out\reconstruction_global\scene.mvs
copy tutorial_out\reconstruction_global\scene.mvs scene.mvs
openMVG_main_openMVG2openMVS.exe -i tutorial_out\reconstruction_sequential\sfm_data.bin -o tutorial_out\reconstruction_sequential\scene.mvs
copy tutorial_out\reconstruction_sequential\scene.mvs scene.mvs
DensifyPointCloud.exe scene.mvs
ReconstructMesh.exe scene_dense.mvs
RefineMesh.exe scene_dense_mesh.mvs
TextureMesh.exe scene_dense_mesh_refine.mvs
Viewer.exe scene.mvs
Viewer.exe scene_dense.mvs
Viewer.exe scene_dense_mesh.mvs
Viewer.exe scene_dense_mesh_refine.mvs
Viewer.exe scene_dense_mesh_refine_texture.mvs
这篇博客只是记录怎样使用OpenMVG和OpenMVS这两个开源工具完成一个三维重建的pipeline,不涉及开发。
为了简便,这里并没有用源码编译软件,而是直接下载的release版本。
OpenMVG是计算机视觉领域处理多视几何的开源库。
openMVG能够:
OpenMVG:https://github.com/openMVG/openMVG/releases。
我直接下载了最新版本,目前的V1.6。解压之后如图
文件夹下有众多的exe文件。
OpenMVS是计算机视觉领域另一个开源算法库,着重解决多视点立体重建,如稠密点云重建,表面重建,表面细化,纹理映射等。
OpenMVS:https://github.com/cdcseacave/openMVS/releases。
我下载的最新版是V1.1.1,解压之后如图
也有很多exe文件和动态库。
OpenMVG+OpenMVS恰好可以完成一个三维重建的pipeline。
解压后的OpenMVG中有以下三个文件
SfM_GlobalPipeline.py是全局式SfM算法,SfM_SequentialPipeline.py是增量式SfM算法。简单一点就直接运行tutorial_demo.py脚本。默认使用的是ImageDataset_SceauxCastle里的图片,如果没有会自动从git上下载。
里面的图片是这样的
有一个K.txt文件是相机的内参,demo里并没有用到
Demo里用到是sensor_width_database下的sensor_width_camera_database.txt里面有大量厂商的相机内参数据。
如果照相机的型号不在这个列表里,(没看代码但猜测)应该是从图片的exif信息也可以推测出。但图片没有exif信息的话,就要自己提供这个K.txt文件了。
仿照demo里的文件组织,使用自己的图片进行三维重建,在同级目录下新建自己的文件夹milk,milk下新建images文件夹,把所有图片放到images文件夹下。
修改tutorial_demo.py 23行的ImageDataset_SceauxCastle为milk。
可以看一下tutorial_demo.py,
其实就是调用了OpenMVG下的几个exe文件,完成重建的几个步骤。自己可以单独调用,一步步看中间结果,这里为了简便就直接运行脚本了。
执行脚本
python tutorial_demo.py
根据图片的大小和特征需等待数分钟。
完成。产生了一个tutorial_out文件夹,里面有三个子文件夹。
其中matches文件夹下是关于特征和匹配的一些文件,
而reconstruction_global和reconstruction_sequential是两种SfM方法产生的结果。
以reconstruction_global为例,
打开SfMReconstruction_Report.html,可以看到SfM重建的报告,
这里面还有一个最重要的文件sfm_data.bin,就是重建的数据。
在进行OpenMVS步骤之前还需要将上一步生成的sfm_data.bin转化成mvs格式。
OpenMVG下有一个可执行文件openMVG_main_openMVG2openMVS.exe可以完成这个功能。
openMVG_main_openMVG2openMVS.exe -i tutorial_out\reconstruction_global\sfm_data.bin -o tutorial_out\reconstruction_global\scene.mvs
这一步会产生两个输出,一个就是scene.mvs这个文件,另一个就是一个undistorted_images文件夹,里面是经过畸变校正的图像。
至此,OpenMVG的使命完成。
步骤分解:
1、首先下载该数据集,将文件夹解压到SfM目录下的dataset文件夹(自己建的,方便管理数据集)中,进入eglise文件夹,把图片放入image文件夹,新建result文件夹
< image >:放置照片的文件夹;
< result >:输出的文件夹;
image存储输入的图片,result存储输出的数据文件
2、读入图像,产生数据文件,SFM文件夹下,终端输入:
openMVG_main_SfMInit_ImageListing -i dataset/eglise/image -o dataset/eglise/result/matches -d /home/lianqi/openMVG/src/openMVG/exif/sensor_width_database/sensor_width_camera_database.txt
1
执行成功后在matches文件夹产生sfm_data.json文件
注意!!!
“sensor_width_camera_database.txt” 是openMVG库中自带的,存储各大主流相机型号和参数的文件, “Nikon D60;23.6” 就写在该文件中。
" -d /home/lianqi/openMVG/src/openMVG/exif/sensor_width_database/sensor_width_camera_database.txt"
这条命令必须要写上,这是导入相机参数的,不然会报错
3、ComputeFeatures
openMVG_main_ComputeFeatures -i dataset/eglise/result/matches/sfm_data.json -o dataset/eglise/result/matches
1
4:ComputeMatches
openMVG_main_ComputeMatches -i dataset/eglise/result/matches/sfm_data.json -o dataset/eglise/result/matches
1
5:IncrementalSfM
openMVG_main_IncrementalSfM -i dataset/eglise/result/matches/sfm_data.json -o dataset/eglise/result/out_Incremental_Reconstruction -m dataset/eglise/result/matches
1
注:若这条命令或之后的命令出现没有找到图片或无法加载图片,例如:
error: failed reloading image ‘/home/lianqi/openMVG_Build/software/SfM/dataset/eglise/result/out_Incremental_Reconstruction/undistorted_images/DSC_0430.JPG’
则说明进入的文件夹太深了,图片并不在这层文件夹内,可以cd . .两次再执行
6:ExportUndistortedImages
openMVG_main_ExportUndistortedImages -i dataset/eglise/result/matches/sfm_data.json -o dataset/eglise/result/out_Incremental_Reconstruction/undistortedimage
1
7:数据格式转换
openMVG_main_openMVG2openMVS -i dataset/eglise/result/out_Incremental_Reconstruction/sfm_data.bin -o dataset/eglise/result/out_Incremental_Reconstruction/scene.mvs
1
sence.mvs即为openMVG生成的稀疏点云文件
将OpenMVG中生成的scene.mvs和undistorted_images文件夹拷贝到OpenMVS目录下。
先用Viewer查看一下稀疏点云,
Viewer.exe scene.mvs
生成稠密点云,
DensifyPointCloud.exe scene.mvs
这个过程比较耗时,我这十几张图片的场景会花费数分钟。
又生成了一系列文件。
查看稠密点云。
Viewer.exe scene_dense.mvs
建立粗网格,
ReconstructMesh.exe scene_dense.mvs
查看粗网格,
Viewer.exe scene_dense_mesh.mvs
生成精细网格(可选),相当耗时。
RefineMesh.exe scene_dense_mesh.mvs
查看结果,
Viewer.exe scene_dense_mesh_refine.mvs
建立混合网格,
TextureMesh.exe scene_dense_mesh_refine.mvs
查看最终结果,
Viewer.exe scene_dense_mesh_refine_texture.mvs
可以看到重建的结果不是很完美,对图像的要求还是很高的。如果缺乏纹理,视角也不多变的话,大概率会重建失败。
SfM_Data是一个数据容器,储存在sfm_data.bin中,它包括(大概也就是二进制编码的结构):Views - 图像、Intrinsics – 相机内参数、Poses – 相机外参数、Landmarks – 三维点和它们的二维图像对应点。
这个算法是需要自己相机的参数的,参数文件为“sensor_width_camera_database.txt”,这个在后续过程中也会提到,主流相机都会在这个文件中写,若其中没有自己的相机型号和参数,可通过以下方法获取(个人认为用焦距来代替参数是不准确的,所以仅在txt中没有该相机的时候用来代替):
II 手机的话下载AID64这个应用,这里面<设备>这项,查看焦距即可
例如我的手机是华为p20pro,相机型号为CLT-A10,焦距为5.58,则在txt中输入“CLT-A10;5.58”