最新OpenMVG编译安装与逐命令运行增量式和全局式SfM教程(文末附自动化运行脚本)

  openmvg是一个轻便的可以逐步运行的SfM开源库,它同时实现了增量式和全局式两种算法。

说明文档地址:https://openmvg.readthedocs.io/en/latest/
github主页地址:https://github.com/openMVG/openMVG
在这里插入图片描述

  

1 编译安装

  openmvg的安装比较简单,首先是安装依赖:

$ sudo apt‐get install libxxf86vm1 libxxf86vm‐dev libpng‐dev libjpeg‐dev libtiff‐dev libxi‐dev libxrandr‐dev graphviz

  然后克隆openmvg源码:

$ git clone ‐‐recursive https://github.com/openMVG/openMVG.git

  最后,使用cmake编译与安装:

$ mkdir openMVG_Build && cd openMVG_Build
$ cmake ‐DCMAKE_BUILD_TYPE=RELEASE ../openMVG/src/
$ cmake ‐‐build . ‐‐target install

  编译过程中有可能会出现eigen版本太低造成的错误:

/usr/include/eigen3/Eigen/SparseCholesky:34:2: error: #error The SparseCholesky module has nothing to offer in MPL2 only mode
 #error The SparseCholesky module has nothing to offer in MPL2 only mode
  ^~~~~
