Example #1
0
    def __call__(self, est_data, gt_data, bins_tensor):
        pitch_cls_loss, pitch_reg_loss = cls_reg_loss(est_data['pitch_cls_result'], gt_data['pitch_cls'], est_data['pitch_reg_result'], gt_data['pitch_reg'])
        roll_cls_loss, roll_reg_loss = cls_reg_loss(est_data['roll_cls_result'], gt_data['roll_cls'], est_data['roll_reg_result'], gt_data['roll_reg'])
        lo_ori_cls_loss, lo_ori_reg_loss = cls_reg_loss(est_data['lo_ori_cls_result'], gt_data['lo_ori_cls'], est_data['lo_ori_reg_result'], gt_data['lo_ori_reg'])
        lo_centroid_loss = reg_criterion(est_data['lo_centroid_result'], gt_data['lo_centroid']) * cls_reg_ratio
        lo_coeffs_loss = reg_criterion(est_data['lo_coeffs_result'], gt_data['lo_coeffs']) * cls_reg_ratio

        lo_bdb3D_result = get_layout_bdb_sunrgbd(bins_tensor, est_data['lo_ori_reg_result'], gt_data['lo_ori_cls'], est_data['lo_centroid_result'],
                                                 est_data['lo_coeffs_result'])
        # layout bounding box corner loss
        lo_corner_loss = cls_reg_ratio * reg_criterion(lo_bdb3D_result, gt_data['lo_bdb3D'])

        return {'pitch_cls_loss':pitch_cls_loss, 'pitch_reg_loss':pitch_reg_loss,
                'roll_cls_loss':roll_cls_loss, 'roll_reg_loss':roll_reg_loss,
                'lo_ori_cls_loss':lo_ori_cls_loss, 'lo_ori_reg_loss':lo_ori_reg_loss,
                'lo_centroid_loss':lo_centroid_loss, 'lo_coeffs_loss':lo_coeffs_loss,
                'lo_corner_loss':lo_corner_loss}, {'lo_bdb3D_result':lo_bdb3D_result}
