def _ensure_calib_is_populated(self) -> None:
        """load up calibration object for all logs

        Returns:
            None
        """
        if self._calib is None:
            self._calib = {}
            for log in self.log_list:
                calib_filename = os.path.join(self.root_dir, log, "vehicle_calibration_info.json")
                self._calib[log] = load_calib(calib_filename)
Exemple #2
0
total_number = total_number * 7

bar = progressbar.ProgressBar(maxval=total_number, \
    widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])

print('Total number of files: {}. Translation starts...'.format(total_number))
print('Progress:')
bar.start()

i = 0

for log_id in argoverse_loader.log_list:
    argoverse_data = argoverse_loader.get(log_id)
    for cam in cams:
        # Recreate the calibration file content
        calibration_data = calibration.load_calib(
            data_dir + log_id + '/vehicle_calibration_info.json')[cam]
        L3 = 'P2: '
        for j in calibration_data.K.reshape(1, 12)[0]:
            L3 = L3 + str(j) + ' '
        L3 = L3[:-1]

        L6 = 'Tr_velo_to_cam: '
        for k in calibration_data.extrinsic.reshape(1, 16)[0][0:12]:
            L6 = L6 + str(k) + ' '
        L6 = L6[:-1]

        L1 = 'P0: 0 0 0 0 0 0 0 0 0 0 0 0'
        L2 = 'P1: 0 0 0 0 0 0 0 0 0 0 0 0'
        L4 = 'P3: 0 0 0 0 0 0 0 0 0 0 0 0'
        L5 = 'R0_rect: 1 0 0 0 1 0 0 0 1'
        L7 = 'Tr_imu_to_velo: 0 0 0 0 0 0 0 0 0 0 0 0'
    from argoverse.utils.frustum_clipping import generate_frustum_planes
    from argoverse.utils.plane_visualization_utils import (
        get_perpendicular,
        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:
    """"""
Exemple #4
0
	dataset_name = 'argoverse'

	ts1 = 315975640448534784 # nano-second timestamp
	ts2 = 315975643412234000

	img1_fpath = f'{img_dir}/ring_front_center_{ts1}.jpg'
	img2_fpath = f'{img_dir}/ring_front_center_{ts2}.jpg'

	img1 = imageio.imread(img1_fpath).astype(np.float32) / 255
	img2 = imageio.imread(img2_fpath).astype(np.float32) / 255
	# plt.imshow(img)
	# plt.show()

	if dataset_name == 'argoverse':
		calib_fpath = '/Users/johnlambert/Downloads/visual-odometry-tutorial/train1/273c1883-673a-36bf-b124-88311b1a80be/vehicle_calibration_info.json'
		calib_dict = load_calib(calib_fpath)
		K = calib_dict['ring_front_center'].K[:3,:3]

		# get the ground truth pose
		# timestamps
		# ts1 = Path(img1_fpath).stem.split('_')[-1]
		# ts2 = Path(img2_fpath).stem.split('_')[-1]


	#plot_argoverse_trajectory(ts1, ts2, dataset_dir, log_id)
	#plot_argoverse_epilines_from_ground_truth_poses(ts1, ts2, img1, img2, K)
	#plot_argoverse_epilines_from_annotated_correspondences(img1, img2, K, False)
	plot_argoverse_epilines_from_annotated_correspondences(img1, img2, K, True)

	# plot_backyard_epilines()
Exemple #5
0
def process_a_split(data_dir,
                    target_data_dir,
                    split_file_path,
                    bev_bnds,
                    bev_meter_per_pixel,
                    bev_wanted_classes,
                    offset=0):
    """
    Args:
        data_dir: directory that contains data corresponding to A SPECIFIC
            SPLIT (train, validation, test)
        target_data_dir: the dir to write to. Contains data corresponding to
            A SPECIFIC SPLIT in KITTI (training, testing)
        split_file_path: location to write all the sample_idx of a split
        bev_bnds: [4] containing [x_min, x_max, y_min, y_max] in meter for the bev
        bev_meter_per_pixel: number of meters in a pixel in bev, most often fractional
        bev_wanted_classes: [VEHICLE, BICYCLIST, PEDESTRIAN, ...] the classes to be
            for bev
        offset: first sample_idx to start counting from, needed to differentiate
            training and validation sample_idx because in KITTI they are under
            the same dir
    """
    print("Processing", data_dir)

    target_velodyne_dir = os.path.join(target_data_dir, 'velodyne')
    target_velodyne_reduced_dir = os.path.join(target_data_dir,
                                               'velodyne_reduced')
    target_calib_dir = os.path.join(target_data_dir, 'calib')
    target_image_2_dir = os.path.join(target_data_dir, 'image_2')
    if 'test' not in split_file_path:
        target_label_2_dir = os.path.join(target_data_dir, 'label_2')

    os.makedirs(target_velodyne_dir, exist_ok=True)
    os.makedirs(target_velodyne_reduced_dir, exist_ok=True)
    os.makedirs(target_calib_dir, exist_ok=True)
    os.makedirs(target_image_2_dir, exist_ok=True)
    if 'test' not in split_file_path:
        os.makedirs(target_label_2_dir, exist_ok=True)

    ############################## for saving BEV segmentation masks paths
    target_bev_drivable_dir = os.path.join(target_data_dir, 'bev_DRIVABLE')
    os.makedirs(target_bev_drivable_dir, exist_ok=True)

    target_bev_fov_dir = os.path.join(target_data_dir, 'bev_FOV')
    os.makedirs(target_bev_fov_dir, exist_ok=True)

    target_bev_cls_dirs = []
    for wanted_cls in bev_wanted_classes:
        target_bev_cls_dir = os.path.join(target_data_dir,
                                          'bev_{}'.format(wanted_cls))
        os.makedirs(target_bev_cls_dir, exist_ok=True)
        target_bev_cls_dirs.append(target_bev_cls_dir)
    ############################## end for saving BEV segmentation masks paths

    # Check the number of logs, defined as one continuous trajectory
    argoverse_loader = ArgoverseTrackingLoader(data_dir)
    print('Total number of logs:', len(argoverse_loader))
    argoverse_loader.print_all()
    print('\n')

    cams = [
        'ring_front_center', 'ring_front_left', 'ring_front_right',
        'ring_rear_left', 'ring_rear_right', 'ring_side_left',
        'ring_side_right'
    ]

    # count total number of files
    total_number = 0
    for q in argoverse_loader.log_list:
        log_lidar_path = os.path.join(data_dir, q, 'lidar')
        path, dirs, files = next(os.walk(log_lidar_path))
        total_number = total_number + len(files)

    total_number = total_number * len(cams)

    print('Now write sample indices to split file.')
    write_split_file(split_file_path, offset, total_number)

    bar = progressbar.ProgressBar(maxval=total_number, \
                                  widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])

    print('Total number of files: {}. Translation starts...'.format(
        total_number))
    print('Progress:')
    bar.start()

    i = 0
    kitti_to_argo_mapping = {}
    for log_id in sorted(argoverse_loader.log_list):
        argoverse_data = argoverse_loader.get(log_id)
        from argoverse.map_representation.map_api import ArgoverseMap
        argoverse_map = ArgoverseMap()
        for cam in cams:

            ############################## Calibration for this whole log ##############################
            log_calib_path = os.path.join(data_dir, log_id,
                                          'vehicle_calibration_info.json')
            calibration_data = calibration.load_calib(log_calib_path)[cam]
            calib_file_content = construct_calib_str(calibration_data,
                                                     pts_in_cam_ego_coord=True)

            log_lidar_dir = os.path.join(data_dir, log_id, 'lidar')

            # Loop through the each lidar frame (10Hz) to rename, copy, and adapt
            # all images, lidars, calibration files, and label files.
            for frame_idx, timestamp in enumerate(
                    sorted(argoverse_data.lidar_timestamp_list)):

                idx = str(i + offset).zfill(9)

                # recording the mapping from kitti to argo
                # (log index, the lidar frame index) uniquely identify a sample
                kitti_to_argo_mapping[idx] = (log_id, frame_idx)

                i += 1
                if i < total_number:
                    bar.update(i + 1)

                ############################## Lidar ##############################

                # Save lidar file into .bin format under the new directory
                lidar_file_path = os.path.join(
                    log_lidar_dir, 'PC_{}.ply'.format(str(timestamp)))
                target_lidar_file_path = os.path.join(target_velodyne_dir,
                                                      idx + '.bin')

                lidar_data = load_ply(lidar_file_path)

                # run this block of code only if we are using the cam coord instead of the ego coord
                if True:
                    in_cam_coord = calibration_data.project_ego_to_cam(
                        lidar_data)
                    in_cam_coord = in_cam_coord[:, [2, 0,
                                                    1]]  # tranpose the xyz
                    in_cam_coord[:, [1, 2]] *= -1  # flip 2 of the axes
                    lidar_data = in_cam_coord

                lidar_data_augmented = np.concatenate(
                    (lidar_data, np.zeros([lidar_data.shape[0], 1])), axis=1)
                lidar_data_augmented = lidar_data_augmented.astype('float32')
                lidar_data_augmented.tofile(target_lidar_file_path)

                ############################## Image ##############################

                # Save the image file into .png format under the new directory
                cam_file_path = argoverse_data.image_list_sync[cam][frame_idx]
                target_cam_file_path = os.path.join(target_image_2_dir,
                                                    idx + '.png')
                copyfile(cam_file_path, target_cam_file_path)

                target_calib_file_path = os.path.join(target_calib_dir,
                                                      idx + '.txt')
                file = open(target_calib_file_path, 'w+')
                file.write(calib_file_content)
                file.close()

                ############################## BEV binary masks ##############################
                bev_drivable_save_path = os.path.join(target_bev_drivable_dir,
                                                      idx + '.png')
                bev_wanted_save_paths = [
                    os.path.join(cls_dir, idx + '.png')
                    for cls_dir in target_bev_cls_dirs
                ]
                bev_fov_save_path = os.path.join(target_bev_fov_dir,
                                                 idx + '.png')

                get_bev(argoverse_data,
                        argoverse_map,
                        log_id,
                        frame_idx,
                        bev_bnds,
                        bev_meter_per_pixel,
                        bev_drivable_save_path,
                        bev_wanted_classes,
                        bev_wanted_save_paths,
                        bev_fov_save_path,
                        visualize=False,
                        camera_calib=calibration_data)

                ############################## Labels ##############################

                if 'test' in split_file_path:
                    continue
                label_object_list = argoverse_data.get_label_object(frame_idx)
                target_label_2_file_path = os.path.join(
                    target_label_2_dir, idx + '.txt')
                file = open(target_label_2_file_path, 'w+')

                # DontCare objects must appear at the end as per KITTI label files
                object_lines = []
                dontcare_lines = []

                for detected_object in label_object_list:
                    classes = detected_object.label_class
                    classes = OBJ_CLASS_MAPPING_DICT[
                        classes]  # map class type from artoverse to KITTI
                    occulusion = round(detected_object.occlusion / 25)
                    height = detected_object.height
                    length = detected_object.length
                    width = detected_object.width
                    truncated = 0

                    center = detected_object.translation  # in ego frame

                    corners_ego_frame = detected_object.as_3d_bbox(
                    )  # all eight points in ego frame
                    corners_cam_frame = calibration_data.project_ego_to_cam(
                        corners_ego_frame
                    )  # all eight points in the camera frame
                    image_corners = calibration_data.project_ego_to_image(
                        corners_ego_frame)
                    image_bbox = [
                        min(image_corners[:, 0]),
                        min(image_corners[:, 1]),
                        max(image_corners[:, 0]),
                        max(image_corners[:, 1])
                    ]
                    # the four coordinates we need for KITTI
                    image_bbox = [round(x) for x in image_bbox]

                    center_cam_frame = calibration_data.project_ego_to_cam(
                        np.array([center]))

                    # if 0 < center_cam_frame[0][2] < max_d and 0 < image_bbox[0] < 1920 and 0 < image_bbox[1] < 1200 and 0 < \
                    #     image_bbox[2] < 1920 and 0 < image_bbox[3] < 1200:
                    if True:
                        # the center coordinates in cam frame we need for KITTI

                        # for the orientation, we choose point 1 and point 5 for application
                        p1 = corners_cam_frame[1]
                        p5 = corners_cam_frame[5]
                        # dz = p1[2] - p5[2]
                        # dx = p1[0] - p5[0]
                        # angle = math.atan2(dz, dx)

                        angle_vec = p1 - p5
                        # norm vec along the x axis, points to the right in KITTI cam rect coordinate
                        origin_vec = np.array([1, 0, 0])
                        import vg
                        angle = vg.signed_angle(origin_vec,
                                                angle_vec,
                                                look=vg.basis.y,
                                                units='rad')

                        # the orientation angle of the car
                        beta = math.atan2(center_cam_frame[0][2],
                                          center_cam_frame[0][0])
                        alpha = angle + beta - math.pi / 2
                        line = classes + ' {} {} {} {} {} {} {} {} {} {} {} {} {} {} \n'.format(
                            round(truncated, 2), occulusion, round(alpha, 2),
                            round(image_bbox[0], 2), round(image_bbox[1], 2),
                            round(image_bbox[2], 2), round(image_bbox[3], 2),
                            round(height, 2), round(width, 2), round(
                                length, 2), round(center_cam_frame[0][0], 2),
                            round(center_cam_frame[0][1], 2) + height / 2,
                            round(center_cam_frame[0][2], 2), round(angle, 2))

                        # separate the object lines so we can move all the dontcare lines at the end
                        if classes == DONT_CARE:
                            dontcare_lines.append(line)
                        else:
                            object_lines.append(line)

                for line in object_lines:
                    file.write(line)
                for line in dontcare_lines:
                    file.write(line)
                file.close()

    # write kitti_to_argo_mapping to a file
    split_dir = os.path.dirname(split_file_path)
    split_name = os.path.basename(split_file_path)
    split_name = os.path.splitext(split_name)[0]
    prefix = 'kitti_to_argo_mapping'
    kitti_to_argo_mapping_path = os.path.join(
        split_dir, "{}_{}.json".format(prefix, split_name))
    file_handle = open(kitti_to_argo_mapping_path, 'w')
    json.dump(kitti_to_argo_mapping, file_handle)
    file_handle.close()

    bar.finish()
    print('Translation finished, processed {} files'.format(i))