Example #1
0
def create_crosswalks_model(map_api: MapAPI) -> CrosswalkModel:
    vertices = []
    vertexType = []

    for element in map_api:
        element_id = MapAPI.id_as_str(element.id)

        if map_api.is_crosswalk(element):
            crosswalk = map_api.get_crosswalk_coords(element_id)
            coords = earclip(crosswalk["xyz"])

            for triangle in coords:

                for vertex in triangle:
                    vertices.append(vertex[0])
                    vertices.append(vertex[1])
                    # z-axis (0 in 2d)
                    vertices.append(0.001)
                    # White
                    vertexType.append(1)

    vertices = np.array(vertices, dtype=np.float32)
    vertexType = np.array(vertexType, dtype=np.float32)

    return CrosswalkModel(vertices, len(vertices) // 3, colors=vertexType)
Example #2
0
 def _get_parent_road_network_segment(self,
                                      lane: Lane) -> RoadNetworkSegment:
     parent_road_network_seg_id: str = MapAPI.id_as_str(
         lane.parent_segment_or_junction)
     parent_road_network_seg: RoadNetworkSegment = self.proto_API[
         parent_road_network_seg_id]
     return parent_road_network_seg
    def get_bounds(self) -> dict:
        """
        For each elements of interest returns bounds [[min_x, min_y],[max_x, max_y]] and proto ids
        Coords are computed by the MapAPI and, as such, are in the world ref system.

        Returns:
            dict: keys are classes of elements, values are dict with `bounds` and `ids` keys
        """
        lanes_ids = []
        crosswalks_ids = []

        lanes_bounds = np.empty(
            (0, 2, 2), dtype=np.float)  # [(X_MIN, Y_MIN), (X_MAX, Y_MAX)]
        crosswalks_bounds = np.empty(
            (0, 2, 2), dtype=np.float)  # [(X_MIN, Y_MIN), (X_MAX, Y_MAX)]

        for element in self.proto_API:
            element_id = MapAPI.id_as_str(element.id)

            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]))

                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])

                crosswalks_bounds = np.append(
                    crosswalks_bounds,
                    np.asarray([[[x_min, y_min], [x_max, y_max]]]),
                    axis=0,
                )
                crosswalks_ids.append(element_id)

        return {
            "lanes": {
                "bounds": lanes_bounds,
                "ids": lanes_ids
            },
            "crosswalks": {
                "bounds": crosswalks_bounds,
                "ids": crosswalks_ids
            },
        }
    def __init__(
        self,
        render_context: RenderContext,
        semantic_map_path: str,
        world_to_ecef: np.ndarray,
    ):
        super(TLSemanticRasterizer, self).__init__()
        self.render_context = render_context
        self.raster_size = render_context.raster_size_px
        self.pixel_size = render_context.pixel_size_m
        self.ego_center = render_context.center_in_raster_ratio

        self.world_to_ecef = world_to_ecef

        self.proto_API = MapAPI(semantic_map_path, world_to_ecef)

        self.bounds_info = self.get_bounds()
        self.raster_channels = 3
Example #5
0
    def __init__(self, raster_size: Tuple[int, int],
                 pixel_size: Union[np.ndarray, list,
                                   float], ego_center: np.ndarray,
                 filter_agents_threshold: float, history_num_frames: int,
                 semantic_map_path: str, world_to_ecef: np.ndarray):
        super().__init__()

        self.raster_size = raster_size
        self.pixel_size = pixel_size

        if isinstance(pixel_size, np.ndarray) or isinstance(pixel_size, list):
            self.pixel_size = pixel_size[0]

        self.filter_agents_threshold = filter_agents_threshold

        self.proto_API = MapAPI(semantic_map_path, world_to_ecef)

        # Create and hide a window
        DisplayManager.create_display(width=raster_size[0],
                                      height=raster_size[1])

        self.output_fbo = initialize_framebuffer_object(width=raster_size[0],
                                                        height=raster_size[1])

        self.loader: Loader = Loader()
        self.shader: StaticShader = StaticShader()
        self.camera: Camera = Camera()
        self.renderer: Renderer = Renderer(display_width=raster_size[0],
                                           display_height=raster_size[1],
                                           camera=self.camera,
                                           pixel_size=self.pixel_size)

        self.renderer.add_renderer('entity_renderer', EntityRenderer())
        self.renderer.add_renderer('map_renderer', MapRenderer())

        self.agent_model: Cube = Cube()
        self.agent_model.load_to_vao(self.loader)

        self.lane_surface_model: LaneSurfaceModel = create_lane_surface_model(
            self.proto_API)
        self.lane_surface_model.load_to_vao(self.loader)

        self.lane_lines_model: LaneLinesModel = create_lane_line_model(
            self.proto_API)
        self.lane_lines_model.load_to_vao(self.loader)

        self.crosswalk_model: CrosswalkModel = create_crosswalks_model(
            self.proto_API)
        self.crosswalk_model.load_to_vao(self.loader)

        self.agents = []
        self.map_layers = []
