Exemple #1
0
def calibrate_extrinsic(config):
    path, videos, vid_indices = get_video_path(config)
    output_filename = 'extrinsics.toml'
    output_path = os.path.join(path, output_filename)

    if os.path.exists(output_path):
        print('\n{} already exists.'.format(output_filename))
        return

    try:
        intrinsics = load_intrinsics(path, vid_indices)
    except:
        print("\nIntrinsic calibration output does not exist.")
        return

    board = get_calibration_board(config)
    cam_align = config['triangulation']['cam_align']

    extrinsics, error = get_extrinsics(vid_indices, videos, intrinsics,
                                       cam_align, board)

    extrinsics_out = {}
    for k, v in extrinsics.items():
        extrinsics_out[k] = v.tolist()
    extrinsics_out['error'] = float(error)

    with open(output_path, 'w') as f:
        toml.dump(extrinsics_out, f)
Exemple #2
0
def calibrate_intrinsic(config):
    path, videos, vid_indices = get_video_path(config)

    board = get_calibration_board(config)

    for vid, vid_idx in zip(videos, vid_indices):
        output_filename = 'intrinsics_{}.toml'.format(vid_idx)
        output_path = os.path.join(path, output_filename)

        if os.path.exists(output_path):
            print('\n{} already exists.'.format(output_filename))
            continue
        else:
            calib = calibrate_camera(vid, board)
            with open(output_path, 'w') as f:
                toml.dump(calib, f)
Exemple #3
0
def draw_dropout_histogram(config):
    data_paths = config['paths_to_2d_data']
    bp_interested = config['labeling']['bodyparts_interested']
    
    path, videos, vid_indices = get_video_path(config)
    
    from matplotlib import pyplot as plt
    data = load_2d_data(config, vid_indices, bp_interested)
    l = len(data['scores'])
    fig = plt.figure()
    # print(data['scores'].shape)
    for i in range(4):
        ax = fig.add_subplot(2,2,i+1)
        ax.hist(data['scores'][:,i,:])
        ax.set_title('Cam '+str(i))
        ax.set_xlabel('Likelihood')
        ax.set_ylabel('Percentage')
        ax.set_ylim([0, l])
        ax.set_yticks([0, l/5, 2*l/5, 3*l/5, 4*l/5, l])
        ax.set_yticklabels(['0', '20', '40', '60', '80', '100'])
        ax.legend(config['labeling']['bodyparts_interested'],loc='upper center',prop={'size': 6})
    plt.show()
Exemple #4
0
def validate_3d(config, **kwargs):
    path, videos, vid_indices = get_video_path(config)
    bp_interested = config['labeling']['bodyparts_interested']
    reconstruction_threshold = config['triangulation'][
        'reconstruction_threshold']
    if config['triangulation'].get('reconstruction_output_path') is None:
        output_path = kwargs.get('output_path', '')
    else:
        output_path = config['triangulation']['reconstruction_output_path']

    try:
        intrinsics = load_intrinsics(path, vid_indices)
    except:
        print("Intrinsic calibration output does not exist.")
        return

    try:
        extrinsics = load_extrinsics(path)
    except:
        print("Extrinsic calibration output does not exist.")
        return

    cam_mats = []
    cam_mats_dist = []

    for vid_idxs in vid_indices:
        mat = arr(extrinsics[vid_idxs])
        left = arr(intrinsics[vid_idxs]['camera_mat'])
        cam_mats.append(mat)
        cam_mats_dist.append(left)

    cam_mats = arr(cam_mats)
    cam_mats_dist = arr(cam_mats_dist)

    out = load_labeled_2d_data(config, vid_indices, bp_interested)

    all_points_raw = out['points']

    all_points_und = undistort_points(all_points_raw, vid_indices, intrinsics)

    length = all_points_raw.shape[0]
    shape = all_points_raw.shape

    all_points_3d = np.zeros((shape[0], shape[2], 3))
    all_points_3d.fill(np.nan)

    errors = np.zeros((shape[0], shape[2]))
    errors.fill(np.nan)

    scores_3d = np.zeros((shape[0], shape[2]))
    scores_3d.fill(np.nan)

    num_cams = np.zeros((shape[0], shape[2]))
    num_cams.fill(np.nan)

    for i in trange(all_points_und.shape[0], ncols=70):
        for j in range(all_points_und.shape[2]):
            pts = all_points_und[i, :, j, :]
            good = ~np.isnan(pts[:, 0])
            if np.sum(good) >= 2:
                # TODO: make triangulation type configurable
                # p3d = triangulate_optim(pts[good], cam_mats[good])
                p3d = triangulate_simple(pts[good], cam_mats[good])
                all_points_3d[i, j] = p3d[:3]
                errors[i, j] = reprojection_error_und(p3d, pts[good],
                                                      cam_mats[good],
                                                      cam_mats_dist[good])
                num_cams[i, j] = np.sum(good)

    if 'reference_point' in config['triangulation'] and 'axes' in config[
            'triangulation']:
        all_points_3d_adj = correct_coordinate_frame(config, all_points_3d,
                                                     bp_interested)
    else:
        all_points_3d_adj = all_points_3d

    dout = pd.DataFrame()
    for bp_num, bp in enumerate(bp_interested):
        for ax_num, axis in enumerate(['x', 'y', 'z']):
            dout[bp + '_' + axis] = all_points_3d_adj[:, bp_num, ax_num]
        dout[bp + '_error'] = errors[:, bp_num]
        dout[bp + '_ncams'] = num_cams[:, bp_num]

    dout['fnum'] = np.arange(length)

    dout.to_csv(os.path.join(output_path, 'validate_3d_data.csv'), index=False)
