forked from ElvinC/gyroflow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GPMF_gyro.py
93 lines (66 loc) · 2.94 KB
/
GPMF_gyro.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
# Script to extract gopro metadata into a useful format.
# Uses a modified python-gpmf from https://github.com/rambo/python-gpmf
import gpmf.parse as gpmf_parse
from gpmf.extract import get_gpmf_payloads_from_file
import sys
import numpy as np
from matplotlib import pyplot as plt
import cv2
class Extractor:
def __init__(self, videopath = "hero5.mp4"):
self.videopath = videopath
payloads, parser = get_gpmf_payloads_from_file(videopath)
self.parsed = []
print(payloads)
for gpmf_data, timestamps in payloads:
self.parsed.append(gpmf_parse.parse_dict(gpmf_data))
self.video_length = 0 # video length in seconds
self.fps = 0
self.find_video_length()
# Parsed gyro samples
self.gyro = []
self.gyro_scal = 0
self.num_gyro_samples = 0
self.gyro_rate = 0 # gyro rate in Hz
self.parsed_gyro = np.zeros((1,4)) # placeholder
self.parse_gyro()
def find_video_length(self):
#find video length using openCV
video = cv2.VideoCapture(self.videopath)
num_frames = video.get(cv2.CAP_PROP_FRAME_COUNT)
self.fps = video.get(cv2.CAP_PROP_FPS)
self.video_length = num_frames / self.fps
print("Video length: {} s, framerate: {} FPS".format(self.video_length,self.fps))
self.size = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
video.release()
def parse_gyro(self):
for frame in self.parsed:
for stream in frame["DEVC"]["STRM"]:
if "GYRO" in stream:
#print(stream["STNM"]) # print stream name
self.gyro += stream["GYRO"]
# Calibration scale shouldn't change
self.gyro_scal = stream["SCAL"]
print(self.gyro_scal)
# Convert to angular vel. vector in rad/s
omega = np.array(self.gyro) / self.gyro_scal
self.num_gyro_samples = omega.shape[0]
self.gyro_rate = self.num_gyro_samples / self.video_length
print("Gyro rate: {} Hz, should be close to 200 or 400 Hz".format(self.gyro_rate))
self.parsed_gyro = np.zeros((self.num_gyro_samples, 4))
self.parsed_gyro[:,0] = np.arange(self.num_gyro_samples) * 1/self.gyro_rate
# Data order for gopro gyro is (z,x,y)
self.parsed_gyro[:,3] = omega[:,0] # z
self.parsed_gyro[:,1] = omega[:,1] # x
self.parsed_gyro[:,2] = omega[:,2] # y
def get_gyro(self, with_timestamp = False):
if with_timestamp:
return self.parsed_gyro
return self.parsed_gyro[:,1:]
def get_accl(self):
return 0
def get_video_length(self):
return self.video_length
if __name__ == "__main__":
testing = Extractor()
testing.get_gyro()