Skip to content

Commit 4466383

Browse files
committed
Update evaluation for docs
1 parent e206566 commit 4466383

5 files changed

Lines changed: 82 additions & 63 deletions

File tree

avapi/evaluation/base.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
# @Author: Spencer Hallyburton <spencer>
2-
# @Date: 2022-04-18
3-
# @Filename: base.py
4-
# @Last modified by: spencer
5-
# @Last modified time: 2022-04-18
6-
71
import glob
82
import os
93
from copy import deepcopy
@@ -19,7 +13,7 @@
1913
)
2014
from tqdm import tqdm
2115

22-
from avapi.utils import color_from_object_type, get_indices_in_folder
16+
from avapi.utils import color_from_object_type, get_indices_filenames_in_folder
2317

2418
from ..visualize import snapshot
2519
from .metrics import precision, recall
@@ -71,7 +65,8 @@ def _results_from_folder(self):
7165
raise RuntimeError(f"No results to be found in {self.result_path}")
7266

7367
# Get indices by looping
74-
self.idxs_available = get_indices_in_folder(glob_dir, self.idxs)
68+
# self.idxs_available = get_indices_in_folder(glob_dir, self.idxs)
69+
idxs, filenames = get_indices_filenames_in_folder(glob_dir, self.idxs)
7570

7671
# -- run per-frame analysis
7772
part_func = partial(
@@ -89,15 +84,15 @@ def _results_from_folder(self):
8984
with Pool(8) as p:
9085
res_frame = list(
9186
tqdm(
92-
p.imap(part_func, self.idxs_available),
93-
total=len(self.idxs_available),
87+
p.imap(part_func, zip(idxs, filenames)),
88+
total=len(filenames),
9489
)
9590
)
9691
else:
97-
for idx in tqdm(self.idxs_available):
98-
res_frame.append(part_func(idx))
92+
for idx, filename in tqdm(zip(idxs, filenames), total=len(filenames)):
93+
res_frame.append(part_func((idx, filename)))
9994

100-
res_frame = {idx: res for idx, res in zip(self.idxs_available, res_frame)}
95+
res_frame = {idx: res for idx, res in zip(idxs, res_frame)}
10196

10297
# -- run per-sequence analysis
10398
res_seq = self._run_per_seq_analysis(res_frame)
@@ -241,9 +236,9 @@ def run_assignment(self, threshold):
241236
if c in idx_tru_dontcare
242237
]
243238
assigns = {
244-
r: c
239+
r: c[0]
245240
for r, c in assignment.iterate_over("rows").items()
246-
if list(c.keys())[0] not in idx_tru_dontcare
241+
if c[0] not in idx_tru_dontcare
247242
}
248243
assignment = OneEdgeBipartiteGraph(
249244
assigns,
@@ -267,8 +262,7 @@ def run_assignment(self, threshold):
267262
)
268263
n_fn = len([idx for idx in idx_FN if self.truths[idx].obj_type == obj_type])
269264
n_tp = 0
270-
for r, cw in assigns.items():
271-
c = list(cw.keys())[0]
265+
for r, c in assigns.items():
272266
if self.detections[r].obj_type == obj_type:
273267
if self.truths[c].obj_type == obj_type:
274268
n_tp += 1

avapi/evaluation/perception.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
# -*- coding: utf-8 -*-
2-
# @Author: spencer@primus
3-
# @Date: 2022-06-28
4-
# @Last Modified by: spencer@primus
5-
# @Last Modified time: 2022-09-09
6-
71
import json
82
import os
93

104
import numpy as np
115
from avstack.geometry import bbox
12-
from avstack.modules.perception.detections import BoxDetection, DetectionDecoder
6+
from avstack.modules.perception.detections import (
7+
BoxDetection,
8+
DetectionContainerDecoder,
9+
)
1310

1411
from avapi.evaluation.base import ResultAnalyzer, ResultManager
1512