Exemple #5
0
def generate_three_dim_pictures(config,csv_idx, **kwargs):
   
    path, videos, vid_indices = get_video_path(config)
    if config.get('output_video_path') is None:
        output_path = kwargs.get('output_path', '')
    else:
        output_path = config['output_video_path']
    
    try:
        connections = config['labeling']['scheme']
    except KeyError:
        connections = []
        
    bp_interested = config['labeling']['bodyparts_interested']
    bp_dict = dict(zip(bp_interested, range(len(bp_interested))))
    
    if config['triangulation'].get('reconstruction_output_path') is None:
        reconstruction_output_path = kwargs.get('output_path', '')
    else:
        reconstruction_output_path = config['triangulation']['reconstruction_output_path']
    
    reconstruction_filename = 'output_3d_data_' + str(csv_idx) + '.csv'
    data = pd.read_csv(os.path.join(reconstruction_output_path, reconstruction_filename))
    
    all_points = np.array([np.array(data.loc[:, (bp+'_x', bp+'_y', bp+'_z')])
                            for bp in bp_interested])
    
    all_errors = np.array([np.array(data.loc[:, bp+'_error'])
                            for bp in bp_interested])
    
    
    all_errors[np.isnan(all_errors)] = 10000
    
    good = (all_errors < 150)
    all_points[~good] = np.nan
    
    all_points_flat = all_points.reshape(-1, 3)
    check = ~np.isnan(all_points_flat[:, 0])
    low, high = np.percentile(all_points_flat[check], [5, 95], axis=0)
    
    fps = config['video']['fps']
    resolution = config['video']['resolution']
    resolution = (640, 480)
    
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    three_dim_video_filename = 'output_3d_video_' + str(csv_idx) + '.mp4'
    
    # cmap = plt.get_cmap('tab10')
    
    all_x_points = all_points[:,:,0]
    all_y_points = all_points[:,:,1]
    all_z_points = all_points[:,:,2]
    x_low, x_high = np.percentile(all_x_points[np.isfinite(all_x_points)], [3, 97])
    y_low, y_high = np.percentile(all_y_points[np.isfinite(all_y_points)], [3, 97])
    z_low, z_high = np.percentile(all_z_points[np.isfinite(all_z_points)], [3, 97])
    
    fig = plt.figure()
    ax = Axes3D(fig)
    
    all_points = np.transpose(all_points, (1,0,2))
    ax.view_init(azim=-48, elev=28)
    
    
    def draw_lines(points):
        ax.set_xlim([x_low-100, x_high+100])
        ax.set_ylim([y_low-100, y_high+100])
        ax.set_zlim([z_low-100, z_high+100])
        ax.set_xlabel('x (mm)')
        ax.set_ylabel('y (mm)')
        ax.set_zlabel('z (mm)')    
        ax.scatter(points[:, 0], points[:, 1], points[:, 2], 'bo', alpha=0.5)
        for connection in connections:
            xs = [points[bp_dict[connection[0]]][0], points[bp_dict[connection[1]]][0]]
            ys = [points[bp_dict[connection[0]]][1], points[bp_dict[connection[1]]][1]]
            zs = [points[bp_dict[connection[0]]][2], points[bp_dict[connection[1]]][2]]
            ax.plot(xs, ys, zs, 'g-')
    
    points = all_points[1000]
    draw_lines(points)
