Exemplo n.º 1
0
assert (len(left_gray) == len(right_gray))

pose = viso2.Matrix_eye(4)
for i in range(N):
    # load the images
    left_img = imread(str(left_gray[i]))
    print(type(left_img), left_img.shape, '++++++')
    right_img = imread(str(right_gray[i]))
    assert (len(left_img.shape) == 2)  # should be grayscale

    print("Processing: Frame:", i)

    # compute visual odometry
    if viso.process_frame(left_img, right_img):
        motion = viso.getMotion()
        est_motion = viso2.Matrix_inv(motion)
        pose = pose * est_motion

        num_matches = viso.getNumberOfMatches()
        num_inliers = viso.getNumberOfInliers()
        print('Matches:', num_matches, "Inliers:",
              100 * num_inliers / num_matches, '%, Current pose:')
        print(pose)

        matches = viso.getMatches()
        assert (matches.size() == num_matches)
        recon.update(matches, motion, 0)
    else:
        print('.... failed!')

points = recon.getPoints()
Exemplo n.º 2
0
def runSFM(dataset_path, feature_dir):
    if_vis = True  # set to True to do the visualization per frame; the images will be saved at '.vis/'. Turn off if you just want the camera poses and errors
    if_on_screen = False  # if True the visualization per frame is going to be displayed realtime on screen; if False there will be no display, but in both options the images will be saved

    # parameter settings (for an example, please download
    img_dir = os.path.join(dataset_path, 'sequences/00/image_0')
    gt_dir = os.path.join(dataset_path, 'poses/00.txt')
    calibFile = os.path.join(dataset_path, 'sequences/00/calib.txt')
    border = 50
    gap = 15
    suffix = 'feature'

    # Load the camera calibration information
    with open(calibFile) as fid:
        calibLines = fid.readlines()
        calibLines = [calibLine.strip() for calibLine in calibLines]

    calibInfo = [float(calibStr) for calibStr in calibLines[0].split(' ')[1:]]
    # param = {'f': calibInfo[0], 'cu': calibInfo[2], 'cv': calibInfo[6]}

    # Load the ground-truth depth and rotation
    with open(gt_dir) as fid:
        gtTr = [[float(TrStr) for TrStr in line.strip().split(' ')]
                for line in fid.readlines()]
    gtTr = np.asarray(gtTr).reshape(-1, 3, 4)

    first_frame = 0
    last_frame = 300

    # init visual odometry
    params = viso2.Mono_parameters()
    params.calib.f = calibInfo[0]
    params.calib.cu = calibInfo[2]
    params.calib.cv = calibInfo[6]
    params.height = 1.6
    params.pitch = -0.08

    first_frame = 0
    last_frame = 300

    # init transformation matrix array
    Tr_total = []
    Tr_total_np = []
    Tr_total.append(viso2.Matrix_eye(4))
    Tr_total_np.append(np.eye(4))

    # init viso module
    visoMono = viso2.VisualOdometryMono(params)

    if if_vis:
        save_path = 'vis_preFeature'
        os.makedirs(save_path, exist_ok=True)

        # create figure
        fig = plt.figure(figsize=(10, 15))
        ax1 = plt.subplot(211)
        ax1.axis('off')
        ax2 = plt.subplot(212)
        ax2.set_xticks(np.arange(-100, 100, step=10))
        ax2.set_yticks(np.arange(-500, 500, step=10))
        ax2.axis('equal')
        ax2.grid()
        if if_on_screen:
            plt.ion()
            plt.show()
        else:
            plt.ioff()

    # for all frames do
    if_replace = False
    errorTransSum = 0
    errorRotSum = 0
    errorRot_list = []
    errorTrans_list = []

    for frame in range(first_frame, last_frame):
        # 1-based index
        k = frame - first_frame + 1

        # read current images
        I = imread(os.path.join(img_dir, '%06d.png' % frame))
        feature = np.load(
            osp.join(feature_dir, '%06d_%s.npy' % (frame, suffix)))
        feature = np.ascontiguousarray(feature)

        assert (len(I.shape) == 2)  # should be grayscale
        feature = feature.astype(np.float32)

        # compute egomotion
        process_result = visoMono.process_frame_preFeat(I, feature, if_replace)

        Tr = visoMono.getMotion()
        matrixer = viso2.Matrix(Tr)
        Tr_np = np.zeros((4, 4))
        Tr.toNumpy(Tr_np)  # so awkward...

        # accumulate egomotion, starting with second frame
        if k > 1:
            if process_result is False:
                if_replace = True
                Tr_total.append(Tr_total[-1])
                Tr_total_np.append(Tr_total_np[-1])
            else:
                if_replace = False
                Tr_total.append(Tr_total[-1] * viso2.Matrix_inv(Tr))
                Tr_total_np.append(
                    Tr_total_np[-1]
                    @ np.linalg.inv(Tr_np))  # should be the same
                print(Tr_total_np[-1])

        # output statistics
        num_matches = visoMono.getNumberOfMatches()
        num_inliers = visoMono.getNumberOfInliers()
        matches = visoMono.getMatches()
        matches_np = np.empty([4, matches.size()])

        for i, m in enumerate(matches):
            matches_np[:, i] = (m.u1p, m.v1p, m.u1c, m.v1c)

        if if_vis:
            # update image
            ax1.clear()
            ax1.imshow(I, cmap='gray', vmin=0, vmax=255)
            if num_matches != 0:
                for n in range(num_matches):
                    ax1.plot([matches_np[0, n], matches_np[2, n]],
                             [matches_np[1, n], matches_np[3, n]])
            ax1.set_title('Frame %d' % frame)

            # update trajectory
            if k > 1:
                ax2.plot([Tr_total_np[k-2][0, 3], Tr_total_np[k-1][0, 3]], \
                    [Tr_total_np[k-2][2, 3], Tr_total_np[k-1][2, 3]], 'b.-', linewidth=1)
                ax2.plot([gtTr[k-2][0, 3], gtTr[k-1][0, 3]], \
                    [gtTr[k-2][2, 3], gtTr[k-1][2, 3]], 'r.-', linewidth=1)
            ax2.set_title(
                'Blue: estimated trajectory; Red: ground truth trejectory')

            plt.draw()

        # Compute rotation
        Rpred_p = Tr_total_np[k - 2][0:3, 0:3]
        Rpred_c = Tr_total_np[k - 1][0:3, 0:3]
        Rpred = Rpred_c.transpose() @ Rpred_p
        Rgt_p = np.squeeze(gtTr[k - 2, 0:3, 0:3])
        Rgt_c = np.squeeze(gtTr[k - 1, 0:3, 0:3])
        Rgt = Rgt_c.transpose() @ Rgt_p
        # Compute translation
        Tpred_p = Tr_total_np[k - 2][0:3, 3:4]
        Tpred_c = Tr_total_np[k - 1][0:3, 3:4]
        Tpred = Tpred_c - Tpred_p
        Tgt_p = gtTr[k - 2, 0:3, 3:4]
        Tgt_c = gtTr[k - 1, 0:3, 3:4]
        Tgt = Tgt_c - Tgt_p
        # Compute errors
        errorRot, errorTrans = errorMetric(Rpred, Rgt, Tpred, Tgt)
        errorRotSum = errorRotSum + errorRot
        errorTransSum = errorTransSum + errorTrans
        # errorRot_list.append(errorRot)
        # errorTrans_list.append(errorTrans)
        print('Mean Error Rotation: %.5f' % (errorRotSum / (k - 1)))
        print('Mean Error Translation: %.5f' % (errorTransSum / (k - 1)))

        print('== [Result] Frame: %d, Matches %d, Inliers: %.2f' %
              (frame, num_matches, 100 * num_inliers / (num_matches + 1e-8)))

        if if_vis:
            # input('Paused; Press Enter to continue') # Option 1: Manually pause and resume
            if if_on_screen:
                plt.pause(
                    0.1
                )  # Or Option 2: enable to this to auto pause for a while after daring to enable animation in case of a delay in drawing
            vis_path = os.path.join(save_path, 'frame%03d.jpg' % frame)
            fig.savefig(vis_path)
            print('Saved at %s' % vis_path)

            if frame % 50 == 0 or frame == last_frame - 1:
                plt.figure(figsize=(10, 15))
                plt.imshow(plt.imread(vis_path))
                plt.axis('off')
                plt.show()