Example #6
0
def create_lane_line_model(map_api: MapAPI) -> LaneLinesModel:
    vertices = []
    vertexType = []

    for element in map_api:
        element_id = MapAPI.id_as_str(element.id)

        if map_api.is_lane(element):
            lane = map_api.get_lane_coords(element_id)
            lane_coords = lane["xyz_left"]

            for idx in range(len(lane_coords) - 1):
                vertices.append(lane_coords[idx][0])
                vertices.append(lane_coords[idx][1])
                vertices.append(1.)
                vertexType.append(3)

                vertices.append(lane_coords[idx + 1][0])
                vertices.append(lane_coords[idx + 1][1])
                vertices.append(1.)
                vertexType.append(3)

            lane_coords = lane["xyz_right"]

            for idx in range(len(lane_coords) - 1):
                vertices.append(lane_coords[idx][0])
                vertices.append(lane_coords[idx][1])
                vertices.append(1.)
                vertexType.append(3)

                vertices.append(lane_coords[idx + 1][0])
                vertices.append(lane_coords[idx + 1][1])
                vertices.append(1.)
                vertexType.append(3)

    vertices = np.array(vertices, dtype=np.float32)
    vertexType = np.array(vertexType, dtype=np.float32)

    return LaneLinesModel(vertices, len(vertices) // 3, vertexType)
Example #7
0
def create_lane_surface_model(map_api: MapAPI) -> LaneSurfaceModel:
    vertices = []
    vertexType = []

    if obj_exists("lane_surface_vertices", './cache'):
        vertices = obj_load("lane_surface_vertices", './cache')
        vertexType = obj_load("lane_surface_vertex_types", "./cache")
        return LaneSurfaceModel(vertices,
                                len(vertices) // 3,
                                colors=vertexType)

    print("Generating triangles from lanes' polygon dataponts...")
    for element in tqdm(map_api):
        element_id = MapAPI.id_as_str(element.id)

        if map_api.is_lane(element):
            lane = map_api.get_lane_coords(element_id)
            left = lane["xyz_left"]
            right = lane["xyz_right"]

            coords = np.vstack((left, np.flip(right, 0)))
            coords = earclip(coords)

            for triangle in coords:

                for vertex in triangle:
                    vertices.append(vertex[0])
                    vertices.append(vertex[1])
                    # z-axis (0 in 2d)
                    vertices.append(0.0001)
                    vertexType.append(1000)

    vertices = np.array(vertices, dtype=np.float32)
    vertexType = np.array(vertexType, dtype=np.float32)

    obj_save(vertices, "lane_surface_vertices", "./cache")
    obj_save(vertexType, "lane_surface_vertex_types", "./cache")

    return LaneSurfaceModel(vertices, len(vertices) // 3, colors=vertexType)
Example #8
0
def render_semantic_map(
        self, center_in_world: np.ndarray, raster_from_world: np.ndarray, tl_faces: np.ndarray = None,
        tl_face_color=True
) -> th.Union[torch.Tensor, dict]:
    """Renders the semantic map at given x,y coordinates.
    Args:
        center_in_world (np.ndarray): XY of the image center in world ref system
        raster_from_world (np.ndarray):
    Returns:
        th.Union[torch.Tensor, dict]
    """
    # filter using half a radius from the center
    raster_radius = float(np.linalg.norm(self.raster_size * self.pixel_size)) / 2

    # get active traffic light faces
    if tl_face_color:
        active_tl_ids = set(filter_tl_faces_by_status(tl_faces, "ACTIVE")["face_id"].tolist())

    # setup canvas
    raster_size = self.render_context.raster_size_px
    res = dict(path=list(), path_type=list())
    for idx in elements_within_bounds(center_in_world, self.bounds_info["lanes"]["bounds"], raster_radius):
        lane = self.proto_API[self.bounds_info["lanes"]["ids"][idx]].element.lane

        # 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], raster_from_world))
        xy_right = cv2_subpixel(transform_points(lane_coords["xyz_right"][:, :2], raster_from_world))
        xy_left = normalize_line(xy_left)
        xy_right = normalize_line(xy_right)

        lane_type = "black"  # no traffic light face is controlling this lane
        if tl_face_color:
            lane_tl_ids = set([MapAPI.id_as_str(la_tc) for la_tc in lane.traffic_controls])
            for tl_id in lane_tl_ids.intersection(active_tl_ids):
                if self.proto_API.is_traffic_face_colour(tl_id, "red"):
                    lane_type = "red"
                elif self.proto_API.is_traffic_face_colour(tl_id, "green"):
                    lane_type = "green"
                elif self.proto_API.is_traffic_face_colour(tl_id, "yellow"):
                    lane_type = "yellow"

        for vector in [xy_left, xy_right]:
            vector = crop_tensor(vector, raster_size)
            if len(vector):
                res['path'].append(vector)
                res['path_type'].append(path_type_to_number(lane_type))
    return res
Example #9
0
    def render_semantic_map(
            self, center_world: np.ndarray, raster_from_world: np.ndarray, history_tl_faces: List[np.ndarray]
    ) -> np.ndarray:
        """Renders the semantic map at given x,y coordinates.

        Args:
            center_world (np.ndarray): XY of the image center in world ref system
            raster_from_world (np.ndarray):
        Returns:
            np.ndarray: RGB raster

        """

        img = 255 * np.ones(shape=(self.raster_size[1], self.raster_size[0], 3), dtype=np.uint8)
        tl_img = 255 * np.ones(shape=(self.raster_size[1], self.raster_size[0], 3), dtype=np.uint8)

        # filter using half a radius from the center
        raster_radius = float(np.linalg.norm(self.raster_size * self.pixel_size)) / 2

        # get active traffic light faces
        all_active_tls = [filter_tl_faces_by_status(tl_faces, "ACTIVE") for tl_faces in history_tl_faces]
        curr_active_tl_ids = create_active_tl_dict(all_active_tls[0], all_active_tls[1:])

        # plot lanes
        lanes_lines = defaultdict(list)
        persistence_lines = defaultdict(list)

        for idx in elements_within_bounds(center_world, self.bounds_info["lanes"]["bounds"], raster_radius):

            lane = self.proto_API[self.bounds_info["lanes"]["ids"][idx]].element.lane

            # 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], raster_from_world))
            xy_right = cv2_subpixel(transform_points(lane_coords["xyz_right"][:, :2], raster_from_world))
            lanes_area = np.vstack((xy_left, np.flip(xy_right, 0)))  # start->end left then end->start right

            # 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)

            # Create lane lines for the current index
            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])
            for tl_id in lane_tl_ids.intersection(set(curr_active_tl_ids.keys())):
                if self.proto_API.is_traffic_face_colour(tl_id, "red"):
                    lane_type = "red"
                elif self.proto_API.is_traffic_face_colour(tl_id, "green"):
                    lane_type = "green"
                elif self.proto_API.is_traffic_face_colour(tl_id, "yellow"):
                    lane_type = "yellow"

                persistence_val = curr_active_tl_ids[tl_id]
                persistence_lines[persistence_val].extend([xy_left, xy_right])

            lanes_lines[lane_type].extend([xy_left, xy_right])

        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)
        cv2.polylines(img, lanes_lines["yellow"], False, (255, 255, 0), lineType=cv2.LINE_AA, shift=CV2_SHIFT)
        cv2.polylines(img, lanes_lines["red"], False, (255, 0, 0), lineType=cv2.LINE_AA, shift=CV2_SHIFT)

        # Fill in tl persistence
        for p in persistence_lines.keys():
            cv2.polylines(tl_img, persistence_lines[p], False, (0, 0, int(p)), lineType=cv2.LINE_AA, shift=CV2_SHIFT)
        # if True: plt.imshow(tl_img); plt.title(str(len(persistence_lines))); plt.show()

        # plot crosswalks
        crosswalks = []
        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], raster_from_world))
            crosswalks.append(xy_cross)

        cv2.polylines(img, crosswalks, True, (255, 117, 69), lineType=cv2.LINE_AA, shift=CV2_SHIFT)

        tl_img = np.sum(tl_img, axis=-1)

        return np.concatenate([img, tl_img[:, :, np.newaxis]], axis=-1)
