diff --git a/l5kit/l5kit/data/map_api.py b/l5kit/l5kit/data/map_api.py index 6811f20a..18947491 100644 --- a/l5kit/l5kit/data/map_api.py +++ b/l5kit/l5kit/data/map_api.py @@ -110,7 +110,7 @@ def get_lane_coords(self, element_id: str) -> dict: element_id (str): lane element id Returns: - dict: a dict with the two boundaries coordinates as (Nx3) XYZ arrays + dict: a dict with the boundaries coordinates as (3xN) XYZ arrays """ element = self[element_id] assert self.is_lane(element) @@ -132,7 +132,10 @@ def get_lane_coords(self, element_id: str) -> dict: lane.geo_frame, ) - return {"xyz_left": xyz_left, "xyz_right": xyz_right} + xyz = np.vstack((xyz_left, np.flip(xyz_right, 0))) + xyz[:, -1] = 1.0 + + return {"xyz": xyz.T} @staticmethod @no_type_check @@ -161,7 +164,7 @@ def get_crosswalk_coords(self, element_id: str) -> dict: element_id (str): crosswalk element id Returns: - dict: a dict with the polygon coordinates as an (Nx3) XYZ array + dict: a dict with the polygon coordinates as an (3xN) XYZ array """ element = self[element_id] assert self.is_crosswalk(element) @@ -174,7 +177,8 @@ def get_crosswalk_coords(self, element_id: str) -> dict: traffic_element.geo_frame, ) - return {"xyz": xyz} + xyz[:, -1] = 1.0 + return {"xyz": xyz.T} def is_traffic_face_colour(self, element_id: str, colour: str) -> bool: """ diff --git a/l5kit/l5kit/rasterization/semantic_rasterizer.py b/l5kit/l5kit/rasterization/semantic_rasterizer.py index 5f728462..d82f9724 100644 --- a/l5kit/l5kit/rasterization/semantic_rasterizer.py +++ b/l5kit/l5kit/rasterization/semantic_rasterizer.py @@ -6,7 +6,7 @@ from ..data.filter import filter_tl_faces_by_status from ..data.map_api import MapAPI -from ..geometry import rotation33_as_yaw, transform_point, transform_points, world_to_image_pixels_matrix +from ..geometry import rotation33_as_yaw, transform_point, world_to_image_pixels_matrix from .rasterizer import Rasterizer # sub-pixel drawing precision constants @@ -95,20 +95,20 @@ def get_bounds(self) -> dict: if self.proto_API.is_lane(element): lane = self.proto_API.get_lane_coords(element_id) - x_min = min(np.min(lane["xyz_left"][:, 0]), np.min(lane["xyz_right"][:, 0])) - y_min = min(np.min(lane["xyz_left"][:, 1]), np.min(lane["xyz_right"][:, 1])) - x_max = max(np.max(lane["xyz_left"][:, 0]), np.max(lane["xyz_right"][:, 0])) - y_max = max(np.max(lane["xyz_left"][:, 1]), np.max(lane["xyz_right"][:, 1])) + x_min = np.min(lane["xyz"][0, :]) + y_min = np.min(lane["xyz"][1, :]) + x_max = np.max(lane["xyz"][0, :]) + y_max = np.max(lane["xyz"][1, :]) lanes_bounds = np.append(lanes_bounds, np.asarray([[[x_min, y_min], [x_max, y_max]]]), axis=0) lanes_ids.append(element_id) if self.proto_API.is_crosswalk(element): crosswalk = self.proto_API.get_crosswalk_coords(element_id) - x_min = np.min(crosswalk["xyz"][:, 0]) - y_min = np.min(crosswalk["xyz"][:, 1]) - x_max = np.max(crosswalk["xyz"][:, 0]) - y_max = np.max(crosswalk["xyz"][:, 1]) + x_min = np.min(crosswalk["xyz"][0, :]) + y_min = np.min(crosswalk["xyz"][1, :]) + x_max = np.max(crosswalk["xyz"][0, :]) + y_max = np.max(crosswalk["xyz"][1, :]) crosswalks_bounds = np.append( crosswalks_bounds, np.asarray([[[x_min, y_min], [x_max, y_max]]]), axis=0, @@ -176,12 +176,10 @@ def render_semantic_map( # get image coords lane_coords = self.proto_API.get_lane_coords(self.bounds_info["lanes"]["ids"][idx]) - xy_left = cv2_subpixel(transform_points(lane_coords["xyz_left"][:, :2], world_to_image_space)) - xy_right = cv2_subpixel(transform_points(lane_coords["xyz_right"][:, :2], world_to_image_space)) - lanes_area = np.vstack((xy_left, np.flip(xy_right, 0))) # start->end left then end->start right + lanes_xy = cv2_subpixel(world_to_image_space.dot(lane_coords["xyz"]).T[:, :2]) # Note(lberg): this called on all polygons skips some of them, don't know why - cv2.fillPoly(img, [lanes_area], (17, 17, 31), lineType=cv2.LINE_AA, shift=CV2_SHIFT) + cv2.fillPoly(img, [lanes_xy], (17, 17, 31), lineType=cv2.LINE_AA, shift=CV2_SHIFT) lane_type = "default" # no traffic light face is controlling this lane lane_tl_ids = set([MapAPI.id_as_str(la_tc) for la_tc in lane.traffic_controls]) @@ -193,7 +191,7 @@ def render_semantic_map( elif self.proto_API.is_traffic_face_colour(tl_id, "yellow"): lane_type = "yellow" - lanes_lines[lane_type].extend([xy_left, xy_right]) + lanes_lines[lane_type].extend([lanes_xy]) cv2.polylines(img, lanes_lines["default"], False, (255, 217, 82), lineType=cv2.LINE_AA, shift=CV2_SHIFT) cv2.polylines(img, lanes_lines["green"], False, (0, 255, 0), lineType=cv2.LINE_AA, shift=CV2_SHIFT) @@ -205,7 +203,7 @@ def render_semantic_map( for idx in elements_within_bounds(center_world, self.bounds_info["crosswalks"]["bounds"], raster_radius): crosswalk = self.proto_API.get_crosswalk_coords(self.bounds_info["crosswalks"]["ids"][idx]) - xy_cross = cv2_subpixel(transform_points(crosswalk["xyz"][:, :2], world_to_image_space)) + xy_cross = cv2_subpixel(world_to_image_space.dot(crosswalk["xyz"]).T[:, :2]) crosswalks.append(xy_cross) cv2.polylines(img, crosswalks, True, (255, 117, 69), lineType=cv2.LINE_AA, shift=CV2_SHIFT)