Esempio n. 1
0
def add_gaussian_noise(seq, rot_noise_deg=10.0, loc_displace_factor=0.1):
    """
    Add gaussian noise for the pose of keyframes
    :param seq: keyframe sequences, dim: (M, 3, 4), M is the number of keyframes
    :param rot_noise_deg: noise in rotation (unit: deg)
    :param loc_displace_factor: displacement factor in translation, the unit 1 is the avg. baseline among all cameras.
    :return: noise sequences with dim (M, 3, 4), displacement std.
    """
    n_frames = seq.shape[0]

    avg_frame_dist = 0
    R, t = cam_opt.Rt(seq[0])
    pre_frame_center = cam_opt.camera_center_from_Tcw(R, t)
    for frame_idx in range(1, n_frames):
        R, t = cam_opt.Rt(seq[frame_idx])
        frame_center = cam_opt.camera_center_from_Tcw(R, t)
        dist = np.linalg.norm(frame_center - pre_frame_center)
        avg_frame_dist += dist
    avg_frame_dist /= n_frames

    # Set the translation noise
    loc_disp_noise_sigma = loc_displace_factor * avg_frame_dist     # std. for random displacement
    disp_noise = np.random.normal(0, loc_disp_noise_sigma, size=(n_frames, 3))

    # Set the rotation noise
    rot_noise_factor = np.deg2rad(rot_noise_deg)
    rot_noise = np.random.normal(0, rot_noise_factor, size=n_frames)

    new_seq = seq.copy()
    for frame_idx in range(1, n_frames):
        T = seq[frame_idx]
        R, t = cam_opt.Rt(T)

        # Add random noise to translation
        C = cam_opt.camera_center_from_Tcw(R, t)
        rand_C = C + disp_noise[frame_idx]

        # Add random noise to rotation
        temp_T = np.eye(4)
        temp_T[:3, :3] = R
        angle, axis, _ = trans.rotation_from_matrix(temp_T)
        new_angle = angle + rot_noise[frame_idx]
        new_axis = axis + np.random.normal(0, 0.1, size=3)
        new_R = trans.rotation_matrix(new_angle, new_axis)[:3, :3]

        new_t = cam_opt.translation_from_center(new_R, rand_C)
        new_seq[frame_idx][:3, :3] = new_R[:3, :3]
        new_seq[frame_idx][:3, 3] = new_t

    return new_seq, loc_disp_noise_sigma
Esempio n. 2
0
def plot_frames_seq_2d(frames: FrameSeqData,
                       plt_axes=None,
                       color=None,
                       legend=None,
                       point_style='-',
                       index_range=(-1, -1),
                       show_view_direction=False):
    """
    Plot frame sequences in 2D figure
    Note: use plt.show() in the end
    :param frames: frame sequences
    :param plt_axes: matplotlib axis handle
    :param color: color tuple, e.g. (1.0, 1.0, 1.0)
    :param legend: legend name for the curve
    """

    if plt_axes is not None:
        ax = plt_axes
    else:
        plt.figure()
        ax = plt.gca()

    if color is None:
        color = np.random.uniform(0, 1, size=3).tolist()

    n_frames = len(frames)
    first_frame = frames.frames[0]

    avg_frame_dist = 0
    R, t = cam_opt.Rt(first_frame['extrinsic_Tcw'])
    pre_frame_center = cam_opt.camera_center_from_Tcw(R, t)

    for frame_idx in range(1, n_frames):
        R, t = cam_opt.Rt(frames.frames[frame_idx]['extrinsic_Tcw'])
        frame_center = cam_opt.camera_center_from_Tcw(R, t)
        dist = np.linalg.norm(frame_center - pre_frame_center)
        avg_frame_dist += dist
    avg_frame_dist /= n_frames

    start_idx = 0 if index_range[0] == -1 else index_range[0]
    end_idx = n_frames if index_range[1] == -1 else min(
        index_range[1], n_frames)

    frame_centers = []
    view_directions = []
    for frame in frames.frames[start_idx:end_idx]:
        cur_Tcw = frame['extrinsic_Tcw']
        cur_center = cam_opt.camera_center_from_Tcw(cur_Tcw[:3, :3],
                                                    cur_Tcw[:3, 3])
        frame_centers.append(cur_center)

        view_direction = np.dot(R.T, np.asarray([0, 0, 1]))
        view_directions.append((view_direction[0], view_direction[2]))

    view_direct_len = 0.1 * avg_frame_dist
    view_directions = view_direct_len * np.asarray(view_directions,
                                                   dtype=np.float32)
    frame_centers = np.asarray(frame_centers, dtype=np.float32)
    ax.plot(frame_centers[0, 0], frame_centers[0, 2], '*',
            color=color)  # First frame
    ax.plot(frame_centers[:, 0],
            frame_centers[:, 2],
            point_style,
            color=color,
            label=legend)

    if show_view_direction:
        for frame_idx in range(0, len(frame_centers)):
            ax.arrow(frame_centers[frame_idx, 0],
                     frame_centers[frame_idx, 2],
                     view_directions[frame_idx, 0],
                     view_directions[frame_idx, 1],
                     head_width=0.3 * view_direct_len,
                     head_length=0.2 * view_direct_len,
                     fc='k',
                     color=color)

    if legend is not None:
        ax.legend()
    ax.set_aspect('equal', adjustable='box')