Example #10
0
    def get_lanes(self, center_in_world: np.ndarray,
                  raster_from_world: np.ndarray, active_tl_ids: set,
                  raster_radius: float) -> Iterator[Dict[str, Any]]:

        lane_indexes = elements_within_bounds(
            center_in_world, self.bounds_info["lanes"]["bounds"],
            raster_radius)
        for idx in lane_indexes:
            lane_id = self.bounds_info["lanes"]["ids"][idx]
            lane = self.proto_API[lane_id].element.lane
            parent_road = self._get_parent_road_network_segment(lane)
            lane_coords = self.proto_API.get_lane_coords(
                self.bounds_info["lanes"]["ids"][idx])

            lane_tl_ids = set(
                [MapAPI.id_as_str(la_tc) for la_tc in lane.traffic_controls])
            lane_tl_ids = lane_tl_ids.intersection(active_tl_ids)
            tl_categories = self._categorize_tl(lane_tl_ids)

            centroids = [lane_coords["xyz_left"], lane_coords["xyz_right"]]

            for centroid in centroids:
                lane_info = {
                    "lane_id":
                    lane_id,
                    "access_restriction":
                    self._get_access_restriction(lane),
                    "orientation_in_parent_segment":
                    self._get_orientation(lane),
                    "turn_type_in_parent_junction":
                    self._get_turn_type(lane),
                    "centroid":
                    transform_points(centroid[:, :2], raster_from_world),
                    "has_adjacent_lane_change_left":
                    len(MapAPI.id_as_str(lane.adjacent_lane_change_left)) > 0,
                    "has_adjacent_lane_change_right":
                    len(MapAPI.id_as_str(lane.adjacent_lane_change_right)) > 0,
                    "tl_count":
                    len(lane.traffic_controls),
                    "tl_signal_red_face_count":
                    len(tl_categories["signal_red_face"]),
                    "tl_signal_yellow_face_count":
                    len(tl_categories["signal_yellow_face"]),
                    "tl_signal_green_face_count":
                    len(tl_categories["signal_green_face"]),
                    "tl_signal_left_arrow_red_face_count":
                    len(tl_categories["signal_left_arrow_red_face"]),
                    "tl_signal_left_arrow_yellow_face_count":
                    len(tl_categories["signal_left_arrow_yellow_face"]),
                    "tl_signal_left_arrow_green_face_count":
                    len(tl_categories["signal_left_arrow_green_face"]),
                    "tl_signal_right_arrow_red_face_count":
                    len(tl_categories["signal_right_arrow_red_face"]),
                    "tl_signal_right_arrow_yellow_face_count":
                    len(tl_categories["signal_right_arrow_yellow_face"]),
                    "tl_signal_right_arrow_green_face_count":
                    len(tl_categories["signal_right_arrow_green_face"]),
                    "can_have_parked_cars":
                    lane.can_have_parked_cars,
                    "road_speed_limit_meters_per_second":
                    self._get_speed_limit(parent_road),
                    "road_class":
                    self._get_road_class(parent_road),
                    "road_direction":
                    self._get_road_direction(parent_road),
                    "road_fwd_lane_count":
                    self._get_fwd_lane_count(parent_road),
                    "road_bwd_lane_count":
                    self._get_bwd_lane_count(parent_road)
                }

                yield lane_info
