-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathextract_video_with_gps.py
96 lines (77 loc) · 3.89 KB
/
extract_video_with_gps.py
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
import edit_exif
from subprocess import Popen, PIPE
from path import Path
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
import pandas as pd
from tqdm import tqdm
import ffmpeg
import anafi_metadata as am
def extract_images(folder_path, file_path, fps):
print("exporting to images with ffmpeg ...")
if fps is not None:
fps_arg = ["-vf", "fps={}".format(fps)]
else:
fps_arg = []
ffmpeg = Popen(["ffmpeg", "-y", "-i", str(file_path), "-qscale:v", "2"] + fps_arg + [str(folder_path/"%05d.jpg")],
stdout=PIPE, stderr=PIPE)
ffmpeg.wait()
return sorted(folder_path.files("*.jpg"))
def extract_metadata(folder_path, file_path, native_wrapper):
output_file = folder_path/"metadata.csv"
print("extracting metadata with vmeta_extract...")
vmeta_extract = Popen([native_wrapper, "vmeta-extract", str(file_path), "--csv", str(output_file)],
stdout=PIPE, stderr=PIPE)
vmeta_extract.wait()
return output_file
def add_gps_to_exif(metadata, image_paths, fps):
metadata = metadata.set_index("time")
metadata.index = pd.to_datetime(metadata.index, unit="us")
if fps is not None:
metadata = metadata.resample("{:.3f}S".format(1/fps)).first()
metadata.to_csv(image_paths[0].parent / "metadata_{}fps.csv".format(fps), sep=" ")
print("Modifying gps EXIF for colmap...")
for img_path, row in tqdm(zip(image_paths, metadata.iterrows()), total=len(image_paths)):
if row[1]["location_valid"] == 1:
edit_exif.set_gps_location(img_path,
row[1]["location_latitude"],
row[1]["location_longitude"],
row[1]["location_altitude"])
def save_images_path_list(output_folder, origin, images_path_list):
relative_path_lists = [origin.relpathto(img) + '\n' for img in images_path_list]
with open(output_folder/'images.txt', 'w') as f:
f.writelines(relative_path_lists)
def workflow(root, output_folder, video_path, args):
print("Generating images with gps for video {}".format(str(video_path)))
output_folder /= video_path.stem
if args.fps is not None:
output_folder += "_{}fps".format(args.fps)
output_folder.mkdir_p()
images_path_list = ffmpeg.extract_images(output_folder, video_path, args.fps)
metadata = am.extract_metadata(output_folder, video_path, args.nw)
add_gps_to_exif(metadata, images_path_list, args.fps)
save_images_path_list(output_folder, args.origin or root, images_path_list)
parser = ArgumentParser(description='image extractor from parrot video',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('--input', metavar='PATH', default="~/Images/scan manoir/anafi/video",
help='path to video folder or video file', type=Path)
parser.add_argument('--fps', metavar='F', default=None, type=int,
help='fps')
parser.add_argument('--output_folder', metavar='DIR', default=None, type=Path)
parser.add_argument('--origin', metavar='DIR', default=None, type=Path,
help='folder relative to which the images path list will be generated')
parser.add_argument('--nw', default='',
help="native-wrapper.sh file location")
if __name__ == '__main__':
file_exts = ['.mp4', '.MP4']
args = parser.parse_args()
if args.input.isfile() and args.input.ext in file_exts:
root = args.input.parent
videos = [args.input]
elif args.input.isdir():
root = args.input
videos = sum([args.input.walkfiles('*{}'.format(ext)) for ext in file_exts], [])
print("Found {} videos".format(len(videos)))
if args.output_folder is None:
args.output_folder = root
for video_path in videos:
workflow(root, args.output_folder/(video_path.parent.relpath(root)), video_path, args)