The latest OpenMVG compilation, installation, and command-by-command incremental and global SfM tutorials (automated running scripts are attached at the end of the article)

  openmvg is a lightweight SfM open source library that can be run step by step. It implements both incremental and global algorithms.

Document address: https://openmvg.readthedocs.io/en/latest/
github homepage address: https://github.com/openMVG/openMVG
insert image description here

  

1 Compile and install

  The installation of openmvg is relatively simple, the first is to install dependencies:

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

  Then clone the openmvg source code:

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

  Finally, use cmake to compile and install:

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

  There may be errors caused by too low eigen version during compilation:

/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);
   ^~~~~~~~~~~~~

  Generally, you only need to upgrade its version to 3.4.0. The command to check the eigen version is:

pkg-config --modversion eigen3

  For the tutorial on reinstalling eigen, please refer to: ubuntu reinstalling/upgrading eigen tutorial
  

2 run command

  The official instructions of openmvg talk about how to run SfM, including using a script to run a line of commands (only when the image exif has internal reference information), and how to run it step by step, you can refer to here . But what needs to be explained here is that the code of openmvg has been modified later, but the usage documentation has not been completely updated. Therefore, if you just run according to the documentation, or many other tutorials (maybe just copying official documents or older ones), you may encounter errors (many examples cannot be run). After encountering some unknown error reports and stepping on a lot of pitfalls, I recorded the commands that can be run. Here, it is best to only change the root path of the output folder, which can be placed in any path you want, but it is best not to modify the names of some outputs, as it is easy to make mistakes. Another issue that needs attention is that it needs to be clear whether the image has exif information that can be read into the camera’s internal parameters, such as focal length. If not, then the camera’s internal parameters need to be input in the first step, which will be introduced separately below.
  

2.1 Image exif with camera internal reference information

# 首先给一些路径进行定义,方便下面描述,使用时使用自己的实际目录进行替换即可
# 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

  The following is the experimental data and the final generated results:
insert image description here
  
insert image description here
  
  Among them, the folder out_Global_Reconstruction/ out_Incremental_Reconstructionunder which the final output results are stored should have the following content:
insert image description here
  The ply file is point cloud data, which can be viewed and edited visually with cloudcompare or meshlab. The above result picture is the sfm_data_colorized.ply file opened with cloudcompare.
  

2.2 Parameter specification input internal reference information

  To enter the internal reference information, you only need to modify it in the first step, and the other steps are consistent with 2.1. The way to manually enter the internal parameter k is to add -kparameters:

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"

  The -kparameters are nine values ​​delimited by double quotes and separated by semicolons, that is, the internal reference matrix K, arranged in row-major order, as follows:

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

  The following is the experimental data and the final generated results:
insert image description here
  
insert image description here  

3 Automatically run scripts

  Running commands line by line is a bit too cumbersome, especially when there are many scenarios to run. So I wrote a script that automates the entire process. If you need to automate multiple processes, just add a for loop. For the script writing tutorial, please refer to the shell/bash script command tutorial .

#!/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}

Guess you like

Origin blog.csdn.net/weixin_44120025/article/details/129191083
SFM