class TLSemanticRasterizer(Rasterizer):
    """
    Rasteriser for the vectorised semantic map (generally loaded from json files).
    """
    @staticmethod
    def from_cfg(cfg, data_manager):
        raster_cfg = cfg["raster_params"]
        # map_type = raster_cfg["map_type"]
        dataset_meta_key = raster_cfg["dataset_meta_key"]

        render_context = RenderContext(
            raster_size_px=np.array(raster_cfg["raster_size"]),
            pixel_size_m=np.array(raster_cfg["pixel_size"]),
            center_in_raster_ratio=np.array(raster_cfg["ego_center"]),
        )
        # filter_agents_threshold = raster_cfg["filter_agents_threshold"]
        # history_num_frames = cfg["model_params"]["history_num_frames"]

        semantic_map_filepath = data_manager.require(
            raster_cfg["semantic_map_key"])
        try:
            dataset_meta = _load_metadata(dataset_meta_key, data_manager)
            world_to_ecef = np.array(dataset_meta["world_to_ecef"],
                                     dtype=np.float64)
        except (KeyError, FileNotFoundError
                ):  # TODO remove when new dataset version is available
            world_to_ecef = get_hardcoded_world_to_ecef()

        return TLSemanticRasterizer(render_context, semantic_map_filepath,
                                    world_to_ecef)

    def __init__(
        self,
        render_context: RenderContext,
        semantic_map_path: str,
        world_to_ecef: np.ndarray,
    ):
        super(TLSemanticRasterizer, self).__init__()
        self.render_context = render_context
        self.raster_size = render_context.raster_size_px
        self.pixel_size = render_context.pixel_size_m
        self.ego_center = render_context.center_in_raster_ratio

        self.world_to_ecef = world_to_ecef

        self.proto_API = MapAPI(semantic_map_path, world_to_ecef)

        self.bounds_info = self.get_bounds()
        self.raster_channels = 3

    # TODO is this the right place for this function?
    def get_bounds(self) -> dict:
        """
        For each elements of interest returns bounds [[min_x, min_y],[max_x, max_y]] and proto ids
        Coords are computed by the MapAPI and, as such, are in the world ref system.

        Returns:
            dict: keys are classes of elements, values are dict with `bounds` and `ids` keys
        """
        lanes_ids = []
        crosswalks_ids = []

        lanes_bounds = np.empty(
            (0, 2, 2), dtype=np.float)  # [(X_MIN, Y_MIN), (X_MAX, Y_MAX)]
        crosswalks_bounds = np.empty(
            (0, 2, 2), dtype=np.float)  # [(X_MIN, Y_MIN), (X_MAX, Y_MAX)]

        for element in self.proto_API:
            element_id = MapAPI.id_as_str(element.id)

            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]))

                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])

                crosswalks_bounds = np.append(
                    crosswalks_bounds,
                    np.asarray([[[x_min, y_min], [x_max, y_max]]]),
                    axis=0,
                )
                crosswalks_ids.append(element_id)

        return {
            "lanes": {
                "bounds": lanes_bounds,
                "ids": lanes_ids
            },
            "crosswalks": {
                "bounds": crosswalks_bounds,
                "ids": crosswalks_ids
            },
        }

    def rasterize(
        self,
        history_frames: np.ndarray,
        history_agents: List[np.ndarray],
        history_tl_faces: List[np.ndarray],
        agent: Optional[np.ndarray] = None,
    ) -> np.ndarray:
        if agent is None:
            ego_translation_m = history_frames[0]["ego_translation"]
            ego_yaw_rad = rotation33_as_yaw(history_frames[0]["ego_rotation"])
        else:
            ego_translation_m = np.append(
                agent["centroid"], history_frames[0]["ego_translation"][-1])
            ego_yaw_rad = agent["yaw"]

        raster_from_world = self.render_context.raster_from_world(
            ego_translation_m, ego_yaw_rad)
        world_from_raster = np.linalg.inv(raster_from_world)

        # get XY of center pixel in world coordinates
        center_in_raster_px = np.asarray(self.raster_size) * (0.5, 0.5)
        center_in_world_m = transform_point(center_in_raster_px,
                                            world_from_raster)

        sem_im = self.render_semantic_map(center_in_world_m, raster_from_world,
                                          history_tl_faces[0])
        return sem_im.astype(np.float32) / 255

    def render_semantic_map(self, center_in_world: np.ndarray,
                            raster_from_world: np.ndarray,
                            tl_faces: np.ndarray) -> np.ndarray:
        """Renders the semantic map at given x,y coordinates.

        Args:
            center_in_world (np.ndarray): XY of the image center in world ref system
            raster_from_world (np.ndarray):
        Returns:
            np.ndarray: RGB raster

        """

        img = 255 * np.ones(
            shape=(self.raster_size[1], self.raster_size[0], 3),
            dtype=np.uint8)

        # filter using half a radius from the center
        raster_radius = float(
            np.linalg.norm(self.raster_size * self.pixel_size)) / 2

        # get active traffic light faces
        active_tl_ids = set(
            filter_tl_faces_by_status(tl_faces, "ACTIVE")["face_id"].tolist())

        # plot lanes
        lanes_lines = defaultdict(list)

        for idx in elements_within_bounds(center_in_world,
                                          self.bounds_info["lanes"]["bounds"],
                                          raster_radius):
            lane = self.proto_API[self.bounds_info["lanes"]["ids"]
                                  [idx]].element.lane

            # 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],
                                 raster_from_world))
            xy_right = cv2_subpixel(
                transform_points(lane_coords["xyz_right"][:, :2],
                                 raster_from_world))
            lanes_area = np.vstack(
                (xy_left, np.flip(xy_right,
                                  0)))  # start->end left then end->start right

            # 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)

            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])
            for tl_id in lane_tl_ids.intersection(active_tl_ids):
                if self.proto_API.is_traffic_face_colour(tl_id, "red"):
                    lane_type = "red"
                elif self.proto_API.is_traffic_face_colour(tl_id, "green"):
                    lane_type = "green"
                elif self.proto_API.is_traffic_face_colour(tl_id, "yellow"):
                    lane_type = "yellow"

            lanes_lines[lane_type].extend([xy_left, xy_right])

        # For debugging
        # import IPython; IPython.embed()
        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)
        cv2.polylines(img,
                      lanes_lines["yellow"],
                      False, (255, 255, 0),
                      lineType=cv2.LINE_AA,
                      shift=CV2_SHIFT)
        cv2.polylines(img,
                      lanes_lines["red"],
                      False, (255, 0, 0),
                      lineType=cv2.LINE_AA,
                      shift=CV2_SHIFT)

        # plot crosswalks
        crosswalks = []
        for idx in elements_within_bounds(
                center_in_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], raster_from_world))
            crosswalks.append(xy_cross)

        cv2.polylines(img,
                      crosswalks,
                      True, (255, 117, 69),
                      lineType=cv2.LINE_AA,
                      shift=CV2_SHIFT)

        return img

    def to_rgb(self, in_im: np.ndarray, **kwargs: dict) -> np.ndarray:
        return (in_im * 255).astype(np.uint8)
    def render_semantic_map(self, center_in_world: np.ndarray,
                            raster_from_world: np.ndarray,
                            tl_faces: np.ndarray) -> np.ndarray:
        """Renders the semantic map at given x,y coordinates.

        Args:
            center_in_world (np.ndarray): XY of the image center in world ref system
            raster_from_world (np.ndarray):
        Returns:
            np.ndarray: RGB raster

        """

        img = 255 * np.ones(
            shape=(self.raster_size[1], self.raster_size[0], 3),
            dtype=np.uint8)

        # filter using half a radius from the center
        raster_radius = float(
            np.linalg.norm(self.raster_size * self.pixel_size)) / 2

        # get active traffic light faces
        active_tl_ids = set(
            filter_tl_faces_by_status(tl_faces, "ACTIVE")["face_id"].tolist())

        # plot lanes
        lanes_lines = defaultdict(list)

        for idx in elements_within_bounds(center_in_world,
                                          self.bounds_info["lanes"]["bounds"],
                                          raster_radius):
            lane = self.proto_API[self.bounds_info["lanes"]["ids"]
                                  [idx]].element.lane

            # 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],
                                 raster_from_world))
            xy_right = cv2_subpixel(
                transform_points(lane_coords["xyz_right"][:, :2],
                                 raster_from_world))
            lanes_area = np.vstack(
                (xy_left, np.flip(xy_right,
                                  0)))  # start->end left then end->start right

            # 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)

            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])
            for tl_id in lane_tl_ids.intersection(active_tl_ids):
                if self.proto_API.is_traffic_face_colour(tl_id, "red"):
                    lane_type = "red"
                elif self.proto_API.is_traffic_face_colour(tl_id, "green"):
                    lane_type = "green"
                elif self.proto_API.is_traffic_face_colour(tl_id, "yellow"):
                    lane_type = "yellow"

            lanes_lines[lane_type].extend([xy_left, xy_right])

        # For debugging
        # import IPython; IPython.embed()
        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)
        cv2.polylines(img,
                      lanes_lines["yellow"],
                      False, (255, 255, 0),
                      lineType=cv2.LINE_AA,
                      shift=CV2_SHIFT)
        cv2.polylines(img,
                      lanes_lines["red"],
                      False, (255, 0, 0),
                      lineType=cv2.LINE_AA,
                      shift=CV2_SHIFT)

        # plot crosswalks
        crosswalks = []
        for idx in elements_within_bounds(
                center_in_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], raster_from_world))
            crosswalks.append(xy_cross)

        cv2.polylines(img,
                      crosswalks,
                      True, (255, 117, 69),
                      lineType=cv2.LINE_AA,
                      shift=CV2_SHIFT)

        return img
