forked from mbalesni/openpilot-pipeline
-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate_gt.py
144 lines (112 loc) · 5.68 KB
/
generate_gt.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env python3
from os.path import exists
import onnxruntime as ort
from tqdm import tqdm
import numpy as np
import sys
import os
import time
import h5py
from pathlib import Path
import argparse
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils import extract_preds, printf, dir_path, PATH_TO_CACHE
from train.dataloader import load_transformed_video
from gt_distill.parse_logs import save_segment_calib
def frames_to_tensor(frames):
H = (frames.shape[1]*2)//3
W = frames.shape[2]
in_img1 = np.zeros((frames.shape[0], 6, H//2, W//2), dtype=np.uint8)
in_img1[:, 0] = frames[:, 0:H:2, 0::2]
in_img1[:, 1] = frames[:, 1:H:2, 0::2]
in_img1[:, 2] = frames[:, 0:H:2, 1::2]
in_img1[:, 3] = frames[:, 1:H:2, 1::2]
in_img1[:, 4] = frames[:, H:H+H//4].reshape((-1, H//2, W//2))
in_img1[:, 5] = frames[:, H+H//4:H+H//2].reshape((-1, H//2, W//2))
return in_img1
def generate_ground_truth(path_to_segment, model, force=False):
'''Model expected to be an onnxruntime InferenceSession.'''
out_path = os.path.join(path_to_segment, 'gt_distill.h5')
if exists(out_path) and not force:
print('Ground truth already exists at:', out_path)
return
input_frames, _ = load_transformed_video(path_to_segment)
if input_frames is None: return
input_frames = input_frames.numpy()
recurrent_state = np.zeros((1, 512)).astype(np.float32)
desire = np.zeros((1, 8)).astype(np.float32)
tc = np.array([[0, 1]]).astype(np.float32)
plans = []
plans_prob = []
lanelines = []
laneline_probs = []
road_edges = []
road_edge_stds = []
for img in input_frames:
img = np.expand_dims(img.astype(np.float32), axis=0)
outs = model.run(None, {'input_imgs': img, 'desire': desire, 'traffic_convention': tc, 'initial_state': recurrent_state})[0]
results = extract_preds(outs, best_plan_only=False)[0]
(lane_lines_t, lane_lines_probs_t), (road_edges_t, road_edges_std_t), (plans_t, plans_prob_t) = results
plans.append(plans_t)
plans_prob.append(plans_prob_t)
lanelines.append(np.stack(lane_lines_t))
laneline_probs.append(np.stack(lane_lines_probs_t))
road_edges.append(np.stack(road_edges_t))
road_edge_stds.append(np.stack(road_edges_std_t))
# Important to refeed the state
recurrent_state = outs[:, -512:]
if not plans:
return
try:
# delete existing file
try:
os.remove(out_path)
except FileNotFoundError:
pass
with h5py.File(out_path, 'w') as h5file_object:
h5file_object.create_dataset("plans", data=np.stack(plans))
h5file_object.create_dataset("plans_prob", data=np.stack(plans_prob))
h5file_object.create_dataset("lanelines", data=np.stack(lanelines))
h5file_object.create_dataset("laneline_probs", data=np.stack(laneline_probs))
h5file_object.create_dataset("road_edges", data=np.stack(road_edges))
h5file_object.create_dataset("road_edge_stds", data=np.stack(road_edge_stds))
except Exception as e:
print(f'Couldn\'t save the ground truths at {path_to_segment}:', e)
if __name__ == '__main__':
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
default_model_path = os.path.join(parent_dir, 'common/models/supercombo.onnx')
parser = argparse.ArgumentParser(description='Run the original supercombo model on the dataset and save the predicted path plans.')
parser.add_argument("--cache", default=str(Path(PATH_TO_CACHE) / 'segments.txt'), help="path to cache file that stores the paths to the segments")
parser.add_argument("--recordings_basedir", type=dir_path, default="/gpfs/space/projects/Bolt/comma_recordings", help="path to base directory with recordings")
parser.add_argument("--openpilot_dir", type=dir_path, default=str(Path.home() / 'openpilot'), help="path to openpilot directory")
parser.add_argument("--path_to_model", default=default_model_path, help="path to model for creating ground truths")
parser.add_argument("--force_gt", dest='force_gt', action='store_true', help="path to model for creating ground truths")
parser.add_argument("--force_calib", dest='force_calib', action='store_true', help="path to model for creating ground truths")
parser.set_defaults(force_gt=False, force_calib=False)
args = parser.parse_args()
options = ort.SessionOptions()
options.intra_op_num_threads = 30
options.execution_mode = ort.ExecutionMode.ORT_SEQUENTIAL
options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
# CPU turns out faster than CUDA with batch size = 1
model = ort.InferenceSession(args.path_to_model, providers=["CPUExecutionProvider"], sess_options=options)
if os.path.exists(args.cache):
printf('Using cached segment directories...')
with open(args.cache, 'r') as f:
segments = [line.strip() for line in f.readlines()]
else:
printf('Finding segment directories...')
os.makedirs(PATH_TO_CACHE, exist_ok=True)
with open(args.cache, 'a+') as f:
pbar = tqdm()
for dir_path, _, files in os.walk(args.recordings_basedir):
if 'video.hevc' not in files and 'fcamera.hevc' not in files:
continue
pbar.update(1)
f.write(dir_path + '\n')
printf('Generating ground truths...')
for dir_path in tqdm(segments):
printf('dir_path:', dir_path)
generate_ground_truth(dir_path, model, force=args.force_gt)
save_segment_calib(dir_path, args.openpilot_dir, force=args.force_calib)
printf()