Example #1
0
 def __init__(self, Thresh=0.7, HallucinatePeeledColor=True):
     super().__init__()
     self.MaskLoss = nn.BCELoss(size_average=True, reduce=True)
     self.Sigmoid = nn.Sigmoid()
     self.Thresh = Thresh
     self.HallucinatePeeledColor = HallucinatePeeledColor
     self.ChamferDist = ChamferDistance()
Example #2
0
import torch
import numpy as np
from tk3dv.extern.chamfer import ChamferDistance
chamfer_dist = ChamferDistance()

#...
# points and points_reconstructed are n_points x 3 matrices

points = torch.from_numpy(np.array([[[1, 1, 0], [2, 1, 0]]], dtype=np.float32))
#points.to(torch.device('cuda'))
points_reconstructed = torch.from_numpy(np.array([[[2, 2, 0]]], dtype=np.float32))
#points_reconstructed.to(torch.device('cuda'))

dist1, dist2 = chamfer_dist(points, points_reconstructed)
# outputs minimum squared distance for each point in the point cloud
print(dist1)
print(dist2)
loss = (torch.mean(dist1)) + (torch.mean(dist2))
print('loss: ' + str(loss))
total_dist = dist1 + dist2
cham = torch.sum(dist1) + torch.sum(dist2)
print('chamfer dist: ' + str(cham))
Example #3
0
def test_shape_recon(model, test_loader, device, log_out, observed_steps,
                     unobserved_steps):
    '''
    Evaluates shape reconstruction from CNF.
    '''
    test_dataset = test_loader.dataset

    chamfer_dist = ChamferDistance()

    log(
        log_out,
        'Observed steps [%s]' % (','.join([str(idx)
                                           for idx in observed_steps])))
    log(
        log_out, 'Unobserved steps [%s]' %
        (','.join([str(idx) for idx in unobserved_steps])))

    use_unobserved_steps = len(unobserved_steps) > 0

    model.eval()

    nfe_stats = []
    model_ids = []
    seq_ids = []
    observed_stats = {'chamfer': [], 'emd': [], 'infer_time': []}
    unobserved_stats = {'chamfer': [], 'emd': []}
    num_batches_total = 0
    for i, data in enumerate(test_loader):
        print('Batch: %d / %d' % (i, len(test_loader)))
        pcl_in, nocs_out = data[
            0]  # world point cloud, corresponding nocs point cloud
        pcl_in = pcl_in.to(device)  # B x T x N x 4 (x,y,z,t)
        nocs_out = nocs_out.to(device)  # B x T x N x 4 (x,y,z,t)

        cur_model_ids = data[1]
        cur_seq_ids = data[2]
        model_ids.extend(cur_model_ids)
        seq_ids.extend(cur_seq_ids)

        # print(cur_model_ids)
        # print(cur_seq_ids)

        B, T, N, _ = pcl_in.size()
        num_batches_total += B
        T_observed = len(observed_steps)
        T_unobserved = len(unobserved_steps)

        if T != PROTOCOL_NUM_STEPS:
            print('Test protocol requires %d steps, but %d given!' %
                  (PROTOCOL_NUM_STEPS, T))
            exit()
        if N != PROTOCOL_NUM_PTS:
            print('Test protocol requires %d points, but %d given!' %
                  (PROTOCOL_NUM_PTS, N))
            exit()

        # only use the observed steps as input
        observed_pcl_in = pcl_in[:, observed_steps, :, :]

        elapsed = 0.0
        start_t = time.time()
        # reconstruct at all time steps, both observed and unobserved
        _, _, pred_pcl, _ = model.reconstruct(observed_pcl_in,
                                              num_points=N,
                                              timestamps=nocs_out[0, :, 0, 3],
                                              constant_in_time=False)
        elapsed = time.time() - start_t

        cur_nfe = model.get_nfe()
        nfe_stats.append(cur_nfe)

        # evaluate Chamfer and EMD
        # first observed
        observed_tnocs_gt = nocs_out[:, observed_steps, :, :3].view(
            (B * T_observed, N, 3))  # don't need time stamp for reconstruction
        observed_reconstr = pred_pcl[:, observed_steps, :, :].view(
            (B * T_observed, N, 3))

        mean_chamfer, cur_emd = eval_reconstr_frames(observed_reconstr,
                                                     observed_tnocs_gt,
                                                     chamfer_dist)
        observed_stats['chamfer'].extend(mean_chamfer.tolist())
        observed_stats['emd'].extend(cur_emd.tolist())
        observed_stats['infer_time'].append(elapsed)

        print('==== OBSERVED ====')
        print('Shape Recon Mean Chamfer: %f' %
              (np.mean(observed_stats['chamfer']) * 1000))
        print('Shape Recon Median Chamfer: %f' %
              (np.median(observed_stats['chamfer']) * 1000))
        print('Shape Recon Mean EMD: %f' %
              (np.mean(observed_stats['emd']) * 1000))
        print('Shape Recon Median EMD: %f' %
              (np.median(observed_stats['emd']) * 1000))
        print('NFE Mean: (%f, %f)' %
              tuple(np.mean(nfe_stats, axis=0).tolist()))
        print('Infer time mean: %f' % (np.mean(observed_stats['infer_time'])))

        if use_unobserved_steps:
            unobserved_tnocs_gt = nocs_out[:, unobserved_steps, :, :3].view(
                (B * T_unobserved, N,
                 3))  # don't need time stamp for reconstruction
            unobserved_reconstr = pred_pcl[:, unobserved_steps, :, :].view(
                (B * T_unobserved, N, 3))

            mean_chamfer, cur_emd = eval_reconstr_frames(
                unobserved_reconstr, unobserved_tnocs_gt, chamfer_dist)
            unobserved_stats['chamfer'].extend(mean_chamfer.tolist())
            unobserved_stats['emd'].extend(cur_emd.tolist())

            print('==== UNOBSERVED ====')
            print('Shape Recon Mean Chamfer: %f' %
                  (np.mean(unobserved_stats['chamfer']) * 1000))
            print('Shape Recon Median Chamfer: %f' %
                  (np.median(unobserved_stats['chamfer']) * 1000))
            print('Shape Recon Mean EMD: %f' %
                  (np.mean(unobserved_stats['emd']) * 1000))
            print('Shape Recon Median EMD: %f' %
                  (np.median(unobserved_stats['emd']) * 1000))
            print('NFE Mean: (%f, %f)' %
                  tuple(np.mean(nfe_stats, axis=0).tolist()))

        # print(len(observed_stats['chamfer']))
        # print(len(unobserved_stats['chamfer']))

    # aggregate
    stats_list = [observed_stats, unobserved_stats
                  ] if use_unobserved_steps else [observed_stats]
    stats_names = ['OBSERVED', 'UNOBSERVED'
                   ] if use_unobserved_steps else ['OBSERVED']
    for stat_dict, stats_name in zip(stats_list, stats_names):
        mean_chamfer_err = np.mean(stat_dict['chamfer']) * 1000.0
        median_chamfer_err = np.median(stat_dict['chamfer']) * 1000.0
        std_chamfer_err = np.std(stat_dict['chamfer']) * 1000.0
        mean_emd_err = np.mean(stat_dict['emd']) * 1000.0
        median_emd_err = np.median(stat_dict['emd']) * 1000.0
        std_emd_err = np.std(stat_dict['emd']) * 1000.0

        log(
            log_out,
            '================  %s SAMPLING RECONSTR EVAL ====================='
            % (stats_name))
        log(
            log_out, 'mean CHAMFER error (x1000): %f +- %f, median: %f' %
            (mean_chamfer_err, std_chamfer_err, median_chamfer_err))
        log(
            log_out, 'mean EMD error (x1000): %f +- %f, median: %f' %
            (mean_emd_err, std_emd_err, median_emd_err))
    log(log_out,
        'NFE Mean: (%f, %f)' % tuple(np.mean(nfe_stats, axis=0).tolist()))
    log(log_out,
        'mean Inference time: %f' % (np.mean(observed_stats['infer_time'])))

    # save the evaluation data
    per_seq_data_out = log_out[:-len('txt')] + 'npz'
    np.savez(per_seq_data_out,
             observed_chamfer=observed_stats['chamfer'],
             observed_emd=observed_stats['emd'],
             unobserved_chamfer=unobserved_stats['chamfer'],
             unobserved_emd=unobserved_stats['emd'])

    # log per-sequence performance
    per_seq_log = log_out[:-len('txt')] + 'csv'
    print('Per seq performance being saved to %s...' % (per_seq_log))
    stats_steps = [T_observed, T_unobserved]
    with open(per_seq_log, 'w', newline='') as csvfile:
        # write header
        csvwriter = csv.writer(csvfile,
                               delimiter=',',
                               quotechar='|',
                               quoting=csv.QUOTE_MINIMAL)
        header = ['type', 'model_id', 'seq_id', 'chamfer', 'emd']
        csvwriter.writerow(header)
        for stat_dict, stats_name, stats_T in zip(stats_list, stats_names,
                                                  stats_steps):
            per_seq_chamfer = np.array(stat_dict['chamfer']).reshape(
                (num_batches_total, stats_T))
            per_seq_chamfer = np.mean(per_seq_chamfer, axis=1)
            per_seq_emd = np.array(stat_dict['emd']).reshape(
                (num_batches_total, stats_T))
            per_seq_emd = np.mean(per_seq_emd, axis=1)

            for line_idx in range(len(model_ids)):
                cur_line = [
                    stats_name, model_ids[line_idx], seq_ids[line_idx],
                    per_seq_chamfer[line_idx], per_seq_emd[line_idx]
                ]
                csvwriter.writerow(cur_line)

    return
