picture_localization.py 5.4 KB
Newer Older
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
from wrappers import Colmap, ETH3D
from cli_utils import set_new_images_arparser, print_step, get_matrix
from video_localization import generate_GT_individual_pictures
import meshlab_xml_writer as mxw
import prepare_images as pi
import prepare_workspace as pw
import pcl_util
import numpy as np


def main():
    args = set_new_images_arparser().parse_args()
    env = vars(args)
    args.workspace = args.workspace.abspath()
    pw.prepare_workspace(args.workspace, env)
    colmap = Colmap(db=env["thorough_db"],
                    image_path=env["colmap_img_root"],
                    mask_path=env["mask_path"],
                    dense_workspace=env["dense_workspace"],
                    binary=args.colmap,
                    verbose=args.verbose,
                    logfile=args.log)
    env["colmap"] = colmap
    eth3d = ETH3D(args.eth3d, args.raw_output_folder / "Images", args.max_occlusion_depth,
                  verbose=args.verbose, logfile=args.log, splat_radius=args.eth3d_splat_radius)
    env["eth3d"] = eth3d
    env["videos_list"] = sum((list((args.input_folder/"Videos").walkfiles('*{}'.format(ext))) for ext in args.vid_ext), [])
    no_gt_folder = args.input_folder/"Videos"/"no_groundtruth"
    if no_gt_folder.isdir():
        env["videos_to_localize"] = [v for v in env["videos_list"] if not str(v).startswith(no_gt_folder)]

    i = 1
    print_step(i, "Pictures preparation")
Clément Pinard's avatar
Clément Pinard committed
34
    env["individual_pictures"] = pi.extract_pictures_to_workspace(**env)
35

Clément Pinard's avatar
Clément Pinard committed
36
37
38
39
40
41
42
43
44
45
46
47
48
    i += 1
    print_step(i, "Add new pictures to COLMAP thorough model")
    colmap.db = env["thorough_db"]
    colmap.match(method="vocab_tree", vocab_tree=env["indexed_vocab_tree"], max_num_matches=env["max_num_matches"])
    extended_georef = env["georef_recon"] + "_extended"
    extended_georef.makedirs_p()
    if args.map_new_images:
        colmap.map(input=env["georef_recon"], output=extended_georef)
    else:
        colmap.register_images(input=env["georef_recon"], output=extended_georef)
    colmap.adjust_bundle(extended_georef, extended_georef,
                         num_iter=args.bundle_adjuster_steps, refine_extra_params=True)
    colmap.merge_models(output=env["georef_full_recon"], input1=env["georef_full_recon"], input2=extended_georef)
49

Clément Pinard's avatar
Clément Pinard committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    if env["rebuild_occlusion_mesh"]:
        i += 1
        print_step(i, "Full reconstruction point cloud densificitation with new images")
        colmap.undistort(input=env["georef_full_recon"])
        # This step should be fast since everything else than new images is already computed
        colmap.dense_stereo(min_depth=env["stereo_min_depth"], max_depth=env["stereo_max_depth"])
        colmap.stereo_fusion(output=env["georefrecon_ply"])
        if args.inspect_dataset:
            georef_mlp = env["georef_full_recon"]/"georef_recon.mlp"
            mxw.create_project(georef_mlp, [env["georefrecon_ply"]])
            colmap.export_model(output=env["georef_full_recon"],
                                input=env["georef_full_recon"],
                                output_type="TXT")
            eth3d.inspect_dataset(scan_meshlab=georef_mlp,
                                  colmap_model=env["georef_full_recon"],
                                  image_path=env["colmap_img_root"])
            eth3d.inspect_dataset(scan_meshlab=env["aligned_mlp"],
                                  colmap_model=env["georef_full_recon"],
                                  image_path=env["colmap_img_root"])
69

Clément Pinard's avatar
Clément Pinard committed
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
        i += 1
        print_step(i, "Occlusion Mesh re-computing")
        '''combine the MLP file into a single ply file. We need the normals for the splats'''
        if args.normals_method == "radius":
            eth3d.compute_normals(env["with_normals_path"], env["aligned_mlp"], neighbor_radius=args.normals_radius)
        else:
            eth3d.compute_normals(env["with_normals_path"], env["aligned_mlp"], neighbor_count=args.normals_neighbours)
        '''Create vis file that will tell by what images each point can be seen. We transfer this knowledge from georefrecon
        to the Lidar model'''
        env["global_registration_matrix"] = get_matrix(env["matrix_path"])
        scale = np.linalg.norm(env["global_registration_matrix"][:3, :3], ord=2)
        with_normals_subsampled = env["with_normals_path"].stripext() + "_subsampled.ply"
        pcl_util.create_vis_file(env["georefrecon_ply"], env["with_normals_path"],
                                 resolution=args.mesh_resolution / scale,
                                 output=with_normals_subsampled)
        '''Compute the occlusion mesh by fooling COLMAP into thinking the lidar point cloud was made with colmap'''
        colmap.delaunay_mesh(env["occlusion_ply"], input_ply=with_normals_subsampled)
        if args.splats:
            eth3d.create_splats(env["splats_ply"], with_normals_subsampled,
                                env["occlusion_ply"], env["splat_threshold"] / scale,
                                env["max_splat_size"])
91
92
93
94

    i += 1
    if i not in args.skip_step:
        print_step(i, "Groud Truth generation")
Clément Pinard's avatar
Clément Pinard committed
95
        by_folder = pi.group_pics_by_folder(env["individual_pictures"])
96
97
98
99
100
101
102
103
104
        for folder, pic_list in by_folder.items():
            generate_GT_individual_pictures(input_colmap_model=env["georef_full_recon"],
                                            individual_pictures=pic_list,
                                            relpath=folder,
                                            step_index=i, **env)


if __name__ == '__main__':
    main()