prepare_images.py 4.91 KB
Newer Older
Clément Pinard's avatar
Clément Pinard committed
1
2
3
from pyproj import Proj
from edit_exif import get_gps_location
import numpy as np
4
import pandas as pd
Clément Pinard's avatar
Clément Pinard committed
5
6
7
8
import rawpy
import imageio
import generate_sky_masks as gsm
import videos_to_colmap as v2c
Clément Pinard's avatar
Clément Pinard committed
9
import colmap_util as ci
Clément Pinard's avatar
Clément Pinard committed
10
11


12
def extract_gps_and_path(individual_pictures, colmap_img_root, system, centroid=None, **env):
Clément Pinard's avatar
Clément Pinard committed
13
14
    proj = Proj(system)
    georef_list = []
15
16
    for img in individual_pictures:
        gps = get_gps_location(colmap_img_root / img)
Clément Pinard's avatar
Clément Pinard committed
17
18
19
20
21
22
23
24
        if gps is not None:
            lat, lng, alt = gps
            x, y = proj(lng, lat)
            if centroid is None:
                centroid = np.array([x, y, alt])
            x -= centroid[0]
            y -= centroid[1]
            alt -= centroid[2]
25
            georef_list.append("{} {} {} {}\n".format(img, x, y, alt))
Clément Pinard's avatar
Clément Pinard committed
26
27
28
    return georef_list, centroid


29
30
def extract_pictures_to_workspace(input_folder, colmap_img_root, individual_pictures_path, workspace, colmap,
                                  raw_ext, pic_ext, more_sift_features, generic_model, **env):
Clément Pinard's avatar
Clément Pinard committed
31
    picture_folder = input_folder / "Pictures"
32
33
    pictures = []
    raw_files = sum((list(picture_folder.walkfiles('*{}'.format(ext))) for ext in raw_ext), [])
Clément Pinard's avatar
Clément Pinard committed
34
35
    for raw in raw_files:
        if not any((raw.stripext() + ext).isfile() for ext in pic_ext):
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
            converted_pic_path = raw.relpath(picture_folder).stripext() + '.jpg'
            if not converted_pic_path.isfile():
                raw_array = rawpy.imread(raw)
                rgb = raw_array.postprocess()
                dst = individual_pictures_path / converted_pic_path
                dst.parent.makedirs_p()
                imageio.imsave(dst, rgb)
            pictures.append(converted_pic_path)
    normal_files = sum((list(picture_folder.walkfiles('*{}'.format(ext))) for ext in pic_ext), [])
    for file in normal_files:
        pic_path = file.relpath(picture_folder)
        if not pic_path.isfile():
            dst = individual_pictures_path / pic_path
            dst.parent.makedirs_p()
            file.copy(dst)
        pictures.append(colmap_img_root.relpathto(individual_pictures_path) / pic_path)
    gsm.process_folder(folder_to_process=individual_pictures_path, colmap_img_root=colmap_img_root, pic_ext=pic_ext, **env)
    with open(picture_folder / "individual_pictures.txt", 'w') as f:
        f.write("\n".join(pictures) + "\n")
    colmap.extract_features(per_sub_folder=True, model=generic_model,
                            image_list=picture_folder/"individual_pictures.txt", more=more_sift_features)
    return pictures
Clément Pinard's avatar
Clément Pinard committed
58
59
60
61


def extract_videos_to_workspace(video_path, video_frame_list_thorough, georef_frames_list, **env):
    existing_georef, env["centroid"] = extract_gps_and_path(**env)
62
63
64
65
66
67
68
69
70
71
    if env["full_metadata"] is None:
        env["full_metadata"] = env["workspace"] / "full_metadata.csv"
    if env["full_metadata"].isfile():
        existing_metadata = pd.read_csv(env["full_metadata"])
    else:
        existing_metadata = None
    path_lists, extracted_video_folders, full_metadata = v2c.process_video_folder(output_video_folder=video_path,
                                                                                  existing_georef=existing_georef,
                                                                                  existing_metadata=existing_metadata,
                                                                                  **env)
Clément Pinard's avatar
Clément Pinard committed
72
    if path_lists is not None:
73
        full_metadata.to_csv(env["full_metadata"])
Clément Pinard's avatar
Clément Pinard committed
74
75
76
77
78
        with open(video_frame_list_thorough, "w") as f:
            f.write("\n".join(path_lists["thorough"]["frames"]))
        with open(georef_frames_list, "w") as f:
            f.write("\n".join(existing_georef) + "\n")
            f.write("\n".join(path_lists["thorough"]["georef"]) + "\n")
79
        for v, video_folder in extracted_video_folders.items():
Clément Pinard's avatar
Clément Pinard committed
80
81
82
83
84
85
86
87
88
89
90
            with open(video_folder / "lowfps.txt", "w") as f:
                f.write("\n".join(path_lists[v]["frames_lowfps"]) + "\n")
            with open(video_folder / "georef.txt", "w") as f:
                f.write("\n".join(existing_georef) + "\n")
                f.write("\n".join(path_lists["thorough"]["georef"]) + "\n")
                f.write("\n".join(path_lists[v]["georef_lowfps"]) + "\n")
            for j, l in enumerate(path_lists[v]["frames_full"]):
                with open(video_folder / "full_chunk_{}.txt".format(j), "w") as f:
                    f.write("\n".join(l) + "\n")
    gsm.process_folder(folder_to_process=video_path, **env)
    return extracted_video_folders
Clément Pinard's avatar
Clément Pinard committed
91
92
93
94
95
96


def choose_biggest_model(dir):
    colmap_model_dirs = dir.dirs("[0-9]*")
    model_sizes = [len(ci.read_model.read_images_binary(d/"images.bin")) for d in colmap_model_dirs]
    return colmap_model_dirs[model_sizes.index(max((model_sizes)))]
97
98
99
100
101
102
103
104
105
106
107


def group_pics_by_folder(pictures):
    result = {}
    for p in pictures:
        key = p.parent
        if p.parent not in result.keys():
            result[key] = [p]
        else:
            result[key].append(p)
    return result