Example #4
0
 def __init__(self, device='cuda', torch_device=None):
     if torch_device is None:
         self.device = torch.device(device) # 'cuda' or 'cpu'
     else:
         self.device = torch_device
     self.ChamferDist = ChamferDistance()
Example #5
0
def test_viz(cfg, model, test_dataset, test_loader, device):
    '''
    Visualize CaSPR results
    '''

    from tk3dv.extern.chamfer import ChamferDistance  # only import if we need it
    chamfer_dist = ChamferDistance()

    model.eval()
    for i, data in enumerate(test_loader):
        print('Batch: %d / %d' % (i, len(test_loader)))
        pcl_in, nocs_out = data[
            0]  # world point cloud, corresponding nocs point cloud
        pcl_in = pcl_in.to(device)  # B x T x N x 4 (x,y,z,t)
        nocs_out = nocs_out.to(device)  # B x T x N x 4 (x,y,z,t)

        # print(nocs_out.size())

        B, T, N, _ = pcl_in.size()

        if B != 1:
            print('batch size must be 1 to visualize!')
            exit()

        cur_model_id = data[1][0]
        cur_seq_id = data[2][0]
        print('Model %s' % (cur_model_id))
        print('Seq %s' % (cur_seq_id))

        #
        # first show quantitative eval for context
        #
        pred_tnocs = None
        if cfg.viz_tnocs and not (cfg.viz_observed or cfg.viz_interpolated):
            _, pred_tnocs = model.encode(pcl_in)
        else:  # we need sampling predictions
            samp_pcl, logprob_samp_pcl, pred_pcl, pred_tnocs = model.reconstruct(
                pcl_in,
                num_points=cfg.num_sampled_pts,
                constant_in_time=cfg.constant_in_time,
                max_timestamp=test_dataset.max_timestamp,
                sample_contours=SAMPLE_CONTOURS_RADII
                if cfg.sample_contours else None)
        if cfg.viz_tnocs:
            nocs_err = torch.norm(pred_tnocs[:, :, :, :3] -
                                  nocs_out[:, :, :, :3],
                                  dim=3).mean().to('cpu').item()
            print('Cur L2 nocs spatial error: %f' % (nocs_err))

        if cfg.viz_observed or cfg.viz_interpolated:
            quant_num_pts = min([cfg.num_sampled_pts, N])
            observed_tnocs_gt = nocs_out[:, :, :quant_num_pts, :3].view(
                (B * T, quant_num_pts,
                 3))  # don't need time stamp for reconstruction
            observed_reconstr = pred_pcl[:, :, :quant_num_pts, :].view(
                (B * T, quant_num_pts, 3))
            mean_chamfer, cur_emd = eval_reconstr_frames(
                observed_reconstr, observed_tnocs_gt, chamfer_dist)
            print('Cur Mean Chamfer: %f' % (np.mean(mean_chamfer) * 1000))
            print('Cur Mean EMD: %f' % (np.mean(cur_emd) * 1000))

        #
        # Visualize
        #

        # needed by all visualizations
        pcl_in_np, gt_nocs_np = torch_to_numpy([pcl_in, nocs_out])
        viz_gt_nocs = np_to_list(gt_nocs_np)
        viz_pcl_in = np_to_list(pcl_in_np)
        gt_nocs_rgb = copy_pcl_list(viz_gt_nocs)

        base_seq_to_viz = [viz_gt_nocs]
        base_rgb_to_viz = [gt_nocs_rgb]
        if cfg.show_input_seq:
            base_seq_to_viz.append(viz_pcl_in)
            base_rgb_to_viz.append(gt_nocs_rgb)

        # TNOCS regression visualization
        if cfg.viz_tnocs:
            print('Visualizing TNOCS Regression Prediction...')
            pred_nocs_np = torch_to_numpy([pred_tnocs])[0]

            viz_pred_nocs = np_to_list(pred_nocs_np)
            if cfg.tnocs_error_map:
                pred_nocs_rgb = [
                    get_error_colors(viz_pred_nocs[idx], viz_gt_nocs[idx])
                    for idx in range(gt_nocs_np.shape[1])
                ]
            else:
                pred_nocs_rgb = copy_pcl_list(viz_pred_nocs)
            # translate to be in predicted viz cube
            viz_pred_nocs = shift_pcl_list(viz_pred_nocs, PRED_OFFSET)

            seq_to_viz = base_seq_to_viz + [viz_pred_nocs]
            rgb_to_viz = base_rgb_to_viz + [pred_nocs_rgb]

            viz_pcl_seq(seq_to_viz,
                        rgb_seq=rgb_to_viz,
                        fps=T,
                        autoplay=True,
                        draw_cubes=cfg.show_nocs_cubes)

        # Observed sampling visualization
        if cfg.viz_observed:
            print('Visualizing CaSPR Observed Reconstruction Sampling...')
            viz_caspr_reconstruction(cfg, samp_pcl, logprob_samp_pcl, pred_pcl,
                                     base_seq_to_viz, base_rgb_to_viz, T)

        # Interpolated sampling visualization
        if cfg.viz_interpolated:
            print('Visualizing CaSPR Interpolated Reconstruction Sampling...')
            timstamps = torch.linspace(0.0, 1.0,
                                       cfg.num_sampled_steps).to(pcl_in)
            # rerun reconstruction on higher-res timestamps
            samp_pcl, logprob_samp_pcl, pred_pcl, _ = model.reconstruct(
                pcl_in,
                timestamps=timstamps,
                num_points=cfg.num_sampled_pts,
                constant_in_time=cfg.constant_in_time,
                sample_contours=SAMPLE_CONTOURS_RADII
                if cfg.sample_contours else None)

            # naively subsample observations to visualize with interpolated result
            subsampled_gt_nocs = []
            subsampled_pcl_in = []
            subsampled_times = []
            subsamples_per_step = int(float(cfg.num_sampled_steps) / T)
            for time_idx in range(T):
                for repeat_idx in range(subsamples_per_step):
                    subsampled_gt_nocs.append(gt_nocs_np[0, time_idx, :, :3])
                    subsampled_pcl_in.append(pcl_in_np[0, time_idx, :, :3])
                    subsampled_times.append(gt_nocs_np[0, time_idx, 0, 3])
            # fill any extras
            while len(subsampled_gt_nocs) < cfg.num_sampled_steps:
                subsampled_gt_nocs.append(gt_nocs_np[0, T - 1, :, :3])
                subsampled_pcl_in.append(pcl_in_np[0, T - 1, :, :3])
                subsampled_times.append(gt_nocs_np[0, T - 1, 0, 3])

            viz_gt_nocs = subsampled_gt_nocs
            viz_pcl_in = subsampled_pcl_in
            gt_nocs_rgb = copy_pcl_list(viz_gt_nocs)

            cur_base_seq_to_viz = [viz_gt_nocs]
            cur_base_rgb_to_viz = [gt_nocs_rgb]
            if cfg.show_input_seq:
                cur_base_seq_to_viz.append(viz_pcl_in)
                cur_base_rgb_to_viz.append(gt_nocs_rgb)

            viz_caspr_reconstruction(cfg, samp_pcl, logprob_samp_pcl, pred_pcl,
                                     cur_base_seq_to_viz, cur_base_rgb_to_viz,
                                     cfg.num_sampled_steps)