Esempio n. 1
0
def track_camera(corner_storage: CornerStorage,
                 intrinsic_mat: np.ndarray,
                 triangulation_parameters: TriangulationParameters,
                 known_view_1: Tuple[int, Pose],
                 known_view_2: Tuple[int, Pose]) \
        -> Tuple[np.ndarray, PointCloudBuilder]:
    track = [None for _ in range(len(corner_storage))]
    points = [None for _ in range(corner_storage.max_corner_id() + 1)]

    init_from_known_views(known_view_1, known_view_2, track, points,
                          corner_storage, intrinsic_mat,
                          triangulation_parameters)

    has_new_track = True
    while has_new_track:
        has_new_track = False
        for i in range(len(track)):
            if track[i] is None:
                is_successful = track_frame(i, track, points, corner_storage,
                                            intrinsic_mat,
                                            triangulation_parameters)
                if is_successful:
                    has_new_track = True

    for i in range(1, len(track)):
        if track[i] is None:
            track[i] = track[i - 1]
    view_mats = np.array(track)

    point_cloud_builder = PointCloudBuilder(
        ids=np.array([i for i in range(len(points)) if points[i] is not None]),
        points=np.array(
            [points[i] for i in range(len(points)) if points[i] is not None]))
    return view_mats, point_cloud_builder
Esempio n. 2
0
def track_and_calc_colors(camera_parameters: CameraParameters,
                          corner_storage: CornerStorage,
                          frame_sequence_path: str,
                          known_view_1: Optional[Tuple[int, Pose]] = None,
                          known_view_2: Optional[Tuple[int, Pose]] = None) \
        -> Tuple[List[Pose], PointCloud]:
    rgb_sequence = frameseq.read_rgb_f32(frame_sequence_path)
    intrinsic_mat = to_opencv_camera_mat3x3(camera_parameters,
                                            rgb_sequence[0].shape[0])

    known_view_1 = None
    known_view_2 = None

    if known_view_1 is None or known_view_2 is None:
        track = [None] * len(corner_storage)
        i, j = initialize(corner_storage, track, intrinsic_mat)
        poses = add_points(corner_storage, track, intrinsic_mat,
                           [None] * (corner_storage.max_corner_id() + 1), i, j)
    else:
        track = init_track_with_known_views(corner_storage, known_view_1,
                                            known_view_2)

        poses = add_points(corner_storage, track, intrinsic_mat,
                           [None] * (corner_storage.max_corner_id() + 1),
                           known_view_1[0], known_view_2[0])

    track, poses = track_(len(corner_storage), track, poses, intrinsic_mat,
                          corner_storage)
    point_cloud_builder = PointCloudBuilder(
        ids=np.array([i for i, point in enumerate(poses)
                      if point is not None]),
        points=np.array([point for point in poses if point is not None]))

    view_mats = np.array(track)

    calc_point_cloud_colors(point_cloud_builder, rgb_sequence, view_mats,
                            intrinsic_mat, corner_storage, 5.0)
    point_cloud = point_cloud_builder.build_point_cloud()
    poses = list(map(view_mat3x4_to_pose, view_mats))
    return poses, point_cloud
