anafi_metadata.py 4.02 KB
Newer Older
Clement Pinard's avatar
Clement Pinard committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import numpy as np
from scipy import integrate


def extrapolate_position(speeds, timestamps, initial_position, final_position):
    trapz_x = integrate.cumtrapz(speeds[:, 0], timestamps, initial=0)
    trapz_y = integrate.cumtrapz(speeds[:, 1], timestamps, initial=0)
    trapz_z = integrate.cumtrapz(speeds[:, 2], timestamps, initial=0)
    trapz = np.stack([trapz_x, trapz_y, trapz_z], axis=-1)
    if initial_position is None and final_position is None:
        return trapz
    elif initial_position is not None and final_position is None:
        return trapz + initial_position
    elif initial_position is None and final_position is not None:
        return trapz + final_position - trapz[-1]
    else:
        interp = np.linspace(0, final_position - trapz[-1], speeds.shape[0])
        return trapz + interp


Clément Pinard's avatar
Clément Pinard committed
22
def preprocess_metadata(metadata, proj):
Clement Pinard's avatar
Clement Pinard committed
23
24
25
26
    def lambda_fun(x):
        return pd.Series(proj(*x), index=["x", "y"])
    position_xy = metadata[["location_longitude", "location_latitude"]].apply(lambda_fun, axis=1)
    metadata = metadata.join(position_xy)
nicolas's avatar
nicolas committed
27
    metadata["z"] = metadata["location_altitude"]
Clement Pinard's avatar
Clement Pinard committed
28
29
30
31
    # Extrapolate position from speed and previous frames

    speed = metadata[["speed_east", "speed_north", "speed_down"]].values * np.array([1, 1, -1])
    timestamps = metadata["time"].values * 1e-6
nicolas's avatar
nicolas committed
32
    positions = metadata[["x", "y", "z"]].values
Clément Pinard's avatar
Clément Pinard committed
33
    if metadata["location_valid"].unique().tolist() == [False]:
Clement Pinard's avatar
Clement Pinard committed
34
35
36
37
38
39
40
41
42
        metadata["indoor"] = True
        positions = extrapolate_position(speed, timestamps, None, None)
    else:
        metadata["indoor"] = False
        if 0 in metadata["location_valid"].unique():
            location_validity = metadata["location_valid"].diff()
            invalidity_start = location_validity.index[location_validity == -1].tolist()
            validity_start = location_validity.index[location_validity == 1].tolist()

43
            if not metadata["location_valid"].iloc[0]:
Clement Pinard's avatar
Clement Pinard committed
44
                end = validity_start.pop(0)
Clément Pinard's avatar
Clément Pinard committed
45
                positions[:end] = extrapolate_position(speed[:end], timestamps[:end], None, positions[end])
46
            if not metadata["location_valid"].iloc[-1]:
Clement Pinard's avatar
Clement Pinard committed
47
48
49
50
                start = invalidity_start.pop(-1) - 1
                positions[start:] = extrapolate_position(speed[start:], timestamps[start:], positions[start], None)

            if(len(invalidity_start) != len(validity_start)):
51
52
53
54
55
                raise ValueError("error, invalidity_start ({}) and validity_start({})"
                                 " are not the same length ({} vs {})".format(invalidity_start,
                                                                              validity_start,
                                                                              len(invalidity_start),
                                                                              len(validity_start)))
Clement Pinard's avatar
Clement Pinard committed
56
57

            for start, end in zip(invalidity_start, validity_start):
Clément Pinard's avatar
Clément Pinard committed
58
                positions[start:end] = extrapolate_position(speed[start:end], timestamps[start:end], positions[start], positions[end])
Clement Pinard's avatar
Clement Pinard committed
59

nicolas's avatar
nicolas committed
60
    metadata["x"], metadata["y"], metadata["z"] = positions.transpose()
Clement Pinard's avatar
Clement Pinard committed
61
62
63
64

    return metadata


Clément Pinard's avatar
Clément Pinard committed
65
def extract_metadata(folder_path, file_path, native_wrapper, proj, w, h, f, save_path=None):
Clement Pinard's avatar
Clement Pinard committed
66
    metadata = native_wrapper.vmeta_extract(file_path)
nicolas's avatar
nicolas committed
67
    metadata = metadata.iloc[:-1]
Clément Pinard's avatar
Clément Pinard committed
68
    metadata = preprocess_metadata(metadata, proj)
Clement Pinard's avatar
Clement Pinard committed
69
70
71
72
73
74
    video_quality = h * w / f
    metadata["video_quality"] = video_quality
    metadata["height"] = h
    metadata["width"] = w
    metadata["framerate"] = f
    metadata["video"] = file_path
Clément Pinard's avatar
Clément Pinard committed
75
    metadata['frame'] = metadata.index + 1
Clément Pinard's avatar
Clément Pinard committed
76
    metadata["location_valid"] = metadata["location_valid"] == 1
77
    fx = metadata["width"] / (2 * np.tan(metadata["picture_hfov"] * np.pi/360))
78
79
    fy = metadata["height"] / (2 * np.tan(metadata["picture_vfov"] * np.pi/360))
    params = np.stack([fx.values, fy.values, metadata["width"]/2, metadata["height"]/2], axis=-1)
80
81
    metadata["camera_params"] = [tuple(p) for p in params]

Clement Pinard's avatar
Clement Pinard committed
82
83
84
    if save_path is not None:
        metadata.to_csv(save_path)
    return metadata