@@ -63,11 +60,12 @@ def _run_per_frame_analysis(
6360
max_dist,
6461
max_occ,
6562
whitelist_types,
66-
idx,
63+
idx_filename,
6764
):
6865
"""Load percep status of a single frame"""
66+
idx, filename = idx_filename
67+
6968
# Get truths
70-
# import ipdb; ipdb.set_trace()
7169
dist_all = max_dist if sensor_eval_super == "ego" else None
7270
truths_all = DM.get_objects(
7371
idx, sensor=sensor_eval_super, max_dist=dist_all, whitelist_types="all"
@@ -85,9 +83,8 @@ def _run_per_frame_analysis(
8583
)
8684

8785
# Get detections
88-
det_file_path = os.path.join(result_path, "%06i.txt" % idx)
89-
with open(det_file_path, "rb") as f:
90-
detections = json.load(f, cls=DetectionDecoder)
86+
with open(filename, "rb") as f:
87+
detections = json.load(f, cls=DetectionContainerDecoder)
9188
dets = [det for det in detections if isinstance(det, (BoxDetection,))]
9289
metric = (
9390
"3D_IoU"

avapi/evaluation/tracking.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
# @Author: spencer@primus
3-
# @Date: 2022-05-30
4-
# @Last Modified by: spencer@primus
5-
# @Last Modified time: 2022-09-09
6-
71
import glob
82
import logging
93
import os
@@ -70,9 +64,11 @@ def _run_per_frame_analysis(
7064
max_dist,
7165
max_occ,
7266
whitelist_types,
73-
idx,
67+
idx_filename,
7468
):
7569
"""Load track status of a single frame"""
70+
idx, filename = idx_filename
71+
7672
# Get truths
7773
dist_all = max_dist if sensor_eval_super == "ego" else None
7874
truths_all = DM.get_objects(
@@ -91,10 +87,8 @@ def _run_per_frame_analysis(
9187
)
9288

9389
# Get tracks
94-
trk_file_path = os.path.join(result_path, "%06i.txt" % idx)
95-
tracks = DM.get_objects_from_file(
96-
trk_file_path, whitelist_types=whitelist_types
97-
)
90+
# trk_file_path = os.path.join(result_path, "%06i.txt" % idx)
91+
tracks = DM.get_objects_from_file(filename, whitelist_types=whitelist_types)
9892

9993
# -- 2d analysis
10094

@@ -142,6 +136,7 @@ def _run_expanded_analysis(
142136
DM, save_folder, sensor_eval, sensor_eval_super, whitelist_types, max_dist
143137
):
144138
"""Run HOTA metrics"""
139+
return {}
145140
tracker_name = "no-name"
146141

147142
# --- metrics evaluator

avapi/utils.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,33 @@ def remove_glob(glob_files):
2929
print("Removed files from: {}".format(os.path.dirname(f)), flush=True)
3030

3131

32+
def get_indices_filenames_in_folder(glob_dir, idxs=None):
33+
idxs_available = []
34+
fnames_available = []
35+
for f in glob_dir:
36+
if "log" in f:
37+
continue
38+
try:
39+
idx = int(f.split("/")[-1].replace(".txt", ""))
40+
except ValueError:
41+
idx = int(f.split("/")[-1].split("-")[2])
42+
if idxs is not None:
43+
try:
44+
iterator = iter(idxs)
45+
except TypeError:
46+
# not iterable
47+
if not (idx == idxs):
48+
continue
49+
else:
50+
# iterable
51+
if idx not in idxs:
52+
continue
53+
if idx not in idxs_available:
54+
idxs_available.append(idx)
55+
fnames_available.append(f)
56+
return idxs_available, fnames_available
57+
58+
3259
def get_indices_in_folder(glob_dir, idxs=None):
3360
"""Get indices of items in a glob_dir
3461
optionally: enforce that they are in the list idxs
@@ -37,7 +64,10 @@ def get_indices_in_folder(glob_dir, idxs=None):
3764
for f in glob_dir:
3865
if "log" in f:
3966
continue
40-
idx = int(f.split("/")[-1].replace(".txt", ""))
67+
try:
68+
idx = int(f.split("/")[-1].replace(".txt", ""))
69+
except ValueError:
70+
idx = int(f.split("/")[-1].split("-")[2])
4171
if idxs is not None:
4272
try:
4373
iterator = iter(idxs)

avapi/visualize/replay.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@
1212
print("Cannot find ipywidgets...cannot run visualizations")
1313

1414
from avstack.environment.objects import VehicleState
15-
from avstack.geometry import bbox
15+
from avstack.geometry import Attitude, GlobalOrigin3D, Position, bbox
1616
from avstack.modules.perception.detections import BoxDetection
1717

18-
from .snapshot import show_image_with_boxes
19-
18+
from avapi.utils import color_from_object_type
2019

21-
# from avapi.evaluation import ResultManager, color_from_object_type
20+
from .snapshot import show_image_with_boxes
2221

2322

2423
# ========================================================
@@ -91,6 +90,8 @@ def load_ground_truth_data(folder):
9190

9291

9392
def replay_ground_truth_from_folder(folder, viz_type="track"):
93+
from avapi.evaluation import ResultManager
94+
9495
assert viz_type in ["track", "track_percep"]
9596
print("Replaying ground truth data from {}".format(folder))
9697
ego_data, npc_data = load_ground_truth_data(folder)
@@ -120,6 +121,8 @@ def replay_ground_truth_from_folder(folder, viz_type="track"):
120121

121122

122123
def replay_ground_truth_from_data_manager(DM, sensor="main_camera"):
124+
from avapi.evaluation import ResultManager
125+
123126
ego_data = [DM.get_ego(frame) for frame in DM.frames]
124127
npc_data = [DM.get_objects(frame) for frame in DM.frames]
125128

@@ -197,7 +200,7 @@ def replay_track_results(
197200
add_points_real.append([])
198201
for pt in pts:
199202
if (pt is not None) and (not isinstance(pt, str)):
200-
pt.change_origin(NominalOriginStandard)
203+
pt.change_reference(GlobalOrigin3D, inplace=True)
201204
add_points_real[i].append(pt)
202205
add_points = add_points_real
203206
if (highlight_track_IDs is None) or (len(highlight_track_IDs) == 0):
@@ -206,7 +209,7 @@ def replay_track_results(
206209
assert len(highlight_track_IDs) == len(track_results), len(highlight_track_IDs)
207210

208211
if ego_box is not None:
209-
ego_box.change_origin(NominalOriginStandard)
212+
ego_box.change_reference(GlobalOrigin3D, inplace=True)
210213

211214
# Get all track locations and predictions ahead of time
212215
trk_points = {} # ID: frame: pt
@@ -216,7 +219,7 @@ def replay_track_results(
216219
for idx, tr in track_results.items():
217220
for track in tr["result"].tracks:
218221
if isinstance(track, VehicleState):
219-
track.change_origin(NominalOriginStandard)
222+
track.change_reference(GlobalOrigin3D, inplace=True)
220223
if track.ID not in trk_points:
221224
trk_points[track.ID] = {}
222225
trk_preds[track.ID] = {}
@@ -229,7 +232,7 @@ def replay_track_results(
229232
raise NotImplementedError(type(track))
230233
for truth in tr["result"].truths:
231234
if isinstance(truth, VehicleState):
232-
truth.change_origin(NominalOriginStandard)
235+
truth.change_reference(GlobalOrigin3D, inplace=True)
233236

234237
def f(idx):
235238
axs_slider.clear()
@@ -255,14 +258,9 @@ def plot_tracks(colors, tracks):
255258
if do_highlight:
256259
fac = 1.2
257260
box_enlarged = bbox.Box3D(
258-
[
259-
fac * track.box.h,
260-
fac * track.box.w,
261-
fac * track.box.l,
262-
track.position,
263-
track.box.attitude,
264-
],
265-
track.position.origin,
261+
position=track.position,
262+
attitude=track.attitude,
263+
hwl=[fac * d for d in track.box.size],
266264
)
267265
axs_slider.add_patch(
268266
_box_to_bev_rect(
@@ -361,7 +359,7 @@ def plot_tracks(colors, tracks):
361359
):
362360
col = tuple(c / 255.0 for c in color)
363361
if "bev" in projection:
364-
truth.box3d.change_origin(NominalOriginStandard)
362+
truth.box3d.change_reference(GlobalOrigin3D, inplace=True)
365363
rect = _box_to_bev_rect(
366364
truth.box3d,
367365
col,
@@ -376,7 +374,9 @@ def plot_tracks(colors, tracks):
376374

377375
# add fake elements to legend
378376
nominal_box = bbox.Box3D(
379-
[2, 2, 4, np.zeros((3,)), np.quaternion(1)], NominalOriginStandard
377+
position=Position(np.zeros((3,)), GlobalOrigin3D),
378+
attitude=Attitude(np.quaternion(1), GlobalOrigin3D),
379+
hwl=[2, 2, 4],
380380
)
381381
# -- unsafe
382382
handles.append(
@@ -535,12 +535,12 @@ def replay_track_percep_results(
535535
track_boxes = []
536536
for trk in track_results[idx]["result"].tracks:
537537
trk_copy = deepcopy(trk).as_object()
538-
trk_copy.change_origin(calib.origin)
538+
trk_copy.change_reference(calib.reference, inplace=True)
539539
track_boxes.append(trk_copy)
540540
box_colors = track_results[idx]["result"].colors["detections"]
541541
if show_truth:
542542
for truth in track_results[idx]["result"].truths:
543-
truth.box.change_origin(calib.origin)
543+
truth.box.change_reference(calib.reference, inplace=True)
544544
track_boxes.append(truth)
545545
box_colors.extend(track_results[idx]["result"].colors["truths"])
546546
else:
@@ -553,7 +553,10 @@ def replay_track_percep_results(
553553
if "fv" in projection:
554554
img = DM.get_image(idx, sensor=sensor)
555555
img3d = show_image_with_boxes(
556-
img, track_boxes, box_colors=box_colors, show=False, return_images=True
556+
img,
557+
track_boxes,
558+
box_colors=box_colors,
559+
show=False,
557560
)
558561
imgs_ALL["fv"] = (
559562
img3d[..., None]
@@ -612,7 +615,7 @@ def _box_to_bev_rect(
612615
(left, bottom),
613616
width,
614617
height,
615-
angle,
618+
angle=angle,
616619
alpha=0.9,
617620
edgecolor=color,
618621
facecolor=facecolor,

0 commit comments

Comments
 (0)