Esempio n. 3
0
def calc_point_cloud_colors(pc_builder: PointCloudBuilder,
                            rgb_sequence: pims.FramesSequence,
                            view_mats: List[np.ndarray],
                            intrinsic_mat: np.ndarray,
                            corner_storage: CornerStorage,
                            max_reproj_error: float) -> None:
    # pylint:disable=too-many-arguments
    # pylint:disable=too-many-locals

    point_cloud_points = np.zeros((corner_storage.max_corner_id() + 1, 3))
    point_cloud_points[pc_builder.ids.flatten()] = pc_builder.points

    color_sums = np.zeros_like(point_cloud_points)
    color_counts = np.zeros_like(color_sums)

    with click.progressbar(zip(rgb_sequence, view_mats, corner_storage),
                           label='Calculating colors',
                           length=len(view_mats)) as progress_bar:
        for image, view, corners in progress_bar:
            try:
                proj_mat = intrinsic_mat @ view
            except Exception as e:
                print(intrinsic_mat)
                print(view)
                raise e
            points3d = point_cloud_points[corners.ids.flatten()]
            with np.errstate(invalid='ignore'):
                errors = compute_reprojection_errors(points3d, corners.points,
                                                     proj_mat)
                errors = np.nan_to_num(errors)

            consistency_mask = (
                (errors <= max_reproj_error) & (corners.points[:, 0] >= 0) &
                (corners.points[:, 1] >= 0) &
                (corners.points[:, 0] < image.shape[1] - 0.5) &
                (corners.points[:, 1] < image.shape[0] - 0.5)).flatten()
            ids_to_process = corners.ids[consistency_mask].flatten()
            corner_points = np.round(corners.points[consistency_mask]).astype(
                np.int32)

            rows = corner_points[:, 1].flatten()
            cols = corner_points[:, 0].flatten()
            color_sums[ids_to_process] += image[rows, cols]
            color_counts[ids_to_process] += 1

    nonzero_mask = (color_counts[:, 0] != 0).flatten()
    color_sums[nonzero_mask] /= color_counts[nonzero_mask]
    colors = color_sums[pc_builder.ids.flatten()]

    pc_builder.set_colors(colors)
    def __init__(self, corner_storage: CornerStorage,
                 intrinsic_mat: np.ndarray,
                 parameters: TriangulationParameters):
        self._corner_storage = corner_storage
        self._intrinsic_mat = intrinsic_mat
        self._triangulation_parameters = parameters

        self._n_frames = len(corner_storage)
        self._track = [None] * self._n_frames
        self._point_positions = [None] * (corner_storage.max_corner_id() + 1)

        frame_ind1, frame_ind2 = self._initialization()
        # print(frame_ind1, frame_ind2)
        # print(self._n_frames)
        self._add_cloud_points(frame_ind1, frame_ind2)
        self._tracking()