Exemple #6
0
def generate_three_dim_video(config,csv_idx, **kwargs):
#def generate_three_dim_video(config, azimuth, elevation **kwargs):
   
    path, videos, vid_indices = get_video_path(config)
    if config.get('output_video_path') is None:
        output_path = kwargs.get('output_path', '')
    else:
        output_path = config['output_video_path']
    
    try:
        connections = config['labeling']['scheme']
    except KeyError:
        connections = []
        
    bp_interested = config['labeling']['bodyparts_interested']
    bp_dict = dict(zip(bp_interested, range(len(bp_interested))))
    
    if config['triangulation'].get('reconstruction_output_path') is None:
        reconstruction_output_path = kwargs.get('output_path', '')
    else:
        reconstruction_output_path = config['triangulation']['reconstruction_output_path']
    
    reconstruction_filename = 'output_3d_data_' + str(csv_idx)+ '.csv'
    data = pd.read_csv(os.path.join(reconstruction_output_path, reconstruction_filename))
    
    all_points = np.array([np.array(data.loc[:, (bp+'_x', bp+'_y', bp+'_z')])
                            for bp in bp_interested])
    
    all_errors = np.array([np.array(data.loc[:, bp+'_error'])
                            for bp in bp_interested])
    
    
    all_errors[np.isnan(all_errors)] = 10000
    
    good = (all_errors < 150)
    all_points[~good] = np.nan
    
    all_points_flat = all_points.reshape(-1, 3)
    check = ~np.isnan(all_points_flat[:, 0])
    low, high = np.percentile(all_points_flat[check], [5, 95], axis=0)
    
    fps = config['video']['fps']
    resolution = config['video']['resolution']
    resolution = (640, 480)
    
    fourcc = cv2.VideoWriter_fourcc(*'DIVX')
    three_dim_video_filename = 'output_3d_video_' + str(csv_idx) + '.avi'
    writer = cv2.VideoWriter(os.path.join(output_path, three_dim_video_filename), 
                              fourcc, fps, resolution)
    
    # cmap = plt.get_cmap('tab10')
    
    all_x_points = all_points[:,:,0]
    all_y_points = all_points[:,:,1]
    all_z_points = all_points[:,:,2]
    x_low, x_high = np.percentile(all_x_points[np.isfinite(all_x_points)], [3, 97])
    y_low, y_high = np.percentile(all_y_points[np.isfinite(all_y_points)], [3, 97])
    z_low, z_high = np.percentile(all_z_points[np.isfinite(all_z_points)], [3, 97])
    
    fig = plt.figure()
    ax = Axes3D(fig)
    
    all_points = np.transpose(all_points, (1,0,2))
    ax.view_init(azim=-48, elev=28)
    
    
    def draw_lines(points):
        ax.set_xlim([x_low-100, x_high+100])
        ax.set_ylim([y_low-100, y_high+100])
        ax.set_zlim([z_low-100, z_high+100])
        ax.set_xlabel('x (mm)')
        ax.set_ylabel('y (mm)')
        ax.set_zlabel('z (mm)')    
        ax.scatter(points[:, 0], points[:, 1], points[:, 2], 'bo', alpha=0.5)
        for connection in connections:
            xs = [points[bp_dict[connection[0]]][0], points[bp_dict[connection[1]]][0]]
            ys = [points[bp_dict[connection[0]]][1], points[bp_dict[connection[1]]][1]]
            zs = [points[bp_dict[connection[0]]][2], points[bp_dict[connection[1]]][2]]
            ax.plot(xs, ys, zs, 'g-')
    
    # points = all_points[0]
    # draw_lines(points)
    # print('ax.azim {}'.format(ax.azim))
    # print('ax.elev {}'.format(ax.elev))
    # # For testing
    # all_points = all_points[:600]
    canvas = FigureCanvas(fig)
    for i in trange((len(all_points)), ncols=70):
        ax.cla()
        points = all_points[i]
        draw_lines(points)
        canvas.draw()
        img = np.array(canvas.renderer._renderer)
        img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
        img = cv2.resize(img, resolution)
        writer.write(img)
    plt.close()
    writer.release()
