forked from jhong93/spot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse_soccernet.py
executable file
·127 lines (98 loc) · 4.39 KB
/
parse_soccernet.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/env python3
import os
import argparse
import json
from collections import defaultdict
from SoccerNet.utils import getListGames
from util.io import load_json
from util.dataset import read_fps, get_num_frames
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument('label_dir', type=str,
help='Path to the SoccerNetV2 labels')
parser.add_argument('frame_dir', type=str,
help='Path to extracted video frames')
parser.add_argument('-o', '--out_dir', type=str,
help='Path to output parsed dataset')
return parser.parse_args()
def load_split(split):
if split == 'val':
split = 'valid'
videos = []
for entry in getListGames(split):
league, season, game = entry.split('/')
videos.append((league, season, game))
return videos
def get_label_names(labels):
return {e['label'] for v in labels for e in v['events']}
def main(label_dir, frame_dir, out_dir):
labels_by_split = defaultdict(list)
for split in ['train', 'val', 'test', 'challenge']:
videos = load_split(split)
for video in videos:
league, season, game = video
video_label_path = os.path.join(
label_dir, league, season, game, 'Labels-v2.json')
if split != 'challenge':
video_labels = load_json(video_label_path)
else:
video_labels = {'annotations': []}
num_events = 0
for half in (1, 2):
video_frame_dir = os.path.join(
frame_dir, league, season, game, str(half))
sample_fps = read_fps(video_frame_dir)
num_frames = get_num_frames(video_frame_dir)
video_id = '{}/{}/{}/{}'.format(league, season, game, half)
half_events = []
for label in video_labels['annotations']:
lhalf = int(label['gameTime'].split(' - ')[0])
if half == lhalf:
adj_frame = float(label['position']) / 1000 * sample_fps
half_events.append({
'frame': int(adj_frame),
'label': label['label'],
'comment': '{}; {}'.format(
label['team'], label['visibility'])
})
if adj_frame >= num_frames:
print('Label past end: {} -- {} < {} -- {}'.format(
video_id, num_frames, int(adj_frame),
label['label']))
num_events += len(half_events)
half_events.sort(key=lambda x: x['frame'])
# max_label_frame = max(e['frame'] for e in half_events) \
# if len(half_events) > 0 else 0
# if max_label_frame >= num_frames:
# num_frames = max_label_frame + 1
labels_by_split[split].append({
'video': video_id,
'num_frames': num_frames,
'num_events': len(half_events),
'events': half_events,
'fps': sample_fps,
'width': 398,
'height': 224
})
assert len(video_labels['annotations']) == num_events, \
video_label_path
train_classes = get_label_names(labels_by_split['train'])
assert train_classes == get_label_names(labels_by_split['test'])
assert train_classes == get_label_names(labels_by_split['val'])
print('Classes:', sorted(train_classes))
for split, labels in labels_by_split.items():
print('{} : {} videos : {} events'.format(
split, len(labels), sum(len(l['events']) for l in labels)))
labels.sort(key=lambda x: x['video'])
if out_dir is not None:
os.makedirs(out_dir, exist_ok=True)
class_path = os.path.join(out_dir, 'class.txt')
with open(class_path, 'w') as fp:
fp.write('\n'.join(sorted(train_classes)))
for split, labels in labels_by_split.items():
out_path = os.path.join(out_dir, '{}.json'.format(split))
with open(out_path, 'w') as fp:
json.dump(labels, fp, indent=2, sort_keys=True)
print('Done!')
if __name__ == '__main__':
main(**vars(get_args()))