Esempio n. 3
0
def plot_array_seq_2d(seq_array,
                      plt_axes=None,
                      color=None,
                      legend=None,
                      point_style='-',
                      index_range=(-1, -1),
                      show_view_direction=False,
                      arrow_color=None):
    """
    Plot frame sequences in 2D figure
    Note: use plt.show() in the end
    :param frames: frame poses with numpy array, dim: (N, 3, 4)
    :param plt_axes: matplotlib axis handle
    :param color: color tuple, e.g. (1.0, 1.0, 1.0)
    :param legend: legend name for the curve
    :param show_view_direction: show view direction in 2d
    """

    if plt_axes is not None:
        ax = plt_axes
    else:
        plt.figure()
        ax = plt.gca()

    if color is None:
        color = np.random.uniform(0, 1, size=3).tolist()

    n_frames = seq_array.shape[0]
    cam_centers = []
    view_directions = []

    avg_frame_dist = 0
    R, t = cam_opt.Rt(seq_array[0])
    pre_frame_center = cam_opt.camera_center_from_Tcw(R, t)
    for frame_idx in range(1, n_frames):
        R, t = cam_opt.Rt(seq_array[frame_idx])
        frame_center = cam_opt.camera_center_from_Tcw(R, t)
        dist = np.linalg.norm(frame_center - pre_frame_center)
        avg_frame_dist += dist
    avg_frame_dist /= n_frames

    start_idx = 0 if index_range[0] == -1 else index_range[0]
    end_idx = n_frames if index_range[1] == -1 else min(
        index_range[1], n_frames)

    for frame_idx in range(start_idx, end_idx):
        Tcw = seq_array[frame_idx]
        R, t = cam_opt.Rt(Tcw)
        C = cam_opt.camera_center_from_Tcw(R, t)
        view_direction = np.dot(R.T, np.asarray([0, 0, 1]))
        view_directions.append((view_direction[0], view_direction[2]))
        cam_centers.append(C)
    cam_centers = np.asarray(cam_centers)
    view_direct_len = 0.1 * avg_frame_dist
    view_directions = view_direct_len * np.asarray(view_directions)

    ax.plot(cam_centers[0, 0], cam_centers[0, 2], '*',
            color=color)  # First frame
    ax.plot(cam_centers[:, 0],
            cam_centers[:, 2],
            point_style,
            color=color,
            label=legend)

    if show_view_direction:
        for frame_idx in range(0, len(cam_centers)):
            ax.arrow(cam_centers[frame_idx, 0],
                     cam_centers[frame_idx, 2],
                     view_directions[frame_idx, 0],
                     view_directions[frame_idx, 1],
                     width=0.01,
                     head_width=0.3 * view_direct_len,
                     head_length=0.2 * view_direct_len,
                     fc='k',
                     color=arrow_color[frame_idx]
                     if arrow_color is not None else color)

    if legend is not None:
        ax.legend()
    ax.set_aspect('equal', adjustable='box')
