def show_image_with_boxes(img: np.ndarray,
                          objects: Iterable[ObjectLabelRecord],
                          calib: Calibration) -> np.ndarray:
    """Show image with 2D bounding boxes."""
    img1 = np.copy(img)

    h, w = np.shape(img1)[0:2]
    planes = generate_frustum_planes(calib.K, calib.camera)
    assert planes is not None

    for obj in objects:
        if obj.occlusion == 100:
            continue
        box3d_pts_3d = obj.as_3d_bbox()
        uv_cam = calib.project_ego_to_cam(box3d_pts_3d)

        img1 = obj.render_clip_frustum_cv2(
            img1,
            uv_cam[:, :3],
            planes.copy(),
            copy.deepcopy(calib.camera_config),
            linewidth=3,
        )

    return img1
Esempio n. 2
0
def test_generate_frustum_planes_stereo() -> None:
    """Test generate_frustum_planes() for a stereo camera.

    Skew is 0.0.
    """
    near_clip_dist = 3.56  # arbitrary value
    K = np.eye(3)
    # Set "focal_length_x_px_"
    K[0, 0] = 3666.534329132812

    # Set "focal_length_y_px_"
    K[1, 1] = 3673.5030423482513

    # Set "focal_center_x_px_"
    K[0, 2] = 1235.0158218941356

    # Set "focal_center_y_px_"
    K[1, 2] = 1008.4536901420888

    camera_name = "stereo_front_left"
    img_height = 2056
    img_width = 2464
    planes = generate_frustum_planes(K,
                                     camera_name,
                                     near_clip_dist=near_clip_dist)
    if planes is None:
        assert False
    left_plane, right_plane, near_plane, low_plane, top_plane = planes

    fx = K[0, 0]
    left_plane_gt = np.array([fx, 0.0, img_width / 2.0, 0.0])
    right_plane_gt = np.array([-fx, 0.0, img_width / 2.0, 0.0])
    near_plane_gt = np.array([0.0, 0.0, 1.0, -near_clip_dist])
    low_plane_gt = np.array([0.0, -fx, img_height / 2.0, 0.0])
    top_plane_gt = np.array([0.0, fx, img_height / 2.0, 0.0])

    assert np.allclose(left_plane,
                       left_plane_gt / np.linalg.norm(left_plane_gt))
    assert np.allclose(right_plane,
                       right_plane_gt / np.linalg.norm(right_plane_gt))
    assert np.allclose(low_plane, low_plane_gt / np.linalg.norm(low_plane_gt))
    assert np.allclose(top_plane, top_plane_gt / np.linalg.norm(top_plane_gt))
    assert np.allclose(near_plane, near_plane_gt)
Esempio n. 3
0
def test_generate_frustum_planes_ring_cam() -> None:
    """Test generate_frustum_planes() for a ring camera.

    Skew is 0.0.
    """
    near_clip_dist = 6.89  # arbitrary value
    K = np.eye(3)
    # Set "focal_length_x_px_"
    K[0, 0] = 1402.4993697398709

    # Set "focal_length_y_px_"
    K[1, 1] = 1405.1207294310225

    # Set "focal_center_x_px_"
    K[0, 2] = 957.8471720086527

    # Set "focal_center_y_px_"
    K[1, 2] = 600.442948946496

    camera_name = "ring_front_right"
    img_height = 1200
    img_width = 1920
    planes = generate_frustum_planes(K,
                                     camera_name,
                                     near_clip_dist=near_clip_dist)
    if planes is None:
        assert False
    left_plane, right_plane, near_plane, low_plane, top_plane = planes

    fx = K[0, 0]
    left_plane_gt = np.array([fx, 0.0, img_width / 2.0, 0.0])
    right_plane_gt = np.array([-fx, 0.0, img_width / 2.0, 0.0])
    near_plane_gt = np.array([0.0, 0.0, 1.0, -near_clip_dist])
    low_plane_gt = np.array([0.0, -fx, img_height / 2.0, 0.0])
    top_plane_gt = np.array([0.0, fx, img_height / 2.0, 0.0])

    assert np.allclose(left_plane,
                       left_plane_gt / np.linalg.norm(left_plane_gt))
    assert np.allclose(right_plane,
                       right_plane_gt / np.linalg.norm(right_plane_gt))
    assert np.allclose(low_plane, low_plane_gt / np.linalg.norm(low_plane_gt))
    assert np.allclose(top_plane, top_plane_gt / np.linalg.norm(top_plane_gt))
    assert np.allclose(near_plane, near_plane_gt)
        plot_frustum_planes_and_normals,
        populate_frustum_voxels,
    )