Example #2
0
def run(cfg):
    '''Begin to run network.'''
    checkpoint = CheckpointIO(cfg)

    '''Mount external config data'''
    cfg = mount_external_config(cfg)

    '''Load save path'''
    cfg.log_string('Data save path: %s' % (cfg.save_path))

    '''Load device'''
    cfg.log_string('Loading device settings.')
    device = load_device(cfg)

    '''Load net'''
    cfg.log_string('Loading model.')
    net = load_model(cfg, device=device)
    checkpoint.register_modules(net=net)
    cfg.log_string(net)

    '''Load existing checkpoint'''
    checkpoint.parse_checkpoint()
    cfg.log_string('-' * 100)

    '''Load data'''
    cfg.log_string('Loading data.')
    data = load_demo_data(cfg.config['demo_path'], device)

    '''Run demo'''
    net.train(cfg.config['mode'] == 'train')
    with torch.no_grad():
        start = time()
        est_data = net(data)
        end = time()

    print('Time elapsed: %s.' % (end-start))

    '''write and visualize outputs'''
    from net_utils.libs import get_layout_bdb_sunrgbd, get_rotation_matix_result, get_bdb_evaluation
    from scipy.io import savemat
    from libs.tools import write_obj

    lo_bdb3D_out = get_layout_bdb_sunrgbd(cfg.bins_tensor, est_data['lo_ori_reg_result'],
                                          torch.argmax(est_data['lo_ori_cls_result'], 1),
                                          est_data['lo_centroid_result'],
                                          est_data['lo_coeffs_result'])
    # camera orientation for evaluation
    cam_R_out = get_rotation_matix_result(cfg.bins_tensor,
                                          torch.argmax(est_data['pitch_cls_result'], 1), est_data['pitch_reg_result'],
                                          torch.argmax(est_data['roll_cls_result'], 1), est_data['roll_reg_result'])

    # projected center
    P_result = torch.stack(((data['bdb2D_pos'][:, 0] + data['bdb2D_pos'][:, 2]) / 2 -
                            (data['bdb2D_pos'][:, 2] - data['bdb2D_pos'][:, 0]) * est_data['offset_2D_result'][:, 0],
                            (data['bdb2D_pos'][:, 1] + data['bdb2D_pos'][:, 3]) / 2 -
                            (data['bdb2D_pos'][:, 3] - data['bdb2D_pos'][:, 1]) * est_data['offset_2D_result'][:,1]), 1)

    bdb3D_out_form_cpu, bdb3D_out = get_bdb_evaluation(cfg.bins_tensor,
                                                       torch.argmax(est_data['ori_cls_result'], 1),
                                                       est_data['ori_reg_result'],
                                                       torch.argmax(est_data['centroid_cls_result'], 1),
                                                       est_data['centroid_reg_result'],
                                                       data['size_cls'], est_data['size_reg_result'], P_result,
                                                       data['K'], cam_R_out, data['split'], return_bdb=True)

    # save results
    nyu40class_ids = [int(evaluate_bdb['classid']) for evaluate_bdb in bdb3D_out_form_cpu]
    save_path = cfg.config['demo_path'].replace('inputs', 'outputs')
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    # save layout
    savemat(os.path.join(save_path, 'layout.mat'),
            mdict={'layout': lo_bdb3D_out[0, :, :].cpu().numpy()})
    # save bounding boxes and camera poses
    interval = data['split'][0].cpu().tolist()
    current_cls = nyu40class_ids[interval[0]:interval[1]]

    savemat(os.path.join(save_path, 'bdb_3d.mat'),
            mdict={'bdb': bdb3D_out_form_cpu[interval[0]:interval[1]], 'class_id': current_cls})
    savemat(os.path.join(save_path, 'r_ex.mat'),
            mdict={'cam_R': cam_R_out[0, :, :].cpu().numpy()})
    # save meshes
    current_faces = est_data['out_faces'][interval[0]:interval[1]].cpu().numpy()
    current_coordinates = est_data['meshes'].transpose(1, 2)[interval[0]:interval[1]].cpu().numpy()

    for obj_id, obj_cls in enumerate(current_cls):
        file_path = os.path.join(save_path, '%s_%s.obj' % (obj_id, obj_cls))

        mesh_obj = {'v': current_coordinates[obj_id],
                    'f': current_faces[obj_id]}

        write_obj(file_path, mesh_obj)

    #########################################################################
    #
    #   Visualization
    #
    #########################################################################
    import scipy.io as sio
    from utils.visualize import format_bbox, format_layout, format_mesh, Box
    from glob import glob

    pre_layout_data = sio.loadmat(os.path.join(save_path, 'layout.mat'))['layout']
    pre_box_data = sio.loadmat(os.path.join(save_path, 'bdb_3d.mat'))

    pre_boxes = format_bbox(pre_box_data, 'prediction')
    pre_layout = format_layout(pre_layout_data)
    pre_cam_R = sio.loadmat(os.path.join(save_path, 'r_ex.mat'))['cam_R']

    vtk_objects, pre_boxes = format_mesh(glob(os.path.join(save_path, '*.obj')), pre_boxes)

    image = np.array(Image.open(os.path.join(cfg.config['demo_path'], 'img.jpg')).convert('RGB'))
    cam_K = np.loadtxt(os.path.join(cfg.config['demo_path'], 'cam_K.txt'))

    scene_box = Box(image, None, cam_K, None, pre_cam_R, None, pre_layout, None, pre_boxes, 'prediction', output_mesh = vtk_objects)
    scene_box.draw_projected_bdb3d('prediction', if_save=True, save_path = '%s/3dbbox.png' % (save_path))
    scene_box.draw3D(if_save=True, save_path = '%s/recon.png' % (save_path))
