Skip to content

Commit 3fac9a0

Browse files
committed
Merge branch 'master' of https://github.com/mapillary/OpenSfM
2 parents 4b95bac + ee951c5 commit 3fac9a0

File tree

2 files changed

+212
-113
lines changed

2 files changed

+212
-113
lines changed

bin/import_colmap

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ from collections import defaultdict
1919
from pathlib import Path
2020
from struct import unpack
2121

22+
import cv2
2223
import matplotlib.pyplot as pl
2324
import numpy as np
2425
from matplotlib import cm
@@ -48,10 +49,10 @@ camera_models = {
4849
}
4950

5051

51-
def compute_and_save_undistorted_reconstruction(reconstruction, tracks_manager, udata):
52+
def compute_and_save_undistorted_reconstruction(reconstruction, tracks_manager, data, udata):
5253
urec = types.Reconstruction()
5354
utracks_manager = pysfm.TracksManager()
54-
undistorted_shots = {}
55+
undistorted_shots = []
5556
for shot in reconstruction.shots.values():
5657
if shot.camera.projection_type == 'perspective':
5758
ucamera = osfm_u.perspective_camera_from_perspective(shot.camera)
@@ -67,7 +68,15 @@ def compute_and_save_undistorted_reconstruction(reconstruction, tracks_manager,
6768
urec.add_shot(ushot)
6869
if tracks_manager:
6970
osfm_u.add_subshot_tracks(tracks_manager, utracks_manager, shot, ushot)
70-
undistorted_shots[shot.id] = ushot
71+
undistorted_shots.append(ushot)
72+
73+
image = data.load_image(shot.id, unchanged=True, anydepth=True)
74+
if image is not None:
75+
max_size = data.config['undistorted_image_max_size']
76+
undistorted = osfm_u.undistort_image(shot, undistorted_shots, image,
77+
cv2.INTER_AREA, max_size)
78+
for k, v in undistorted.items():
79+
udata.save_undistorted_image(k, v)
7180

7281
udata.save_undistorted_reconstruction([urec])
7382
if tracks_manager:
@@ -415,15 +424,17 @@ def import_depthmaps_from_fused_pointcloud(udata, urec, image_ix_to_shot_id, pat
415424
points_seen = read_vis(path_ply.with_suffix('.ply.vis'), image_ix_to_shot_id)
416425

417426
# Project to shots and save as depthmaps
427+
max_size = udata.config['depthmap_resolution']
418428
for shot_id, points_seen_ixs in points_seen.items():
419429
print("Projecting shot {}".format(shot_id))
420430
project_pointcloud_save_depth(udata,
421431
urec,
422432
points[points_seen_ixs],
423-
shot_id)
433+
shot_id,
434+
max_size)
424435

425436

426-
def project_pointcloud_save_depth(udata, urec, points, shot_id, max_sz=1024):
437+
def project_pointcloud_save_depth(udata, urec, points, shot_id, max_sz):
427438
# Project points to the undistorted image
428439
shot = urec.shots[shot_id]
429440
w, h = shot.camera.width, shot.camera.height
@@ -453,23 +464,24 @@ def project_pointcloud_save_depth(udata, urec, points, shot_id, max_sz=1024):
453464
distances = np.linalg.norm(points - shot.pose.get_origin(), axis=1)
454465
viewing_angles = np.arctan2(np.linalg.norm(points_2d, axis=1), shot.camera.focal)
455466
depths = distances * np.cos(viewing_angles)
467+
depths[depths > udata.config['depthmap_max_depth']] = 0
456468

457469
# Create depth image
458470
depth_image = np.zeros([h, w])
459471
depth_image[pixel_coords[:, 1], pixel_coords[:, 0]] = depths[mask]
460472

461473
# Save numpy
462-
filepath = Path(udata._depthmap_file(shot_id, 'fused.npz'))
474+
filepath = Path(udata._depthmap_file(shot_id, 'clean.npz'))
463475
filepath.parent.mkdir(exist_ok=True, parents=True)
464-
np.savez_compressed(filepath, points=depth_image)
476+
np.savez_compressed(filepath, depth=depth_image, plane=np.zeros(1), score=np.zeros(1))
465477

466478
# Save jpg for visualization
467479
import matplotlib.pyplot as plt
468480
fig = plt.figure()
469481
rgb, sm = depth_colormap(depth_image)
470482
plt.imshow(rgb)
471483
small_colorbar(plt.gca(), mappable=sm)
472-
filepath = Path(udata._depthmap_file(shot_id, 'fused_viz.png'))
484+
filepath = Path(udata.data_path) / 'plot_depthmaps' / '{}.png'.format(shot_id)
473485
filepath.parent.mkdir(exist_ok=True, parents=True)
474486
plt.savefig(filepath, dpi=300)
475487
plt.close(fig)
@@ -486,8 +498,7 @@ def quaternion_to_angle_axis(quaternion):
486498
angle = 2 * math.acos(qw)
487499
return [angle * x, angle * y, angle * z]
488500

489-
490-
if __name__ == "__main__":
501+
def main():
491502
parser = argparse.ArgumentParser(
492503
description='Convert COLMAP database to OpenSfM dataset')
493504
parser.add_argument('database', help='path to the database to be processed')
@@ -503,12 +514,24 @@ if __name__ == "__main__":
503514
if not images_path.exists():
504515
os.symlink(args.images, images_path, target_is_directory=True)
505516

517+
# Copy the config if this is an colmap export of an opensfm export
518+
if p_db.parent.name == 'colmap_export' and not (export_folder/'config.yaml').exists():
519+
os.symlink(p_db.parent.parent / 'config.yaml', export_folder / 'config.yaml')
520+
506521
data = dataset.DataSet(export_folder)
507522
db = sqlite3.connect(p_db.as_posix())
508523
camera_map, image_map = import_cameras_images(db, data)
524+
525+
# Create image_list.txt
526+
with open(export_folder / 'image_list.txt', 'w') as f:
527+
for image_id, (filename, camera_id) in image_map.items():
528+
f.write('images/' + filename + '\n')
529+
data._load_image_list()
530+
509531
keypoints = import_features(db, data, image_map, camera_map)
510532
import_matches(db, data, image_map)
511533

534+
512535
rec_cameras = p_db.parent / 'cameras.bin'
513536
rec_points = p_db.parent / 'points3D.bin'
514537
rec_images = p_db.parent / 'images.bin'
@@ -529,7 +552,7 @@ if __name__ == "__main__":
529552

530553
# Save undistorted reconstruction as well
531554
udata = dataset.UndistortedDataSet(data, 'undistorted')
532-
urec = compute_and_save_undistorted_reconstruction(reconstruction, tracks_manager, udata)
555+
urec = compute_and_save_undistorted_reconstruction(reconstruction, tracks_manager, data, udata)
533556

534557
# Project colmap's fused pointcloud to save depths in opensfm format
535558
path_ply = p_db.parent / 'dense/fused.ply'
@@ -544,6 +567,10 @@ if __name__ == "__main__":
544567
print("Not importing dense reconstruction: Didn't find {}".format(path_ply))
545568

546569
else:
547-
print("Didn't find reconstruction files in text format")
570+
print("Didn't find some of the reconstruction files at {}".format(p_db.parent))
548571

549572
db.close()
573+
574+
575+
if __name__ == "__main__":
576+
main()

0 commit comments

Comments
 (0)