Skip to content

Commit

Permalink
scripts: add model_aligner to COLMAP SfM pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
cdcseacave committed Mar 6, 2024
1 parent 6803f21 commit 2ccd08e
Showing 1 changed file with 54 additions and 40 deletions.
94 changes: 54 additions & 40 deletions scripts/python/MvgMvsPipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[--12 12 [12 ...]] [--13 13 [13 ...]] [--14 14 [14 ...]]
[--15 15 [15 ...]] [--16 16 [16 ...]] [--17 17 [17 ...]]
[--18 18 [18 ...]] [--19 19 [19 ...]] [--20 20 [20 ...]]
[--21 21 [21 ...]] [--22 22 [22 ...]]
[--21 21 [21 ...]] [--22 22 [22 ...]] [--23 23 [23 ...]]
input_dir output_dir
Photogrammetry reconstruction with these steps:
Expand All @@ -32,14 +32,15 @@
12. Feature Extractor colmap
13. Exhaustive Matcher colmap
14. Mapper colmap
15. Image Undistorter colmap
16. Export to openMVS InterfaceCOLMAP
17. Densify point-cloud DensifyPointCloud
18. Reconstruct the mesh ReconstructMesh
19. Refine the mesh RefineMesh
20. Texture the mesh TextureMesh
21. Estimate disparity-maps DensifyPointCloud
22. Fuse disparity-maps DensifyPointCloud
15. Model Aligner colmap
16. Image Undistorter colmap
17. Export to openMVS InterfaceCOLMAP
18. Densify point-cloud DensifyPointCloud
19. Reconstruct the mesh ReconstructMesh
20. Refine the mesh RefineMesh
21. Texture the mesh TextureMesh
22. Estimate disparity-maps DensifyPointCloud
23. Fuse disparity-maps DensifyPointCloud
positional arguments:
input_dir the directory which contains the pictures set.
Expand All @@ -49,22 +50,22 @@
-h, --help show this help message and exit
--steps STEPS [STEPS ...] steps to process
--preset PRESET steps list preset in
SEQUENTIAL = [0, 1, 2, 3, 4, 5, 11, 17, 18, 19, 20]
GLOBAL = [0, 1, 2, 3, 4, 6, 11, 17, 18, 19, 20]
SEQUENTIAL = [0, 1, 2, 3, 4, 5, 11, 18, 19, 20, 21]
GLOBAL = [0, 1, 2, 3, 4, 6, 11, 18, 19, 20, 21]
MVG_SEQ = [0, 1, 2, 3, 4, 5, 7, 8, 9, 11]
MVG_GLOBAL = [0, 1, 2, 3, 4, 6, 7, 8, 9, 11]
COLMAP_MVS = [12, 13, 14, 15, 16, 17, 18, 19, 20]
COLMAP = [12, 13, 14, 15, 16]
MVS = [17, 18, 19, 20]
MVS_SGM = [21, 22]
COLMAP_MVS = [12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
COLMAP = [12, 13, 14, 15, 16, 17]
MVS = [18, 19, 20, 21]
MVS_SGM = [22, 23]
default : SEQUENTIAL
Passthrough:
Option to be passed to command lines (remove - in front of option names)
e.g. --1 p ULTRA to use the ULTRA preset in openMVG_main_ComputeFeatures
For example, running the script
[MvgMvsPipeline.py input_dir output_dir --steps 0 1 2 3 4 5 11 17 18 20 --1 p HIGH n 8 --3 n HNSWL2]
[--steps 0 1 2 3 4 5 11 17 18 20] runs only the desired steps
[MvgMvsPipeline.py input_dir output_dir --steps 0 1 2 3 4 5 11 18 19 21 --1 p HIGH n 8 --3 n HNSWL2]
[--steps 0 1 2 3 4 5 11 18 19 21] runs only the desired steps
[--1 p HIGH n 8] where --1 refer to openMVG_main_ComputeFeatures,
p refers to describerPreset option and set to HIGH, and n refers
to numThreads and set to 8. The second step (Compute matches),
Expand Down Expand Up @@ -140,14 +141,14 @@ def find(afile):
if sys.platform.startswith('win'):
COLMAP_BIN += ".bat"

PRESET = {'SEQUENTIAL': [0, 1, 2, 3, 4, 5, 11, 17, 18, 19, 20],
'GLOBAL': [0, 1, 2, 3, 4, 6, 11, 17, 18, 19, 20],
PRESET = {'SEQUENTIAL': [0, 1, 2, 3, 4, 5, 11, 18, 19, 20, 21],
'GLOBAL': [0, 1, 2, 3, 4, 6, 11, 18, 19, 20, 21],
'MVG_SEQ': [0, 1, 2, 3, 4, 5, 7, 8, 9, 11],
'MVG_GLOBAL': [0, 1, 2, 3, 4, 6, 7, 8, 9, 11],
'COLMAP_MVS': [12, 13, 14, 15, 16, 17, 18, 19, 20],
'COLMAP': [12, 13, 14, 15, 16],
'MVS': [17, 18, 19, 20],
'MVS_SGM': [21, 22]}
'COLMAP_MVS': [12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
'COLMAP': [12, 13, 14, 15, 16, 17],
'MVS': [18, 19, 20, 21],
'MVS_SGM': [22, 23]}

PRESET_DEFAULT = 'SEQUENTIAL'

Expand Down Expand Up @@ -246,35 +247,38 @@ def __init__(self):
["-i", "%reconstruction_dir%"+FOLDER_DELIM+"sfm_data.bin", "-o", "%mvs_dir%"+FOLDER_DELIM+"scene.mvs", "-d", "%mvs_dir%"+FOLDER_DELIM+"images"]],
["Feature Extractor", # 12
COLMAP_BIN,
["feature_extractor", "--database_path", "%matches_dir%"+FOLDER_DELIM+"database.db", "--image_path", "%input_dir%"]],
["feature_extractor", "--database_path", "%matches_dir%"+FOLDER_DELIM+"database.db", "--image_path", "%input_dir%", "--ImageReader.single_camera=1", "--ImageReader.camera_model=OPENCV"]],
["Exhaustive Matcher", # 13
COLMAP_BIN,
["exhaustive_matcher", "--database_path", "%matches_dir%"+FOLDER_DELIM+"database.db"]],
["Mapper", # 14
COLMAP_BIN,
["mapper", "--database_path", "%matches_dir%"+FOLDER_DELIM+"database.db", "--image_path", "%input_dir%", "--output_path", "%reconstruction_dir%"]],
["Image Undistorter", # 15
["Model Aligner", # 15
COLMAP_BIN,
["model_aligner", "--input_path", "%reconstruction_dir%"+FOLDER_DELIM+"0", "--database_path", "%matches_dir%"+FOLDER_DELIM+"database.db", "--output_path", "%reconstruction_dir%"+FOLDER_DELIM+"0", "--ref_is_gps=1", "--robust_alignment_max_error=2.0", "--alignment_type=enu", "--transform_path", "%reconstruction_dir%"+FOLDER_DELIM+"transform.txt"]],
["Image Undistorter", # 16
COLMAP_BIN,
["image_undistorter", "--image_path", "%input_dir%", "--input_path", "%reconstruction_dir%"+FOLDER_DELIM+"0", "--output_path", "%reconstruction_dir%"+FOLDER_DELIM+"dense", "--output_type", "COLMAP"]],
["Export to openMVS", # 16
["Export to openMVS", # 17
os.path.join(OPENMVS_BIN, "InterfaceCOLMAP"),
["-i", "%reconstruction_dir%"+FOLDER_DELIM+"dense", "-o", "scene.mvs", "--image-folder", "%reconstruction_dir%"+FOLDER_DELIM+"dense"+FOLDER_DELIM+"images", "-w", "\"%mvs_dir%\""]],
["Densify point cloud", # 17
["Densify point cloud", # 18
os.path.join(OPENMVS_BIN, "DensifyPointCloud"),
["scene.mvs", "--dense-config-file", "Densify.ini", "--resolution-level", "1", "--number-views", "8", "-w", "\"%mvs_dir%\""]],
["Reconstruct the mesh", # 18
["Reconstruct the mesh", # 19
os.path.join(OPENMVS_BIN, "ReconstructMesh"),
["scene_dense.mvs", "-p", "scene_dense.ply", "-w", "\"%mvs_dir%\""]],
["Refine the mesh", # 19
["Refine the mesh", # 20
os.path.join(OPENMVS_BIN, "RefineMesh"),
["scene_dense.mvs", "-m", "scene_dense_mesh.ply", "-o", "scene_dense_mesh_refine.mvs", "--scales", "1", "--gradient-step", "25.05", "-w", "\"%mvs_dir%\""]],
["Texture the mesh", # 20
["Texture the mesh", # 21
os.path.join(OPENMVS_BIN, "TextureMesh"),
["scene_dense.mvs", "-m", "scene_dense_mesh_refine.ply", "--decimate", "0.5", "-w", "\"%mvs_dir%\""]],
["Estimate disparity-maps", # 21
["Estimate disparity-maps", # 22
os.path.join(OPENMVS_BIN, "DensifyPointCloud"),
["scene.mvs", "--dense-config-file", "Densify.ini", "--fusion-mode", "-1", "-w", "\"%mvs_dir%\""]],
["Fuse disparity-maps", # 22
["Fuse disparity-maps", # 23
os.path.join(OPENMVS_BIN, "DensifyPointCloud"),
["scene.mvs", "--dense-config-file", "Densify.ini", "--fusion-mode", "-2", "-w", "\"%mvs_dir%\""]]
]
Expand Down Expand Up @@ -388,11 +392,11 @@ def mkdir_ine(dirname):
STEPS.replace_opt(4, FOLDER_DELIM+"matches.f.bin", FOLDER_DELIM+"matches.e.bin")
STEPS[4].opt.extend(["-g", "e"])

if 20 in CONF.steps: # TextureMesh
if 19 not in CONF.steps: # RefineMesh
if 21 in CONF.steps: # TextureMesh
if 20 not in CONF.steps: # RefineMesh
# RefineMesh step is not run, use ReconstructMesh output
STEPS.replace_opt(20, "scene_dense_mesh_refine.ply", "scene_dense_mesh.ply")
STEPS.replace_opt(20, "scene_dense_mesh_refine_texture.mvs", "scene_dense_mesh_texture.mvs")
STEPS.replace_opt(21, "scene_dense_mesh_refine.ply", "scene_dense_mesh.ply")
STEPS.replace_opt(21, "scene_dense_mesh_refine_texture.mvs", "scene_dense_mesh_texture.mvs")

for cstep in CONF.steps:
printout("#%i. %s" % (cstep, STEPS[cstep].info), effect=INVERSE)
Expand Down Expand Up @@ -423,12 +427,22 @@ def mkdir_ine(dirname):
if not DEBUG:
# Launch the current step
try:
pStep = subprocess.Popen(cmdline)
pStep.wait()
if pStep.returncode != 0:
if subprocess.run(cmdline, check=True).returncode != 0:
break
except subprocess.CalledProcessError:
# check if this COLMAP model-aligner step, retry using plane alignment instead of GPS
if cstep == 15 and "--ref_is_gps=1" in STEPS[cstep].opt:
printout("# Retry COLMAP model-aligner step using plane alignment instead of GPS", effect=INVERSE)
STEPS.replace_opt(15, "--ref_is_gps=1", "--ref_is_gps=0")
STEPS.replace_opt(15, "--alignment_type=enu", "--alignment_type=plane")
cmdline = [STEPS[cstep].cmd] + STEPS[cstep].opt + opt
print('Cmd: ' + ' '.join(cmdline))
if subprocess.run(cmdline, check=True).returncode != 0:
break
else:
sys.exit('\r\nProcess failed at step %i' % cstep)
except KeyboardInterrupt:
sys.exit('\r\nProcess canceled by user, all files remains')
sys.exit('\r\nProcess canceled by user at step %i, all files remains' % cstep)
else:
print('\t'.join(cmdline))

Expand Down

0 comments on commit 2ccd08e

Please sign in to comment.