Exemple #7
0
def reconstruction_validation(config, img_paths):
    images = [cv2.imread(img_path) for img_path in img_paths]
    
    board = get_calibration_board(config)
    (w,h) = board.getChessboardSize()
    num_corners = (w-1)*(h-1)
    
    path, videos, vid_indices = get_video_path(config)
    num_cams = len(vid_indices)
    intrinsics = load_intrinsics(path, vid_indices)
    
    all_detectedCorners = np.zeros((num_corners, num_cams, 2))
    all_detectedCorners.fill(np.nan)
    all_detectedIds = []
    images_with_corners = []
    
    for i, (image, vid_idx) in enumerate(zip(images, vid_indices)):
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        intrinsic = intrinsics[vid_idx]
        detectedCorners, detectedIds = detect_aruco(gray, intrinsic, board)
        images_with_corners.append(cv2.aruco.drawDetectedCornersCharuco(image, 
                                                     detectedCorners,
                                                     detectedIds))
        all_detectedIds.append(detectedIds)
        
        for coord, j in zip(detectedCorners, detectedIds):
            all_detectedCorners[j[0]][i] = coord
    
    extrinsics = load_extrinsics(path)
    
    cam_mats = np.array([extrinsics[vid_idx] for vid_idx in vid_indices])
    
    undistorted_corners = undistort_points(all_detectedCorners, vid_indices, intrinsics)
    
    points_3d, _ = triangulate_points(undistorted_corners, cam_mats)
    points_3d = points_3d[:, :3]
    
    points_3d_transform = transform_corners(points_3d, w, h)
    
    square_length = config['calibration']['board_square_side_length']
    
    x = np.linspace((-w/2+1)*square_length, (w/2-1)*square_length, w-1)
    y = np.linspace((-h/2+1)*square_length, (h/2-1)*square_length, h-1)
    xv, yv = np.meshgrid(x, y)
    
    pseudo_real_corners = np.zeros((num_corners, 3))
    pseudo_real_corners[:, 0] = np.reshape(xv, (-1))
    pseudo_real_corners[:, 1] = np.reshape(yv, (-1))

    subplot_w = int(num_cams // np.floor(np.sqrt(num_cams)))
    subplot_h = num_cams / subplot_w
    
    fig = plt.figure()
    
    for i in range(num_cams):
        ax = fig.add_subplot(subplot_w, subplot_h, i+1)
        ax.imshow(images_with_corners[i])
        ax.axis('off')
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    
    labels = ['id_'+str(i) for i in range(num_corners)]
    
    for i, (pred, real) in enumerate(zip(points_3d_transform, pseudo_real_corners)):
        ax.scatter(pred[0], pred[1], pred[2], c='r', alpha=0.5)
        ax.scatter(real[0], real[1], real[2], c='b', alpha=0.5)
        annotate3D(ax, s=labels[i], xyz=pred, fontsize=8, xytext=(-3,3),
               textcoords='offset points', ha='center',va='bottom')
    
    ax_min, ax_max = -np.floor(max(w, h)*square_length)//2, np.floor(max(w, h)*square_length//2)
    ax.set_xlim([ax_min, ax_max])
    ax.set_ylim([ax_min, ax_max])
    ax.set_zlim([ax_min, ax_max])
    ax.view_init(elev=50, azim=-70)
    
    ax.set_xlabel('x (mm)')
    ax.set_ylabel('y (mm)')
    ax.set_zlabel('z (mm)')    
        
    return points_3d, points_3d_transform