In file included from /usr/include/eigen3/Eigen/SparseCholesky:37:0,
                 from /home/czq/softwares/openMVG/src/openMVG/multiview/rotation_averaging_l1.cpp:37:
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:266:72: error: ‘AMDOrdering’ does not name a type; did you mean ‘COLAMDOrdering’?
 plate<typename _MatrixType, int _UpLo = Lower, typename _Ordering = AMDOrdering<typename _MatrixType::StorageIndex> > class SimplicialLLT;
                                                                     ^~~~~~~~~~~
                                                                        COLAMDOrdering
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:266:83: error: expected ‘>’ before ‘<’ token
 ame _MatrixType, int _UpLo = Lower, typename _Ordering = AMDOrdering<typename _MatrixType::StorageIndex> > class SimplicialLLT;
                                                                     ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:267:72: error: ‘AMDOrdering’ does not name a type; did you mean ‘COLAMDOrdering’?
 plate<typename _MatrixType, int _UpLo = Lower, typename _Ordering = AMDOrdering<typename _MatrixType::StorageIndex> > class SimplicialLDLT;
                                                                     ^~~~~~~~~~~
                                                                        COLAMDOrdering
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:267:83: error: expected ‘>’ before ‘<’ token
 ame _MatrixType, int _UpLo = Lower, typename _Ordering = AMDOrdering<typename _MatrixType::StorageIndex> > class SimplicialLDLT;
                                                                     ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:268:72: error: ‘AMDOrdering’ does not name a type; did you mean ‘COLAMDOrdering’?
 plate<typename _MatrixType, int _UpLo = Lower, typename _Ordering = AMDOrdering<typename _MatrixType::StorageIndex> > class SimplicialCholesky;
                                                                     ^~~~~~~~~~~
                                                                        COLAMDOrdering
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:268:83: error: expected ‘>’ before ‘<’ token
 ame _MatrixType, int _UpLo = Lower, typename _Ordering = AMDOrdering<typename _MatrixType::StorageIndex> > class SimplicialCholesky;
                                                                     ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:515:60: error: template argument 3 is invalid
     typedef internal::traits<SimplicialLDLT<MatrixType,UpLo> > LDLTTraits;
                                                            ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:515:62: error: template argument 1 is invalid
     typedef internal::traits<SimplicialLDLT<MatrixType,UpLo> > LDLTTraits;
                                                              ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:516:59: error: template argument 3 is invalid
     typedef internal::traits<SimplicialLLT<MatrixType,UpLo>  > LLTTraits;
                                                           ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:516:62: error: template argument 1 is invalid
     typedef internal::traits<SimplicialLLT<MatrixType,UpLo>  > LLTTraits;
                                                              ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h: In member function ‘void Eigen::SimplicialCholesky<_MatrixType, _UpLo, _Ordering>::_solve_impl(const Eigen::MatrixBase<OtherDerived>&, Eigen::MatrixBase<OtherDerived>&) const’:
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:605:27: error: qualified-id in declaration before ‘(’ token
           LDLTTraits::getL(Base::m_matrix).solveInPlace(dest);
                           ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:607:26: error: qualified-id in declaration before ‘(’ token
           LLTTraits::getL(Base::m_matrix).solveInPlace(dest);
                          ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:616:27: error: qualified-id in declaration before ‘(’ token
           LDLTTraits::getU(Base::m_matrix).solveInPlace(dest);
                           ^
/usr/include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h:618:26: error: qualified-id in declaration before ‘(’ token
           LLTTraits::getU(Base::m_matrix).solveInPlace(dest);
                          ^
/home/czq/softwares/openMVG/src/openMVG/multiview/rotation_averaging_l1.cpp: In function ‘bool openMVG::rotation_averaging::l1::internal::SolveIRLS(const RelativeRotations&, openMVG::rotation_averaging::l1::Matrix3x3Arr&, const sMat&, unsigned int, double)’:
/home/czq/softwares/openMVG/src/openMVG/multiview/rotation_averaging_l1.cpp:460:53: error: template argument 3 is invalid
   using Linear_Solver_T = Eigen::SimplicialLDLT<sMat>;
                                                     ^
/home/czq/softwares/openMVG/src/openMVG/multiview/rotation_averaging_l1.cpp:462:3: error: ‘Linear_Solver_T’ was not declared in this scope
   Linear_Solver_T linear_solver;
   ^~~~~~~~~~~~~~~
/home/czq/softwares/openMVG/src/openMVG/multiview/rotation_averaging_l1.cpp:463:3: error: ‘linear_solver’ was not declared in this scope
   linear_solver.analyzePattern(A.transpose() * A);
   ^~~~~~~~~~~~~

  一般只需将其版本升级为3.4.0即可。查看eigen版本的命令为:

pkg-config --modversion eigen3

  重装eigen的教程可以参考:ubuntu重装/升级eigen教程
  

2 运行命令

  openmvg的官方使用说明里有说如何运行SfM,包括使用脚本一行命令运行(只有在图像exif带内参信息的时候才能使用),以及如何分步运行,可以参考这里。但是这里需要说明的是,openmvg的代码后面有修改过,而使用文档却并没有完全更新过来。所以,如果只是按照使用文档来运行,或者是很多别的教程(可能只是直接抄官方文档或者比较老的),很可能会遇到错误(很多示例并不能跑)。在遇到一些不知名的报错以及踩过不少坑之后,我把可以运行出来的命令记录下来。这里,最好只改变输出文件夹的根路径,可以放在任何你想放的路径下,但是一些输出的名字这些,最好不要修改,容易出错。另一个需要注意的问题是,需要明确图像有无exif信息可以读取到相机内参,比如焦距这些,如果没有的话,那么相机内参还需要在第一步的时候就进行输入,下面分别进行介绍。
  

2.1 图像exif带相机内参信息

# 首先给一些路径进行定义,方便下面描述,使用时使用自己的实际目录进行替换即可
# DIR_DATA: 图像数据存放路径
# DIR_OUTPUT: 存放输出结果的路径
# DIR_OM: 存放openmvg源码的路径
1. 初始化图像列表
openMVG_main_SfMInit_ImageListing -d DIR_OM/openMVG/src/openMVG/exif/sensor_width_database/sensor_width_camera_database.txt -i DIR_DATA -o DIR_OUTPUT
2. 计算特征
openMVG_main_ComputeFeatures -i DIR_OUTPUT/sfm_data.json -o DIR_OUTPUT
3. 生成图像对
openMVG_main_PairGenerator -i DIR_OUTPUT/sfm_data.json -o DIR_OUTPUT/imgpairs.bin
4. 图像匹配
openMVG_main_ComputeMatches -i DIR_OUTPUT/sfm_data.json -p DIR_OUTPUT/imgpairs.bin -o DIR_OUTPUT/matches.bin
5. 错误匹配点对滤除
openMVG_main_GeometricFilter -i DIR_OUTPUT/sfm_data.json -m DIR_OUTPUT/matches.bin -g f -o DIR_OUTPUT/matches.f.bin
6.1. 全局式SfM
openMVG_main_SfM -s GLOBAL -i DIR_OUTPUT/sfm_data.json -m DIR_OUTPUT/ -o DIR_OUTPUT/out_Global_Reconstruction
6.2. 增量式SfM
openMVG_main_SfM -s INCREMENTAL -i DIR_OUTPUT/sfm_data.json -m DIR_OUTPUT/ -o DIR_OUTPUT/out_Incremental_Reconstruction
7.1. 生成颜色(全局式)
openMVG_main_ComputeSfM_DataColor -i DIR_OUTPUT/out_Global_Reconstruction/sfm_data.bin -o DIR_OUTPUT/out_Global_Reconstruction/sfm_data_colorized.ply
7.2. 生成颜色(增量式)
openMVG_main_ComputeSfM_DataColor -i DIR_OUTPUT/out_Incremental_Reconstruction/sfm_data.bin -o DIR_OUTPUT/out_Incremental_Reconstruction/sfm_data_colorized.ply

  下面是实验数据与最终生成的结果:
在这里插入图片描述
  
在这里插入图片描述
  
  其中,存放最终输出结果的文件夹out_Global_Reconstruction/out_Incremental_Reconstruction下应该会有如下内容:
在这里插入图片描述
  ply文件是点云数据,可以使用cloudcompare或者meshlab可视化查看和编辑,上面的结果图就是用cloudcompare打开的sfm_data_colorized.ply文件。
  

2.2 参数指定输入内参信息

  要输入内参信息,只需在第一步的时候进行修改即可,其他步骤与2.1一致。手动输入内参k的方式是增加-k参数:

1. 初始化图像列表
openMVG_main_SfMInit_ImageListing -d DIR_OM/openMVG/src/openMVG/exif/sensor_width_database/sensor_width_camera_database.txt -i DIR_DATA -o DIR_OUTPUT -k "6432;0;3000;0;6455;2000;0;0;1"

  其中-k参数是由双引号界定由分号分隔的九个值,也就是内参矩阵K,按行主序排列,依次为:

"fx;0;cx;0;fy;cy;0;0;1"

  下面是实验数据与最终生成的结果:
在这里插入图片描述
  
在这里插入图片描述  

3 自动化运行脚本

  逐行运行命令有点太繁琐了,特别是在要跑的场景比较多的时候。于是我编写了一个脚本,可以自动化执行整个流程。如果需要自动化执行多个流程,加个for循环就可以了。脚本编写教程可参考shell/bash脚本命令教程

#!/bin/bash

##################################################### variables ########################################################

# model name
model_name=ortho1_3_112
# sensor db path, change it according to your environment
db_path=../../../workspace/openmvg/openMVG/src/openMVG/exif/sensor_width_database/sensor_width_camera_database.txt
# input images folder
in_img_dir=../imgs/100-130/${model_name}
# output folder
out_dir=./${model_name}
# intrinsic matrix
k="3746.77;0;1988;0;3761.05;1326;0;0;1"
# json path
json_path=${out_dir}/sfm_data.json
# image pairs path
img_pair_path=${out_dir}/imgpairs.bin
# matches path
matches_path=${out_dir}/matches.bin
# refine matches path
refined_path=${out_dir}/matches.f.bin
# output incremental reconstruction folder
out_incremental_dir=${out_dir}/out_Incremental_Reconstruction
# incremental reconstruction model path
incremental_bin_path=${out_incremental_dir}/sfm_data.bin
# color ply path
out_incremental_color_path=${out_incremental_dir}/sfm_data_colorized.ply
# output global reconstruction folder
out_global_dir=${out_dir}/out_Global_Reconstruction
# global reconstruction model path
global_bin_path=${out_global_dir}/sfm_data.bin
# color ply path
out_global_color_path=${out_global_dir}/sfm_data_colorized.ply


##################################################### commands #########################################################

# initial image list
openMVG_main_SfMInit_ImageListing \
      -d ${db_path} \
      -i ${in_img_dir} \
      -o ${out_dir} \
      -k ${k}

wait

# compute features
openMVG_main_ComputeFeatures \
      -i ${json_path} \
      -o ${out_dir}

wait

# generate image pairs
openMVG_main_PairGenerator \
      -i ${json_path} \
      -o ${img_pair_path}

wait

# feature matching
openMVG_main_ComputeMatches \
      -i ${json_path} \
      -p ${img_pair_path} \
      -o ${matches_path}

wait

# geometric filter

openMVG_main_GeometricFilter \
      -i ${json_path} \
      -m ${matches_path} \
      -g f \
      -o ${refined_path}

wait

# incremental reconstruction

openMVG_main_SfM \
      -s INCREMENTAL \
      -i ${json_path} \
      -m ${out_dir} \
      -o ${out_incremental_dir}

wait

# compute color for incremental model

openMVG_main_ComputeSfM_DataColor \
      -i ${incremental_bin_path} \
      -o ${out_incremental_color_path}

wait

# global reconstruction

openMVG_main_SfM \
      -s GLOBAL \
      -i ${json_path} \
      -m ${out_dir} \
      -o ${out_global_dir}

wait

# compute color for incremental model

openMVG_main_ComputeSfM_DataColor \
      -i ${global_bin_path} \
      -o ${out_global_color_path}

猜你喜欢

转载自blog.csdn.net/weixin_44120025/article/details/129191083