Esempio n. 5
0
def track_and_calc_colors(camera_parameters: CameraParameters,
                          corner_storage: CornerStorage,
                          frame_sequence_path: str,
                          known_view_1: Optional[Tuple[int, Pose]] = None,
                          known_view_2: Optional[Tuple[int, Pose]] = None) \
        -> Tuple[List[Pose], PointCloud]:
    if known_view_1 is None or known_view_2 is None:
        raise NotImplementedError()

    rgb_sequence = frameseq.read_rgb_f32(frame_sequence_path)
    intrinsic_mat = to_opencv_camera_mat3x3(camera_parameters,
                                            rgb_sequence[0].shape[0])

    view_mats = np.zeros((len(corner_storage), 3, 4), dtype=np.float64)
    processed_frames = np.zeros(len(corner_storage), dtype=np.bool)
    points3d = np.zeros((corner_storage.max_corner_id() + 1, 3),
                        dtype=np.float64)
    added_points = np.zeros(corner_storage.max_corner_id() + 1, dtype=np.bool)

    print('Trying to extract 3d points from known frames...')

    view_mats[known_view_1[0]] = pose_to_view_mat3x4(known_view_1[1])
    view_mats[known_view_2[0]] = pose_to_view_mat3x4(known_view_2[1])
    processed_frames[known_view_1[0]] = processed_frames[
        known_view_2[0]] = True
    extracted_points = extract_points(corner_storage[known_view_1[0]],
                                      corner_storage[known_view_2[0]],
                                      view_mats[known_view_1[0]],
                                      view_mats[known_view_2[0]],
                                      intrinsic_mat)
    if not extracted_points:
        print(
            'Extracting 3d points from known frames failed: '
            'either there are no common points, or triangulation angle between frames is too small.\n'
            'Try to choose another initial frames.',
            file=sys.stderr)
        exit(0)
    print('Succeeded! Trying to build point cloud...')

    added_points[extracted_points[0]] = True
    points3d[extracted_points[0]] = extracted_points[1]

    was_updated = True
    while was_updated:
        was_updated = False
        unprocessed_frames = np.arange(len(corner_storage),
                                       dtype=np.int32)[~processed_frames]
        for frame in unprocessed_frames:
            points3d_ids = np.arange(corner_storage.max_corner_id() + 1,
                                     dtype=np.int32)[added_points]
            common, (indices1, indices2) = snp.intersect(
                points3d_ids,
                corner_storage[frame].ids.flatten(),
                indices=True)
            if len(common) <= 5:
                continue

            try:
                print(f'Processing frame {frame}: ', end='')
                retval, rvec, tvec, inliers = cv2.solvePnPRansac(
                    objectPoints=points3d[common],
                    imagePoints=corner_storage[frame].points[indices2],
                    cameraMatrix=intrinsic_mat,
                    distCoeffs=None)
            except:
                retval = False

            if not retval:
                print(f'failed to solve PnP RANSAC, trying another frame')
                continue

            print(f'succeeded, found {len(inliers)} inliers')
            was_updated = True
            view_mats[frame] = rodrigues_and_translation_to_view_mat3x4(
                rvec, tvec)
            for processed_frame in np.arange(len(corner_storage),
                                             dtype=np.int32)[processed_frames]:
                extracted_points = extract_points(
                    corner_storage[frame], corner_storage[processed_frame],
                    view_mats[frame], view_mats[processed_frame],
                    intrinsic_mat, points3d_ids)

                if extracted_points:
                    added_points[extracted_points[0]] = True
                    points3d[extracted_points[0]] = extracted_points[1]
            processed_frames[frame] = True
            print(f'Current point cloud contains {sum(added_points)} points')

    for _ in range(2):
        for i in range(1, len(corner_storage)):
            if not processed_frames[i]:
                processed_frames[i] = True
                view_mats[i] = view_mats[i - 1]
        processed_frames = processed_frames[::-1]
        view_mats = view_mats[::-1]

    print(
        f'Finished building point cloud, now it contains {sum(added_points)} points'
    )

    point_cloud_builder = PointCloudBuilder(ids=np.arange(
        corner_storage.max_corner_id() + 1, dtype=np.int32)[added_points],
                                            points=points3d[added_points])

    calc_point_cloud_colors(point_cloud_builder, rgb_sequence, view_mats,
                            intrinsic_mat, corner_storage, 5.0)
    point_cloud = point_cloud_builder.build_point_cloud()
    poses = list(map(view_mat3x4_to_pose, view_mats))
    return poses, point_cloud