except ImportError:
    MAYAVI_MISSING = True
else:
    MAYAVI_MISSING = False

_TEST_DIR = pathlib.Path(__file__).parent.parent / "tests"

if not MAYAVI_MISSING:
    calib = load_calib(
        os.fspath(_TEST_DIR /
                  "test_data/tracking/1/vehicle_calibration_info.json")
    )["ring_front_center"]
    planes = generate_frustum_planes(calib.K, calib.camera)
    assert planes is not None

skip_if_mayavi_missing = pytest.mark.skipif(
    MAYAVI_MISSING,
    reason=
    "Could not test functionality that depends on mayavi because mayavi is missing.",
)


@skip_if_mayavi_missing  # type: ignore
def test_plot_frustum_planes_and_normals() -> None:
    """"""

    assert planes is not None
    plot_frustum_planes_and_normals(planes,
Esempio n. 5
0
def dump_clipped_3d_cuboids_to_images(
    log_ids: Sequence[str],
    max_num_images_to_render: int,
    data_dir: str,
    experiment_prefix: str,
    motion_compensate: bool = True,
) -> List[str]:
    """
    We bring the 3D points into each camera coordinate system, and do the clipping there in 3D.

    Args:
        log_ids: A list of log IDs
        max_num_images_to_render: maximum numbers of images to render.
        data_dir: path to dataset with the latest data
        experiment_prefix: Output directory
        motion_compensate: Whether to motion compensate when projecting

    Returns:
        saved_img_fpaths
    """
    saved_img_fpaths = []
    dl = SimpleArgoverseTrackingDataLoader(data_dir=data_dir,
                                           labels_dir=data_dir)
    avm = ArgoverseMap()

    for log_id in log_ids:
        save_dir = f"{experiment_prefix}_{log_id}"
        if not Path(save_dir).exists():
            os.makedirs(save_dir)

        city_name = dl.get_city_name(log_id)
        log_calib_data = dl.get_log_calibration_data(log_id)

        flag_done = False
        for cam_idx, camera_name in enumerate(RING_CAMERA_LIST +
                                              STEREO_CAMERA_LIST):
            cam_im_fpaths = dl.get_ordered_log_cam_fpaths(log_id, camera_name)
            for i, im_fpath in enumerate(cam_im_fpaths):
                if i % 50 == 0:
                    logging.info("\tOn file %s of camera %s of %s", i,
                                 camera_name, log_id)

                cam_timestamp = Path(im_fpath).stem.split("_")[-1]
                cam_timestamp = int(cam_timestamp)

                # load PLY file path, e.g. 'PC_315978406032859416.ply'
                ply_fpath = dl.get_closest_lidar_fpath(log_id, cam_timestamp)
                if ply_fpath is None:
                    continue
                lidar_pts = load_ply(ply_fpath)
                save_img_fpath = f"{save_dir}/{camera_name}_{cam_timestamp}.jpg"
                if Path(save_img_fpath).exists():
                    saved_img_fpaths += [save_img_fpath]
                    if max_num_images_to_render != -1 and len(
                            saved_img_fpaths) > max_num_images_to_render:
                        flag_done = True
                        break
                    continue

                city_to_egovehicle_se3 = dl.get_city_to_egovehicle_se3(
                    log_id, cam_timestamp)
                if city_to_egovehicle_se3 is None:
                    continue

                lidar_timestamp = Path(ply_fpath).stem.split("_")[-1]
                lidar_timestamp = int(lidar_timestamp)
                labels = dl.get_labels_at_lidar_timestamp(
                    log_id, lidar_timestamp)
                if labels is None:
                    logging.info("\tLabels missing at t=%s", lidar_timestamp)
                    continue

                # Swap channel order as OpenCV expects it -- BGR not RGB
                # must make a copy to make memory contiguous
                img = imageio.imread(im_fpath)[:, :, ::-1].copy()
                camera_config = get_calibration_config(log_calib_data,
                                                       camera_name)
                planes = generate_frustum_planes(
                    camera_config.intrinsic.copy(), camera_name)
                img = plot_lane_centerlines_in_img(
                    lidar_pts,
                    city_to_egovehicle_se3,
                    img,
                    city_name,
                    avm,
                    camera_config,
                    planes,
                )

                for label_idx, label in enumerate(labels):
                    obj_rec = json_label_dict_to_obj_record(label)
                    if obj_rec.occlusion == 100:
                        continue

                    cuboid_vertices = obj_rec.as_3d_bbox()
                    points_h = point_cloud_to_homogeneous(cuboid_vertices).T
                    if motion_compensate:
                        (
                            uv,
                            uv_cam,
                            valid_pts_bool,
                            K,
                        ) = project_lidar_to_img_motion_compensated(
                            points_h,  # these are recorded at lidar_time
                            copy.deepcopy(log_calib_data),
                            camera_name,
                            cam_timestamp,
                            lidar_timestamp,
                            data_dir,
                            log_id,
                            return_K=True,
                        )
                    else:
                        # project_lidar_to_img
                        (
                            uv,
                            uv_cam,
                            valid_pts_bool,
                            camera_config,
                        ) = project_lidar_to_undistorted_img(
                            points_h, copy.deepcopy(log_calib_data),
                            camera_name)
                    if valid_pts_bool.sum() == 0:
                        continue

                    img = obj_rec.render_clip_frustum_cv2(
                        img,
                        uv_cam.T[:, :3],
                        planes.copy(),
                        copy.deepcopy(camera_config),
                    )

                cv2.imwrite(save_img_fpath, img)
                saved_img_fpaths += [save_img_fpath]
                if max_num_images_to_render != -1 and len(
                        saved_img_fpaths) > max_num_images_to_render:
                    flag_done = True
                    break
            if flag_done:
                break
        category_subdir = "amodal_labels"

        if not Path(f"{experiment_prefix}_{category_subdir}").exists():
            os.makedirs(f"{experiment_prefix}_{category_subdir}")

        for cam_idx, camera_name in enumerate(RING_CAMERA_LIST +
                                              STEREO_CAMERA_LIST):
            # Write the cuboid video -- could also write w/ fps=20,30,40
            if "stereo" in camera_name:
                fps = 5
            else:
                fps = 30
            img_wildcard = f"{save_dir}/{camera_name}_%*.jpg"
            output_fpath = f"{experiment_prefix}_{category_subdir}/{log_id}_{camera_name}_{fps}fps.mp4"
            write_nonsequential_idx_video(img_wildcard, output_fpath, fps)

    return saved_img_fpaths
Esempio n. 6
0
argoverse_loader = ArgoverseTrackingLoader(tracking_dataset_dir)
log_id = argoverse_loader.log_list[log_index]
argoverse_data = argoverse_loader[log_index]
city_name = argoverse_data.city_name

use_existing_files = True
domv = DatasetOnMapVisualizer(dataset_dir,
                              experiment_prefix,
                              use_existing_files=use_existing_files,
                              log_id=argoverse_data.current_log)

# %%
camera = 'ring_front_center'
# camera = 'ring_front_left'
calib = argoverse_data.get_calibration(camera)
planes = generate_frustum_planes(calib.camera_config.intrinsic.copy(), camera)

domv = DatasetOnMapVisualizer(tracking_dataset_dir,
                              experiment_prefix,
                              use_existing_files=True,
                              log_id=argoverse_data.current_log)
# %%


def get_plot(map_range, axis_off=True, for_network=False):

    my_dpi = 96.0  # screen constant, check here https://www.infobyip.com/detectmonitordpi.php
    if for_network:
        fig = plt.figure(figsize=(72 / my_dpi, 72 / my_dpi), dpi=my_dpi)
    else:
        fig = plt.figure(figsize=(496 / my_dpi, 496 / my_dpi), dpi=my_dpi)