from argparse import ArgumentTypeError from datetime import timedelta from pathlib import Path from subprocess import run from matplotlib import colormaps from matplotlib.colors import Colormap from pointcloudset import Dataset def load_dataset( bag_file_path: Path, pointcloud_topic: str = "/ouster/points" ) -> Dataset: return Dataset.from_file(bag_file_path, topic=pointcloud_topic) def save_dataset(dataset: Dataset, output_file_path: Path): if not output_file_path.is_dir(): raise ArgumentTypeError(f"{output_file_path} has to be a valid folder!") dataset.to_file(output_file_path) def calculate_average_frame_rate(dataset: Dataset): timestamps = dataset.timestamps time_deltas = [ timestamps[i + 1] - timestamps[i] for i in range(len(timestamps) - 1) ] average_delta = sum(time_deltas, timedelta()) / len(time_deltas) average_frame_rate = 1 / average_delta.total_seconds() return average_frame_rate def existing_file(path_string: str) -> Path: path = Path(path_string) if not path.exists(): raise ArgumentTypeError(f"{path} does not exist!") if not path.is_file(): raise ArgumentTypeError(f"{path} is not a valid file!") return path def existing_folder(path_string: str) -> Path: path = Path(path_string) if not path.exists(): raise ArgumentTypeError(f"{path} does not exist!") if not path.is_dir(): raise ArgumentTypeError(f"{path} is not a valid folder!") return path def existing_path(path_string: str) -> Path: path = Path(path_string) if not path.exists(): raise ArgumentTypeError(f"{path} does not exist!") return path def positive_int(number_str: str) -> int: number_val = int(number_str) if number_val < 0: raise ArgumentTypeError(f"{number_val} is not a positive integer!") return number_val def angle(angle_str: str) -> float: angle_val = float(angle_str) if angle_val < 0 or angle_val >= 360: raise ArgumentTypeError( f"{angle_val} is not a valid angle! Needs to be in [0, 360)" ) return angle_val def angle_width(angle_str: str) -> float: angle_val = float(angle_str) if angle_val < 0 or angle_val > 360: raise ArgumentTypeError( f"{angle_val} is not a valid angle width! Needs to be in [0, 360]" ) return angle_val def get_colormap_with_special_missing_color( colormap_name: str, missing_data_color: str = "black", reverse: bool = False ) -> Colormap: colormap = ( colormaps[colormap_name] if not reverse else colormaps[f"{colormap_name}_r"] ) colormap.set_bad(missing_data_color) return colormap def create_video_from_images( input_images_pattern: str, output_file: Path, frame_rate: int ) -> None: # Construct the ffmpeg command command = [ "ffmpeg", "-y", "-framerate", str(frame_rate), "-i", input_images_pattern, "-c:v", "libx264", "-profile:v", "high", "-crf", "20", "-pix_fmt", "yuv420p", output_file.as_posix(), ] run(command, check=True)