Esempio n. 4
0
    K = K_from_frame(cur_frame)

    # Read image
    cur_img = cv2.imread(os.path.join(base_dir, cur_name)).astype(
        np.float32) / 255.0
    next_img = cv2.imread(os.path.join(base_dir, next_name)).astype(
        np.float32) / 255.0
    cur_depth = load_depth_from_png(os.path.join(base_dir, cur_depth_name))
    h, w, c = cur_img.shape

    rel_T = cam_opt.relateive_pose(cur_Tcw[:3, :3], cur_Tcw[:3, 3],
                                   next_Tcw[:3, :3], next_Tcw[:3, 3])

    # Translation
    Cb = cam_opt.camera_center_from_Tcw(rel_T[:3, :3], rel_T[:3, 3])
    baseline = np.linalg.norm(Cb)

    # View angle
    q = trans.quaternion_from_matrix(rel_T)
    R = trans.quaternion_matrix(q)
    rel_rad, rel_axis, _ = trans.rotation_from_matrix(R)
    rel_deg = np.rad2deg(rel_rad)

    next2cur, _ = cam_opt.wrapping(cur_img, next_img, cur_depth, K,
                                   rel_T[:3, :3], rel_T[:3, 3])
    show_multiple_img([{
        'img': cur_img,
        'title': 'a'
    }, {
        'img': next2cur,
                                           displacement_dist_std=0.05)
    # print('Displacement:', disp_sigmaq)
    T_noise = torch.from_numpy(T_noise)
    torch.set_default_tensor_type('torch.cuda.FloatTensor')

    fig = plt.figure()
    ax = plt.gca()
    Tcw_n = np.load(os.path.join(in_dir, "Tcw_%05d.npy") % sample_idx)
    T_noise_n = np.load(os.path.join(in_dir, "Tcw_n%05d.npy") % sample_idx)
    T_pred_n = np.load(os.path.join(in_dir, "Tcw_p%05d.npy") % sample_idx)

    # T_noise_n = T_noise.cpu().numpy().reshape(L, 3, 4)
    for f_idx in range(0, L):
        T_item = Tcw_n[f_idx, :, :]
        T_n_item = T_noise_n[f_idx, :, :]
        c1 = cam_opt.camera_center_from_Tcw(T_item[:3, :3], T_item[:3, 3])
        c2 = cam_opt.camera_center_from_Tcw(T_n_item[:3, :3], T_n_item[:3, 3])
        print('Baseline: ', np.linalg.norm(c1 - c2))

    plot_array_seq_2d(Tcw_n,
                      plt_axes=ax,
                      color=(0, 0, 1),
                      show_view_direction=True,
                      legend='GT')
    plot_array_seq_2d(T_noise_n,
                      plt_axes=ax,
                      color=(1, 0, 0),
                      show_view_direction=True,
                      legend='Noise')
    plot_array_seq_2d(T_pred_n,
                      plt_axes=ax,
Esempio n. 6
0
        if n1_name not in bundle_image2idx or n2_name not in bundle_image2idx:
            continue

        if len(match['n1_feat_id']) == 0 or len(match['n2_feat_id']) == 0:
            continue

        assert n1 == pair[1] and n2 == pair[2]

        K1 = bundle_recon_cams[n1].K_matrix()
        K2 = bundle_recon_cams[n2].K_matrix()
        covis = max(int(covis_map[n1, n2]), int(covis_map[n2, n1]))

        n1_Rt = bundle_recon_cams[n1].recon_cam_Es()
        n2_Rt = bundle_recon_cams[n2].recon_cam_Es()

        n1_C = cam_opt.camera_center_from_Tcw(n1_Rt[:3, :3], n1_Rt[:3, 3])
        n2_C = cam_opt.camera_center_from_Tcw(n2_Rt[:3, :3], n2_Rt[:3, 3])

        if n1_Rt[2, 2] == 0 or n2_Rt[2, 2] == 0:
            continue
        rel_Rt_gt = cam_opt.relateive_pose(n1_Rt[:, :3], n1_Rt[:, 3],
                                           n2_Rt[:, :3], n2_Rt[:, 3])
        Rij = rel_Rt_gt[:, :3]
        tij = rel_Rt_gt[:, 3]

        tij = tij / np.sqrt(np.sum(np.square(tij)))

        rel_R = np.matmul(rel_Rt[:3, :3], Rij.T)
        R_err = np.rad2deg(np.arccos((np.trace(rel_R) - 1) / 2))
        t_err = np.rad2deg(rel_t_err(tij, rel_Rt[:3, 3]))
Esempio n. 7
0
def add_drift_noise(seq, rot_noise_deg=10.0, displacement_dist_std=0.1):
    """
    Add gaussian noise for the pose of keyframes, here we update the noise-track with random noise to
    simulate drift error.
    :param seq: keyframe sequences, dim: (M, 3, 4), M is the number of keyframes
    :param rot_noise_deg: noise in rotation (unit: deg)
    :param displacement_dist_std: displacement factor in translation, the unit 1 is the avg. baseline among all cameras.
    :return: noise sequences with dim (M, 3, 4), displacement std.
    """
    n_frames = seq.shape[0]

    avg_frame_dist = 0
    R, t = cam_opt.Rt(seq[0])
    pre_frame_center = cam_opt.camera_center_from_Tcw(R, t)
    for frame_idx in range(1, n_frames):
        R, t = cam_opt.Rt(seq[frame_idx])
        frame_center = cam_opt.camera_center_from_Tcw(R, t)
        dist = np.linalg.norm(frame_center - pre_frame_center)
        pre_frame_center = frame_center
        avg_frame_dist += dist
    avg_frame_dist /= n_frames

    # Set the translation noise
    loc_disp_noise_sigma = displacement_dist_std                    # std. for random displacement
    disp_noise = np.random.normal(0, loc_disp_noise_sigma, size=(n_frames, 3))

    # Set the rotation noise
    rot_noise_factor = np.deg2rad(rot_noise_deg)
    rot_noise = np.random.normal(0, rot_noise_factor, size=n_frames)

    # Add random noise, here we have two track: 'ground-truth-track' and 'noise-track'
    # the 'ground-truth-track' providing ground-truth relative pose, we then add noise
    # onto relative pose, and added to the 'noise-track' in the end.

    new_seq = seq.copy()
    pre_frame = seq[0]                                      # used for ground-truth track
    pre_noise_frame = np.eye(4)                             # noise-track, init the same with first ground-truth pose
    pre_noise_frame[:3, :] = pre_frame

    for frame_idx in range(1, n_frames):
        # Ground-truth-track
        # current frame:
        T = seq[frame_idx]
        R, t = cam_opt.Rt(T)

        # previous frame:
        pre_R, pre_t = cam_opt.Rt(pre_frame)
        pre_T = np.eye(4, dtype=np.float32)
        pre_T[:3, :3] = pre_R
        pre_T[:3, 3] = pre_t

        # inv_T = cam_opt.camera_pose_inv(R, t)
        # r_angle, r_axis, _ = trans.rotation_from_matrix(inv_T)
        # print('Old Rotation:', r_angle)

        # Compute ground-truth relative pose, and add random noise to translation
        rel_T = cam_opt.relateive_pose(pre_R, pre_t, R, t)
        rel_R, rel_t = cam_opt.Rt(rel_T)
        rel_C = cam_opt.camera_center_from_Tcw(rel_R, rel_t)
        rand_C = rel_C + disp_noise[frame_idx]

        # Add random noise to rotation
        temp_T = np.eye(4, dtype=np.float32)
        temp_T[:3, :3] = rel_R
        angle, axis, _ = trans.rotation_from_matrix(temp_T)
        new_angle = rot_noise[frame_idx]
        new_axis = np.random.normal(0, 1.0, size=3)
        noise_R = trans.rotation_matrix(new_angle, new_axis)[:3, :3]

        # print('New', np.rad2deg(new_angle))

        # Build new relative transformation matrix
        new_R = np.dot(noise_R, rel_R)
        new_t = cam_opt.translation_from_center(new_R, rand_C)
        temp_T[:3, :3] = new_R
        temp_T[:3, 3] = new_t

        # Add the noise relative transformation onto noise-track
        new_T = np.dot(temp_T, pre_noise_frame)
        new_seq[frame_idx][:3, :] = new_T[:3, :]

        # Update both ground-truth-track as well as noise-track
        pre_frame = T
        pre_noise_frame = new_T

        # inv_new_T = cam_opt.camera_pose_inv(new_T[:3, :3], new_T[:3, 3])
        # r_angle, r_axis, _ = trans.rotation_from_matrix(inv_new_T)
        # print('New Rotation:', r_angle)

    return new_seq, loc_disp_noise_sigma
Esempio n. 8
0
    # noise_T, rand_std_radius = add_gaussian_noise(seq_T, rot_noise_deg=8.0, loc_displace_factor=0.1)
    noise_T, rand_std_radius = add_drift_noise(seq_T, rot_noise_deg=8.0, displacement_dist_std=0.08)

    # Show 2D Seq
    if show_2d_path:
        import matplotlib.pyplot as plt
        from seq_data.plot_seq_2d import plot_array_seq_2d
        plt.figure()
        ax = plt.gca()
        plot_array_seq_2d(noise_T, plt_axes=ax, show_view_direction=True, legend='noise', color='r')
        plot_array_seq_2d(seq_T, plt_axes=ax, show_view_direction=True, legend='ori', color='b')

        # Plot displacement radius
        for frame_idx in range(1, noise_T.shape[0]):
            T = seq_T[frame_idx]
            C = cam_opt.camera_center_from_Tcw(T[:3, :3], T[:3, 3])
            circle = plt.Circle((C[0], C[2]), 3 * rand_std_radius, color=(1.0, 0.0, 0.0, 0.1))
            ax.add_patch(circle)

        ax.set_aspect('equal', adjustable='box')
        plt.show()
    else:
        from visualizer.visualizer_3d import Visualizer

        # Show 3D case
        vis = Visualizer()

        count = 0
        def keyPressEvent(obj, event):
            global seq_T
            global noise_T
Esempio n. 9
0
def sel_triple_sun3d(base_dir, scene_frames, max_triple_num,
                     num_sample_per_triple, trans_thres, overlap_thres):
    """
    Select triples (anchor, positive, negative) from a sun3d sequence
    :param base_dir: dataset base directory
    :param scene_frames: scene frames to extract triples
    :param max_triple_num: maximum number of triples
    :param num_sample_per_triple: number of positive/negative samples per triple
    :param trans_thres: translation threshold for positive samples, based on the center of different frames
    :param overlap_thres: overlap threshold for positive samples, (low, high)
    :return: [{'anchor': frame_dict, 'positive': FrameSeqData, 'negative': FrameSeqData}, {...}, ...]
    """
    dim = scene_frames.get_frame_dim(scene_frames.frames[0])
    K = scene_frames.get_K_mat(scene_frames.frames[0])
    pre_cache_x2d = cam_opt.x_2d_coords(dim[0], dim[1])

    camera_centers = np.empty((len(scene_frames), 3), dtype=np.float32)
    for i, frame in enumerate(scene_frames.frames):
        Tcw = scene_frames.get_Tcw(frame)
        center = cam_opt.camera_center_from_Tcw(Tcw[:3, :3], Tcw[:3, 3])
        camera_centers[i, :] = center

    kdtree = KDTree(camera_centers)

    triple_list = []
    anchor_idces = np.random.choice(len(scene_frames),
                                    max_triple_num,
                                    replace=False)
    for anchor_idx in anchor_idces:
        anchor_frame = scene_frames.frames[anchor_idx]
        anchor_Tcw = scene_frames.get_Tcw(anchor_frame)
        anchor_depth_path = scene_frames.get_depth_name(anchor_frame)
        anchor_depth = read_sun3d_depth(
            os.path.join(base_dir, anchor_depth_path))
        anchor_depth[anchor_depth < 1e-5] = 1e-5

        potential_pos_idces = kdtree.query_ball_point(
            camera_centers[anchor_idx], trans_thres)
        pos_idces = []
        for potential_pos_idx in potential_pos_idces:
            potential_pos_frame = scene_frames.frames[potential_pos_idx]
            potential_pos_Tcw = scene_frames.get_Tcw(potential_pos_frame)
            overlap = cam_opt.photometric_overlap(anchor_depth,
                                                  K,
                                                  Ta=anchor_Tcw,
                                                  Tb=potential_pos_Tcw,
                                                  pre_cache_x2d=pre_cache_x2d)
            if overlap_thres[0] < overlap < overlap_thres[1]:
                pos_idces.append(potential_pos_idx)

        if len(pos_idces) < num_sample_per_triple:
            continue
        else:
            sel_pos_idces = np.random.choice(pos_idces,
                                             num_sample_per_triple,
                                             replace=False)

        neg_idces = list(set(range(len(scene_frames))) - set(pos_idces))
        sel_neg_idces = np.random.choice(neg_idces,
                                         num_sample_per_triple,
                                         replace=False)

        triple_list.append({
            'anchor':
            copy.deepcopy(anchor_frame),
            'positive': [
                copy.deepcopy(scene_frames.frames[idx])
                for idx in sorted(sel_pos_idces)
            ],
            'negative': [
                copy.deepcopy(scene_frames.frames[idx])
                for idx in sorted(sel_neg_idces)
            ],
        })

        # print(camera_centers[anchor_idx])
        # print(camera_centers[pos_idces])
        # print(camera_centers[neg_idces])
        # print('----------------------------------------------------------')

    return triple_list