Example #13
0
 def render_lane(self, ax, lane):
     coords = self._map_api.get_lane_coords(MapAPI.id_as_str(lane.id))
     self.render_boundary(ax, coords["xyz_left"])
     self.render_boundary(ax, coords["xyz_right"])
Example #14
0
    draw_trajectory(im, target_positions_pixels, data["target_yaws"], TARGET_POINTS_COLOR)
    clear_output(wait=True)
    display(PIL.Image.fromarray(im[::-1]))

# %% [markdown]
# We can also take a general view of the street from a matplotlib-type perspective. I borrow this from [this wonderful notebook](https://www.kaggle.com/t3nyks/lyft-working-with-map-api)

# %% [code] {"_kg_hide-input":true}
from l5kit.data.map_api import MapAPI
from l5kit.rasterization.rasterizer_builder import _load_metadata

semantic_map_filepath = dm.require(cfg["raster_params"]["semantic_map_key"])
dataset_meta = _load_metadata(cfg["raster_params"]["dataset_meta_key"], dm)
world_to_ecef = np.array(dataset_meta["world_to_ecef"], dtype=np.float64)

map_api = MapAPI(semantic_map_filepath, world_to_ecef)
MAP_LAYERS = ["junction", "node", "segment", "lane"]


def element_of_type(elem, layer_name):
    return elem.element.HasField(layer_name)