Example #3
0
    def get_metric_values(self, est_data, gt_data):
        ''' Performs a evaluation step.
        '''
        # Layout IoU
        lo_bdb3D_out = get_layout_bdb_sunrgbd(
            self.cfg.bins_tensor, est_data['lo_ori_reg_result'],
            torch.argmax(est_data['lo_ori_cls_result'], 1),
            est_data['lo_centroid_result'], est_data['lo_coeffs_result'])

        layout_iou = []
        for index, sequence_id in enumerate(gt_data['sequence_id']):
            lo_iou = get_iou_cuboid(
                lo_bdb3D_out[index, :, :].cpu().numpy(),
                gt_data['lo_bdb3D'][index, :, :].cpu().numpy())
            layout_iou.append(lo_iou)

        # camera orientation for evaluation
        cam_R_out = get_rotation_matix_result(
            self.cfg.bins_tensor, torch.argmax(est_data['pitch_cls_result'],
                                               1),
            est_data['pitch_reg_result'],
            torch.argmax(est_data['roll_cls_result'],
                         1), est_data['roll_reg_result'])

        # projected center
        P_result = torch.stack(
            ((gt_data['bdb2D_pos'][:, 0] + gt_data['bdb2D_pos'][:, 2]) / 2 -
             (gt_data['bdb2D_pos'][:, 2] - gt_data['bdb2D_pos'][:, 0]) *
             est_data['offset_2D_result'][:, 0],
             (gt_data['bdb2D_pos'][:, 1] + gt_data['bdb2D_pos'][:, 3]) / 2 -
             (gt_data['bdb2D_pos'][:, 3] - gt_data['bdb2D_pos'][:, 1]) *
             est_data['offset_2D_result'][:, 1]), 1)

        bdb3D_out_form_cpu, bdb3D_out = get_bdb_evaluation(
            self.cfg.bins_tensor,
            torch.argmax(est_data['ori_cls_result'], 1),
            est_data['ori_reg_result'],
            torch.argmax(est_data['centroid_cls_result'], 1),
            est_data['centroid_reg_result'],
            gt_data['size_cls'],
            est_data['size_reg_result'],
            P_result,
            gt_data['K'],
            cam_R_out,
            gt_data['split'],
            return_bdb=True)

        bdb2D_out = get_bdb_2d_result(bdb3D_out, cam_R_out, gt_data['K'],
                                      gt_data['split'])

        nyu40class_ids = []
        IoU3D = []
        IoU2D = []
        for index, evaluate_bdb in enumerate(bdb3D_out_form_cpu):
            NYU40CLASS_ID = int(evaluate_bdb['classid'])
            iou_3D = get_iou_cuboid(
                get_corners_of_bb3d_no_index(evaluate_bdb['basis'],
                                             evaluate_bdb['coeffs'],
                                             evaluate_bdb['centroid']),
                gt_data['bdb3D'][index, :, :].cpu().numpy())

            box1 = bdb2D_out[index, :].cpu().numpy()
            box2 = gt_data['bdb2D_from_3D_gt'][index, :].cpu().numpy()

            box1 = {'u1': box1[0], 'v1': box1[1], 'u2': box1[2], 'v2': box1[3]}
            box2 = {'u1': box2[0], 'v1': box2[1], 'u2': box2[2], 'v2': box2[3]}

            iou_2D = get_iou(box1, box2)

            nyu40class_ids.append(NYU40CLASS_ID)
            IoU3D.append(iou_3D)
            IoU2D.append(iou_2D)
        '''Save results'''
        if self.cfg.config['log']['save_results']:

            save_path = self.cfg.config['log']['vis_path']

            for index, sequence_id in enumerate(gt_data['sequence_id']):
                save_path_per_img = os.path.join(save_path,
                                                 str(sequence_id.item()))
                if not os.path.exists(save_path_per_img):
                    os.mkdir(save_path_per_img)

                # save layout results
                savemat(
                    os.path.join(save_path_per_img, 'layout.mat'),
                    mdict={'layout': lo_bdb3D_out[index, :, :].cpu().numpy()})

                # save bounding boxes and camera poses
                interval = gt_data['split'][index].cpu().tolist()
                current_cls = nyu40class_ids[interval[0]:interval[1]]

                savemat(os.path.join(save_path_per_img, 'bdb_3d.mat'),
                        mdict={
                            'bdb': bdb3D_out_form_cpu[interval[0]:interval[1]],
                            'class_id': current_cls
                        })
                savemat(os.path.join(save_path_per_img, 'r_ex.mat'),
                        mdict={'cam_R': cam_R_out[index, :, :].cpu().numpy()})

                current_faces = est_data['out_faces'][
                    interval[0]:interval[1]].cpu().numpy()
                current_coordinates = est_data['meshes'].transpose(
                    1, 2)[interval[0]:interval[1]].cpu().numpy()

                for obj_id, obj_cls in enumerate(current_cls):
                    file_path = os.path.join(save_path_per_img,
                                             '%s_%s.obj' % (obj_id, obj_cls))

                    mesh_obj = {
                        'v': current_coordinates[obj_id],
                        'f': current_faces[obj_id]
                    }

                    write_obj(file_path, mesh_obj)

        metrics = {}
        metrics['layout_iou'] = np.mean(layout_iou)
        metrics['iou_3d'] = IoU3D
        metrics['iou_2d'] = IoU2D
        return metrics