def from_file(cls, path, *args, **kwargs): with open(path, "r") as f: d = json.load(f) points = d["points"] points.append(points[0]) # Close the loop points = interpolate_points(points, 1000) return cls(points, *args, **kwargs)
def __init__(self, pts, nb_checkpoints=100, render_params=None): l = LineString(pts).length n = int(l / 3e-3) # Get number of points for 3 mm spacing self.pts = interpolate_points( np.array(pts), n) # interpolate points to get the right spacing self.x = self.pts[:, 0] self.y = self.pts[:, 1] self.render_params = render_params self.mpt = MultiPoint(self.pts) self.string = LineString(self.pts) # Find starting point and angle self.start_xy = self.x[0], self.y[0] self.start_angle = self.angle_at_index(0) # Get length self.length = self.string.length # Progress tracking setup self.progress = 0. self.progress_idx = 0 self.nb_checkpoints = nb_checkpoints self.checkpoints = [ i * (self.length / self.nb_checkpoints) for i in range(1, self.nb_checkpoints + 1) ] self.next_checkpoint_idx = 0 self.done = False
def _render(self, w=3., h=2., ppm=1500, line_thickness=0.015, save=None, line_color="black", background="white", line_opacity=0.8, dashed=False): """ Render track using open-cv :param w: canvas width in meters :param h: canvas height in meters :param ppm: pixel per meter :param line_thickness: line thickness in meters :param save: path to save :param line_color: string or BGR tuple options: [black, red, green, blue] :param background: string or BGR tuple options: [wood, wood_2, concrete, brick, checkerboard, white, gray] :param line_opacity: opacity of line in range 0, 1 where 0 is fully transparent :return: rendered track image array """ import cv2 w_res = int(round(w * ppm)) h_res = int(round(h * ppm)) t_res = int(round(line_thickness * ppm)) background_bgr = None if isinstance(background, str): background = background.lower() if background == "wood": bg = cv2.imread( os.path.join(root_dir, "track_textures", "wood.jpg")) elif background == "wood_2": bg = cv2.imread( os.path.join(root_dir, "track_textures", "wood_2.jpg")) elif background == "concrete": bg = cv2.imread( os.path.join(root_dir, "track_textures", "concrete.jpg")) elif background == "brick": bg = cv2.imread( os.path.join(root_dir, "track_textures", "brick.jpg")) elif background == "checkerboard": bg = cv2.imread( os.path.join(root_dir, "track_textures", "checkerboard.jpg")) elif background == "white": background_bgr = (255, 255, 255) elif background == "gray": background_bgr = (150, 150, 150) else: raise ValueError("Invalid background string.") if background_bgr: bg = np.ones((h_res, w_res, 3), dtype=np.uint8) bg[:, :, 0] *= background_bgr[0] bg[:, :, 1] *= background_bgr[1] bg[:, :, 2] *= background_bgr[2] else: bg = cv2.resize(bg, (w_res, h_res), interpolation=cv2.INTER_LINEAR) elif isinstance(background, tuple): bg = np.ones((h_res, w_res, 3), dtype=np.uint8) bg[:, :, 0] *= background[0] bg[:, :, 1] *= background[1] bg[:, :, 2] *= background[2] else: raise ValueError("Invalid background.") if isinstance(line_color, str): line_color = line_color.lower() if line_color == "black": line_bgr = (0, 0, 0) elif line_color == "red": line_bgr = (0, 0, 255) elif line_color == "green": line_bgr = (0, 128, 0) elif line_color == "blue": line_bgr = (255, 0, 0) else: raise ValueError("Invalid color string.") elif isinstance(line_color, tuple): line_bgr = line_color else: raise ValueError("Invalid line_color.") line = bg.copy() if dashed: pts = interpolate_points(self.pts, 1000) n = self.length / dashed chunks = np.array_split(pts, n)[::2] for c in chunks: for i in range(len(c) - 1): x1, y1 = c[i] x1_img = int(round((x1 + w / 2) * ppm, ndigits=0)) y1_img = int(round(h_res - (y1 + h / 2) * ppm, ndigits=0)) x2, y2 = c[i + 1] x2_img = int(round((x2 + w / 2) * ppm, ndigits=0)) y2_img = int(round(h_res - (y2 + h / 2) * ppm, ndigits=0)) cv2.line(line, (x1_img, y1_img), (x2_img, y2_img), color=line_bgr, thickness=t_res, lineType=cv2.LINE_AA) else: for i in range(len(self.pts) - 1): x1, y1 = self.pts[i] x1_img = int(round((x1 + w / 2) * ppm, ndigits=0)) y1_img = int(round(h_res - (y1 + h / 2) * ppm, ndigits=0)) x2, y2 = self.pts[i + 1] x2_img = int(round((x2 + w / 2) * ppm, ndigits=0)) y2_img = int(round(h_res - (y2 + h / 2) * ppm, ndigits=0)) cv2.line(line, (x1_img, y1_img), (x2_img, y2_img), color=line_bgr, thickness=t_res, lineType=cv2.LINE_AA) alpha = line_opacity out = cv2.addWeighted(line, alpha, bg, 1 - alpha, 0) if save is not None: cv2.imwrite(save, out) return out