def get_elements_from_layer(map_api, layer_name):
    return [elem for elem in map_api.elements if element_of_type(elem, layer_name)]


class MapRenderer:
    
    def __init__(self, map_api):
        self._color_map = dict(drivable_area='#a6cee3',
Example #15
0
def render_semantic_map(self,
                        center_in_world: np.ndarray,
                        raster_from_world: np.ndarray,
                        tl_faces: np.ndarray = None,
                        svg_args=None,
                        face_color=False) -> draw.Drawing:
    """Renders the semantic map at given x,y coordinates.
    Args:
        center_in_world (np.ndarray): XY of the image center in world ref system
        raster_from_world (np.ndarray):
    Returns:
        drawvg.Drawing object
    """
    # filter using half a radius from the center
    raster_radius = float(np.linalg.norm(
        self.raster_size * self.pixel_size)) / 2
    svg_args = svg_args or dict()

    # get active traffic light faces
    if face_color:
        active_tl_ids = set(
            filter_tl_faces_by_status(tl_faces, "ACTIVE")["face_id"].tolist())

    # setup canvas
    raster_size = self.render_context.raster_size_px
    origin = self.render_context.origin
    d = draw.Drawing(*raster_size,
                     origin=tuple(origin),
                     displayInline=False,
                     **svg_args)

    for idx in elements_within_bounds(center_in_world,
                                      self.bounds_info["lanes"]["bounds"],
                                      raster_radius):
        lane = self.proto_API[self.bounds_info["lanes"]["ids"]
                              [idx]].element.lane

        # 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],
                             raster_from_world))
        xy_right = cv2_subpixel(
            transform_points(lane_coords["xyz_right"][:, :2],
                             raster_from_world))

        if face_color:
            lane_type = "black"  # 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])
            for tl_id in lane_tl_ids.intersection(active_tl_ids):
                if self.proto_API.is_traffic_face_colour(tl_id, "red"):
                    lane_type = "red"
                elif self.proto_API.is_traffic_face_colour(tl_id, "green"):
                    lane_type = "green"
                elif self.proto_API.is_traffic_face_colour(tl_id, "yellow"):
                    lane_type = "yellow"

        for line in [xy_left, xy_right]:
            vector = line / CV2_SHIFT_VALUE
            vector[:, 1] = raster_size[1] + origin[1] - vector[:, 1]
            vector[:, 0] = vector[:, 0] + origin[0]
            drawn_shape = draw.Lines(
                *vector.reshape(-1)) if not face_color else draw.Lines(
                    *vector.reshape(-1), close=False, stroke=lane_type)
            d.append(drawn_shape)
    return d