Esempio n. 6
0
def track_and_calc_colors(
    camera_parameters: CameraParameters,
    corner_storage: CornerStorage,
    frame_sequence_path: str,
    known_view_1: Optional[Tuple[int, Pose]] = None,
    known_view_2: Optional[Tuple[int, Pose]] = None
) -> Tuple[List[Pose], PointCloud]:
    rgb_sequence = frameseq.read_rgb_f32(frame_sequence_path)
    intrinsic_mat = to_opencv_camera_mat3x3(camera_parameters,
                                            rgb_sequence[0].shape[0])
    if known_view_1 is None or known_view_2 is None:
        known_view_1, known_view_2 = initial_camera_views(
            corner_storage, intrinsic_mat)
    print(known_view_1[1])
    print(known_view_2[1])

    print(known_view_1[0], known_view_2[0])

    print(intrinsic_mat)

    points_3d, points_ids = calc_starting_points(intrinsic_mat, corner_storage,
                                                 known_view_1, known_view_2)

    #initial_points_3d, initial_points_ids = points_3d.copy(), points_ids.copy()

    n_points = corner_storage.max_corner_id() + 1
    res_points_3d = np.full((n_points, 3), None)
    #res_points_3d[points_ids] = points_3d

    view_mats = [np.full((3, 4), None) for _ in range(len(corner_storage))]
    view_mats[known_view_1[0]], view_mats[
        known_view_2[0]] = pose_to_view_mat3x4(
            known_view_1[1]), pose_to_view_mat3x4(known_view_2[1])

    print(f'len(corner_storage):{len(corner_storage)}')

    id1 = known_view_1[0]
    for n_frame, corners in enumerate(corner_storage[id1 + 1:], id1 + 1):
        common_obj, common_img, common_ids = get_common_points(
            corners, points_ids, points_3d)

        mat, points_3d, points_ids, reprojection_error = build_view_mat(
            common_obj, common_img, common_ids, intrinsic_mat)
        points_ids = np.array(points_ids)
        view_mats[n_frame] = mat

        is_null = np.array([(x[0] is None) for x in res_points_3d[points_ids]])
        #res_points_3d[points_ids[is_null]] = points_3d[is_null]

        n_inliers = len(points_3d)

        points_3d, points_ids = calc_new_points(n_frame, intrinsic_mat,
                                                corner_storage, view_mats,
                                                points_3d, points_ids)

        print(
            f"Processing frame #{n_frame}. Number of inliers: {n_inliers}. "
            f"Reprojection error: {reprojection_error}. Tracking points: {len(common_img)}"
        )

    for n_frame, corners in list(enumerate(corner_storage))[::-1]:
        common_obj, common_img, common_ids = get_common_points(
            corners, points_ids, points_3d)

        mat, points_3d, points_ids, reprojection_error = build_view_mat(
            common_obj, common_img, common_ids, intrinsic_mat)
        view_mats[n_frame] = mat

        is_null = np.array([(x[0] is None) for x in res_points_3d[points_ids]])
        #res_points_3d[points_ids[is_null]] = points_3d[is_null]

        n_inliers = len(points_3d)

        points_3d, points_ids = calc_new_points(n_frame, intrinsic_mat,
                                                corner_storage, view_mats,
                                                points_3d, points_ids)

        print(
            f"Processing frame #{n_frame}. Number of inliers: {n_inliers}. "
            f"Reprojection error: {reprojection_error}. Tracking points: {len(common_img)}"
        )

    # Approximating

    n_iter = 1
    for iter in range(n_iter):
        for n_frame, corners in enumerate(corner_storage):
            common_obj, common_img, common_ids = get_common_points(
                corners, points_ids, points_3d)

            mat, points_3d, points_ids, reprojection_error = build_view_mat(
                common_obj, common_img, common_ids, intrinsic_mat)

            view_mats[n_frame] = mat
            if iter == n_iter - 1:
                res_points_3d[points_ids] = points_3d

            n_inliers = len(points_3d)

            points_3d, points_ids = calc_new_points(n_frame, intrinsic_mat,
                                                    corner_storage, view_mats,
                                                    points_3d, points_ids)

            print(
                f"Processing frame #{n_frame}. Number of inliers: {n_inliers}. "
                f"Reprojection error: {reprojection_error}. Tracking points: {len(common_img)}"
            )

        for n_frame, corners in list(enumerate(corner_storage))[::-1]:
            common_obj, common_img, common_ids = get_common_points(
                corners, points_ids, points_3d)

            mat, points_3d, points_ids, reprojection_error = build_view_mat(
                common_obj, common_img, common_ids, intrinsic_mat)

            view_mats[n_frame] = mat
            if iter == n_iter - 1:
                res_points_3d[points_ids] = points_3d

            n_inliers = len(points_3d)

            points_3d, points_ids = calc_new_points(n_frame, intrinsic_mat,
                                                    corner_storage, view_mats,
                                                    points_3d, points_ids)

            print(
                f"Processing frame #{n_frame}. Number of inliers: {n_inliers}. "
                f"Reprojection error: {reprojection_error}. Tracking points: {len(common_img)}"
            )

    res_points_ids = np.array(
        [i for i, x in enumerate(res_points_3d) if x[0] is not None])
    res_points_3d = np.array(res_points_3d[res_points_ids], dtype=float)

    point_cloud_builder = PointCloudBuilder(ids=res_points_ids,
                                            points=res_points_3d)

    calc_point_cloud_colors(point_cloud_builder, rgb_sequence, view_mats,
                            intrinsic_mat, corner_storage, 5.0)

    point_cloud = point_cloud_builder.build_point_cloud()
    poses = list(map(view_mat3x4_to_pose, view_mats))
    return poses, point_cloud