Skip to content
This repository was archived by the owner on Jul 8, 2023. It is now read-only.

Commit 0218699

Browse files
committed
GoPro gyro extraction implemented
1 parent 243fe65 commit 0218699

File tree

2 files changed

+72
-15
lines changed

2 files changed

+72
-15
lines changed

GPMF_gyro.py

+25-14
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,39 @@
44
import gpmf.parse as gpmf_parse
55
from gpmf.extract import get_gpmf_payloads_from_file
66
import sys
7-
7+
import numpy as np
8+
from matplotlib import pyplot as plt
89

910
class Extractor:
1011
def __init__(self, videopath = "hero5.mp4"):
1112
self.videopath = videopath
1213

1314
payloads, parser = get_gpmf_payloads_from_file(videopath)
1415

16+
self.parsed = []
17+
1518
for gpmf_data, timestamps in payloads:
16-
for element, parents in gpmf_parse.recursive(gpmf_data):
17-
try:
18-
value = gpmf_parse.parse_value(element)
19-
except ValueError:
20-
value = element.data
21-
print("{} {} > {}: {}".format(
22-
timestamps,
23-
' > '.join([x.decode('ascii') for x in parents]),
24-
element.key.decode('ascii'),
25-
value
26-
))
19+
self.parsed.append(gpmf_parse.parse_dict(gpmf_data))
20+
21+
22+
23+
2724

2825
def get_gyro(self):
29-
return 1
26+
self.gyro = []
27+
self.scal = 0
28+
for frame in self.parsed:
29+
for stream in frame["DEVC"]["STRM"]:
30+
if "GYRO" in stream:
31+
self.gyro += stream["GYRO"]
32+
self.scal = stream["SCAL"]
33+
34+
35+
36+
omega = np.array(self.gyro) / self.scal
37+
38+
plt.plot(omega[:,0])
39+
plt.show()
3040

3141
def get_accl(self):
3242
return 1
@@ -36,4 +46,5 @@ def get_video_length(self):
3646

3747

3848
if __name__ == "__main__":
39-
testing = Extractor()
49+
testing = Extractor()
50+
testing.get_gyro()

gpmf/parse.py

+47-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
# Derived from:
2+
# https://github.com/rambo/python-gpmf
13
# The MIT License (MIT)
24
# Copyright (c) 2014 Eero af Heurlin
3-
# https://github.com/rambo/python-gpmf
45

56
#!/usr/bin/env python3
67
"""Parses the FOURCC data in GPMF stream into fields"""
@@ -42,6 +43,9 @@
4243

4344
def parse_value(element):
4445
"""Parses element value"""
46+
if not element:
47+
return "HELLOWTHERE"
48+
4549
type_parsed = TYPES.parse(bytes([element.type]))
4650
#print("DEBUG: type_parsed={}, element.repeat={}, element.size={}, len(element.data): {}".format(type_parsed, element.repeat, element.size, len(element.data)))
4751

@@ -123,7 +127,49 @@ def recursive(data, parents=tuple()):
123127
yield subyield
124128
else:
125129
yield (element, parents)
130+
131+
def parse_list(data, parent = []):
132+
elements = construct.GreedyRange(FOURCC).parse(data)
133+
134+
out_list = []
135+
for element in elements:
136+
if element.type == 0:
137+
138+
out_list.append(parse_list(element.data, out_list))
139+
else:
140+
try:
141+
value = parse_value(element)
142+
except ValueError:
143+
value = element.data
144+
145+
out_list.append(value)
146+
print(element.key)
147+
148+
return out_list
149+
150+
def parse_dict(data):
151+
"""Parse data into a dict recursively
152+
"""
153+
154+
elements = construct.GreedyRange(FOURCC).parse(data)
155+
new_dict = dict()
156+
157+
for element in elements:
158+
if element.type == 0:
159+
160+
if (element.key.decode('ascii') == "STRM"):
161+
new_dict.setdefault("STRM", []).append(parse_dict(element.data))
162+
else:
163+
new_dict[element.key.decode('ascii')] = parse_dict(element.data)
164+
165+
else:
166+
try:
167+
value = parse_value(element)
168+
except ValueError:
169+
value = element.data
170+
new_dict[element.key.decode('ascii')] = value
126171

172+
return new_dict
127173

128174
if __name__ == '__main__':
129175
import sys

0 commit comments

Comments
 (0)