Example #16
0
def _get_frame_data(mapAPI: MapAPI, frame: np.ndarray,
                    agents_frame: np.ndarray,
                    tls_frame: np.ndarray) -> FrameVisualization:
    """Get visualisation objects for the current frame.

    :param mapAPI: mapAPI object (used for lanes, crosswalks etc..)
    :param frame: the current frame (used for ego)
    :param agents_frame: agents in this frame
    :param tls_frame: the tls of this frame
    :return: A FrameVisualization object. NOTE: trajectory are not included here
    """
    ego_xy = frame["ego_translation"][:2]

    #################
    # plot lanes
    lane_indices = indices_in_bounds(ego_xy,
                                     mapAPI.bounds_info["lanes"]["bounds"], 50)
    active_tl_ids = set(
        filter_tl_faces_by_status(tls_frame, "ACTIVE")["face_id"].tolist())
    lanes_vis: List[LaneVisualization] = []

    for idx, lane_idx in enumerate(lane_indices):
        lane_idx = mapAPI.bounds_info["lanes"]["ids"][lane_idx]

        lane_tl_ids = set(mapAPI.get_lane_traffic_control_ids(lane_idx))
        lane_colour = "gray"
        for tl_id in lane_tl_ids.intersection(active_tl_ids):
            lane_colour = COLORS[mapAPI.get_color_for_face(tl_id)]

        lane_coords = mapAPI.get_lane_coords(lane_idx)
        left_lane = lane_coords["xyz_left"][:, :2]
        right_lane = lane_coords["xyz_right"][::-1, :2]

        lanes_vis.append(
            LaneVisualization(xs=np.hstack((left_lane[:, 0], right_lane[:,
                                                                        0])),
                              ys=np.hstack((left_lane[:, 1], right_lane[:,
                                                                        1])),
                              color=lane_colour))

    #################
    # plot crosswalks
    crosswalk_indices = indices_in_bounds(
        ego_xy, mapAPI.bounds_info["crosswalks"]["bounds"], 50)
    crosswalks_vis: List[CWVisualization] = []

    for idx in crosswalk_indices:
        crosswalk = mapAPI.get_crosswalk_coords(
            mapAPI.bounds_info["crosswalks"]["ids"][idx])
        crosswalks_vis.append(
            CWVisualization(xs=crosswalk["xyz"][:, 0],
                            ys=crosswalk["xyz"][:, 1],
                            color="yellow"))
    #################
    # plot ego and agents
    agents_frame = np.insert(agents_frame, 0, get_ego_as_agent(frame))
    box_world_coords = get_box_world_coords(agents_frame)

    # ego
    ego_vis = EgoVisualization(xs=box_world_coords[0, :, 0],
                               ys=box_world_coords[0, :, 1],
                               color="red",
                               center_x=agents_frame["centroid"][0, 0],
                               center_y=agents_frame["centroid"][0, 1])

    # agents
    agents_frame = agents_frame[1:]
    box_world_coords = box_world_coords[1:]

    agents_vis: List[AgentVisualization] = []
    for agent, box_coord in zip(agents_frame, box_world_coords):
        label_index = np.argmax(agent["label_probabilities"])
        agent_type = PERCEPTION_LABELS[label_index]
        agents_vis.append(
            AgentVisualization(xs=box_coord[..., 0],
                               ys=box_coord[..., 1],
                               color="#1F77B4" if agent_type not in COLORS else
                               COLORS[agent_type],
                               track_id=agent["track_id"],
                               agent_type=PERCEPTION_LABELS[label_index],
                               prob=agent["label_probabilities"][label_index]))

    return FrameVisualization(ego=ego_vis,
                              agents=agents_vis,
                              lanes=lanes_vis,
                              crosswalks=crosswalks_vis,
                              trajectories=[])