-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathdataset.py
More file actions
124 lines (93 loc) · 3.68 KB
/
Copy pathdataset.py
File metadata and controls
124 lines (93 loc) · 3.68 KB
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
from __future__ import annotations
from typing import TYPE_CHECKING
from attrs import define
from t4_devkit import Tier4
from t4_devkit.dataclass import HomogeneousMatrix, TransformBuffer
from .task import EvaluationTask
if TYPE_CHECKING:
from t4_devkit.dataclass import BoxLike
from t4_devkit.schema import EgoPose, Sensor
__all__ = ["load_dataset", "FrameGroundTruth", "SceneGroundTruth"]
def load_dataset(data_root: str, task: EvaluationTask) -> SceneGroundTruth:
"""Load dataset.
Args:
data_root (str): Root directory path to the dataset.
task (EvaluationTask): Evaluation task.
Returns:
SceneGroundTruth: Loaded container of ground truths.
"""
t4 = Tier4("annotation", data_root=data_root, verbose=False)
frames: list[FrameGroundTruth] = []
for i, sample in enumerate(t4.sample):
# annotation boxes
boxes = (
list(map(t4.get_box3d, sample.ann_3ds))
if task.is_3d()
else list(map(t4.get_box2d, sample.ann_2ds))
)
# transformation matrix from ego to map
ego_pose = _closest_ego_pose(t4, sample.timestamp)
ego2map = HomogeneousMatrix(
position=ego_pose.translation,
rotation=ego_pose.rotation,
src="base_link",
dst="map",
)
frames.append(
FrameGroundTruth(
unix_time=sample.timestamp,
frame_index=i,
boxes=boxes,
ego2map=ego2map,
)
)
# transformation matrices from ego to each sensor
ego2sensors = TransformBuffer()
for cs_record in t4.calibrated_sensor:
sensor: Sensor = t4.get("sensor", cs_record.sensor_token)
matrix = HomogeneousMatrix(
position=cs_record.translation,
rotation=cs_record.rotation,
src="base_link",
dst=sensor.channel,
)
ego2sensors.set_transform(matrix)
return SceneGroundTruth(data_root=data_root, frames=frames, ego2sensors=ego2sensors)
def _closest_ego_pose(t4: Tier4, timestamp: int) -> EgoPose:
"""Lookup the ego pose record at the closest timestamp."""
return min(t4.ego_pose, key=lambda e: abs(e.timestamp - timestamp))
@define
class FrameGroundTruth:
"""A container of boxes at a single frame.
Attributes:
unix_time (int): Unix timestamp.
frame_index (int): Index number of the frame.
boxes (list[BoxLike]): List of ground truth instances.
ego2map (HomogeneousMatrix): Transformation matrix from ego to map coordinate.
"""
unix_time: int
frame_index: int
boxes: list[BoxLike]
ego2map: HomogeneousMatrix
@define
class SceneGroundTruth:
"""A container of frame ground truths.
Attributes:
data_root (str): Root directory path to the dataset.
frames (list[FrameGroundTruth]): List of frame ground truths.
ego2sensors (TransformBuffer): Buffer of transformation matrices from ego to each sensor coordinates.
"""
data_root: str
frames: list[FrameGroundTruth]
ego2sensors: TransformBuffer
def lookup_frame(self, unix_time: int, tolerance: int) -> FrameGroundTruth | None:
"""Lookup the closest set of ground truth frame.
Return None if the minimum time difference exceeds `tolerance`.
Args:
unix_time (int): Unix timestamp.
tolerance (int): Time difference tolerance in micro seconds.
Returns:
Return frame ground truth if succeeded, otherwise None.
"""
closest = min(self.frames, key=lambda f: abs(unix_time - f.unix_time))
return closest if abs(unix_time - closest.unix_time) <= tolerance else None