forked from wangyida/hineus
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun_colmap.py
More file actions
155 lines (136 loc) · 4.53 KB
/
run_colmap.py
File metadata and controls
155 lines (136 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""
COLMAP Wrapper for Structure from Motion
This module provides a high-level interface to run COLMAP pipeline including
feature extraction, matching, sparse reconstruction, and dense reconstruction.
"""
import argparse
import os
import subprocess
from pathlib import Path
from typing import Optional
import numpy as np
from skimage.io import imread
from colmap.database import COLMAPDatabase
from colmap.read_write_model import CAMERA_MODEL_NAMES
def run_sfm(
image_dir: str,
project_dir: str,
same_camera: bool = False,
colmap_path: str = "$HOME/code/colmap/build/src/exe/colmap"
) -> None:
"""
Run complete COLMAP Structure from Motion pipeline.
Args:
image_dir: Path to directory containing images
project_dir: Output directory for COLMAP project
same_camera: If True, use same camera for all images
colmap_path: Path to COLMAP executable
"""
Path(project_dir).mkdir(exist_ok=True, parents=True)
# create database for all images
db = COLMAPDatabase.connect(f'{project_dir}/database.db')
db.create_tables()
# add images
img_dir = Path(image_dir)
img_fns = []
for pattern in ['*.jpg', '*.png', '*.PNG', '*.JPG']:
img_fns += [fn for fn in img_dir.glob(pattern)]
img_fns = sorted(img_fns)
global_cam_id = None
for k, img_fn in enumerate(img_fns):
img = imread(img_fn)
h, w, _ = img.shape
focal = np.sqrt(h**2 + w**2) # guess a focal here
if same_camera:
if k == 0:
global_cam_id = db.add_camera(
CAMERA_MODEL_NAMES['SIMPLE_PINHOLE'].model_id,
float(w),
float(h),
np.array([focal, w / 2, h / 2], np.float64),
prior_focal_length=True)
db.add_image(img_fn.name, global_cam_id)
else:
cam_id = db.add_camera(
CAMERA_MODEL_NAMES['SIMPLE_PINHOLE'].model_id,
float(w),
float(h),
np.array([focal, w / 2, h / 2], np.float64),
prior_focal_length=True)
db.add_image(img_fn.name, cam_id)
db.commit()
db.close()
# feature extraction
cmd = [
colmap_path, 'feature_extractor', '--database_path',
f'{project_dir}/database.db', '--image_path', f'{image_dir}'
]
print(' '.join(cmd))
subprocess.run(cmd, check=True)
# feature matching
cmd = [
colmap_path, 'exhaustive_matcher', '--database_path',
f'{project_dir}/database.db'
]
print(' '.join(cmd))
subprocess.run(cmd, check=True)
# SfM
Path(f'{project_dir}/sparse').mkdir(exist_ok=True, parents=True)
cmd = [
colmap_path, 'mapper', '--database_path', f'{project_dir}/database.db',
'--image_path', f'{image_dir}', '--output_path',
f'{project_dir}/sparse'
]
print(' '.join(cmd))
subprocess.run(cmd, check=True)
# dense reconstruction
Path(f'{project_dir}/dense').mkdir(exist_ok=True, parents=True)
cmd = [
colmap_path, 'image_undistorter', '--image_path', f'{image_dir}',
'--input_path', f'{project_dir}/sparse/0', '--output_path',
f'{project_dir}/dense'
]
print(' '.join(cmd))
subprocess.run(cmd, check=True)
cmd = [
colmap_path, 'patch_match_stereo', '--workspace_path',
f'{project_dir}/dense'
]
print(' '.join(cmd))
subprocess.run(cmd, check=True)
cmd = [
str(colmap_path),
'stereo_fusion',
'--workspace_path',
f'{project_dir}/dense',
'--workspace_format',
'COLMAP',
'--input_type',
'geometric',
'--output_path',
f'{project_dir}/points.ply',
# '--StereoFusion.num_threads','14',
'--StereoFusion.check_num_images',
'5',
# '--StereoFusion.cache_size','14',
# '--StereoFusion.use_cache','1',
# '--StereoFusion.max_image_size','1024'
]
print(' '.join(cmd))
subprocess.run(cmd, check=True)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--project_dir', type=str)
parser.add_argument('--colmap', type=str)
parser.add_argument('--same_camera',
action='store_true',
default=False,
dest='same_camera')
args = parser.parse_args()
image_dir = f'{args.project_dir}/images'
run_sfm(image_dir,
args.project_dir,
args.same_camera,
colmap_path=args.colmap)
if __name__ == "__main__":
main()