예제 #1
0
def test_net(
        args,
        dataset_name,
        proposal_file,
        output_dir,
        ind_range=None,
        gpu_id=0):
    """Run inference on all images in a dataset or over an index range of images
    in a dataset using a single GPU.
    """
    assert not cfg.MODEL.RPN_ONLY, 'Use rpn_generate to generate proposals from RPN-only models'
    dataset = JsonDataset(dataset_name, args.dataset_dir)
    timers = defaultdict(Timer)
    if ind_range is not None:
        if cfg.TEST.SOFT_NMS.ENABLED:
            det_name = 'detection_range_%s_%s_soft_nms.pkl' % tuple(ind_range)
        else:
            det_name = 'detection_range_(%d_%d)_nms_%.1f.pkl' % (ind_range[0], ind_range[1], cfg.TEST.NMS)
    else:
        det_name = 'detections.pkl'
    det_file = os.path.join(output_dir, det_name)
    roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset(dataset, proposal_file, ind_range, args)
    num_images = len(roidb)
    image_ids = []
    num_classes = cfg.MODEL.NUM_CLASSES
    all_boxes, all_segms, all_keyps = empty_results(num_classes, num_images)

    for i, entry in enumerate(roidb):
        image_ids.append(entry['image'])
    args.image_ids = image_ids

    # If we have already computed the boxes
    if os.path.exists(det_file):
        obj = load_object(det_file)
        all_boxes, all_segms, all_keyps = obj['all_boxes'], obj['all_segms'], obj['all_keyps']

    else:
        model = initialize_model_from_cfg(args, gpu_id=gpu_id)
        for i, entry in enumerate(roidb):
            if cfg.TEST.PRECOMPUTED_PROPOSALS:
                # The roidb may contain ground-truth rois (for example, if the roidb
                # comes from the training or val split). We only want to evaluate
                # detection on the *non*-ground-truth rois. We select only the rois
                # that have the gt_classes field set to 0, which means there's no
                # ground truth.
                box_proposals = entry['boxes'][entry['gt_classes'] == 0]
                if len(box_proposals) == 0:
                    continue
            else:
                # Faster R-CNN type models generate proposals on-the-fly with an
                # in-network RPN; 1-stage models don't require proposals.
                box_proposals = None

            im = cv2.imread(entry['image'])
            cls_boxes_i, cls_segms_i, cls_keyps_i, car_cls_i, euler_angle_i, trans_pred_i = im_detect_all(model, im, box_proposals, timers, dataset)
            extend_results(i, all_boxes, cls_boxes_i)
            if cls_segms_i is not None:
                extend_results(i, all_segms, cls_segms_i)
            if cls_keyps_i is not None:
                extend_results(i, all_keyps, cls_keyps_i)

            if i % 10 == 0:  # Reduce log file size
                ave_total_time = np.sum([t.average_time for t in timers.values()])
                eta_seconds = ave_total_time * (num_images - i - 1)
                eta = str(datetime.timedelta(seconds=int(eta_seconds)))
                det_time = (
                    timers['im_detect_bbox'].average_time +
                    timers['im_detect_mask'].average_time +
                    timers['im_detect_keypoints'].average_time
                )
                misc_time = (
                    timers['misc_bbox'].average_time +
                    timers['misc_mask'].average_time +
                    timers['misc_keypoints'].average_time
                )
                logger.info(
                    (
                        'im_detect: range [{:d}, {:d}] of {:d}: '
                        '{:d}/{:d} {:.3f}s + {:.3f}s (eta: {})'
                    ).format(
                        start_ind + 1, end_ind, total_num_images, start_ind + i + 1,
                        start_ind + num_images, det_time, misc_time, eta
                    )
                )

            if cfg.VIS:
                im_name = os.path.splitext(os.path.basename(entry['image']))[0]
                vis_utils.vis_one_image_eccv2018_car_3d(
                    im[:, :, ::-1],
                    '{:d}_{:s}'.format(i, im_name),
                    os.path.join(output_dir, 'vis'),
                    boxes=cls_boxes_i,
                    car_cls_prob=car_cls_i,
                    euler_angle=euler_angle_i,
                    trans_pred=trans_pred_i,
                    car_models=dataset.Car3D.car_models,
                    intrinsic=dataset.Car3D.get_intrinsic_mat(),
                    segms=cls_segms_i,
                    keypoints=cls_keyps_i,
                    thresh=0.9,
                    box_alpha=0.8,
                    dataset=dataset.Car3D)
        cfg_yaml = yaml.dump(cfg)
        save_object(
            dict(
                all_boxes=all_boxes,
                all_segms=all_segms,
                all_keyps=all_keyps,
                cfg=cfg_yaml
            ), det_file
        )
        logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file)))

    results = task_evaluation.evaluate_all(dataset, all_boxes, all_segms, all_keyps, output_dir, args)
    return results
예제 #2
0
def test_net_Car3D(
        args,
        dataset_name,
        proposal_file,
        output_dir,
        ind_range=None,
        gpu_id=0):
    """Run inference on all images in a dataset or over an index range of images
    in a dataset using a single GPU.
    """
    assert not cfg.MODEL.RPN_ONLY, 'Use rpn_generate to generate proposals from RPN-only models'
    dataset = JsonDataset(dataset_name, args.dataset_dir)
    timers = defaultdict(Timer)

    roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset(dataset, proposal_file, ind_range, args)
    num_images = len(roidb)
    image_ids = []
    if cfg.MODEL.TRANS_HEAD_ON:
        json_dir = os.path.join(output_dir, 'json_'+args.list_flag+'_trans')
    else:
        json_dir = os.path.join(output_dir, 'json_'+args.list_flag)

    json_dir += '_iou_' + str(args.iou_ignore_threshold)
    if not cfg.TEST.BBOX_AUG.ENABLED:
        json_dir += '_BBOX_AUG_single_scale'
    else:
        json_dir += '_BBOX_AUG_multiple_scale'

    if not cfg.TEST.CAR_CLS_AUG.ENABLED:
        json_dir += '_CAR_CLS_AUG_single_scale'
    else:
        json_dir += '_CAR_CLS_AUG_multiple_scale'

    if cfg.TEST.GEOMETRIC_TRANS:
        json_dir += '_GEOMETRIC_TRANS'

    if cfg.TEST.CAR_CLS_AUG.H_FLIP and cfg.TEST.CAR_CLS_AUG.SCALE_H_FLIP:
        json_dir += '_hflipped'

    roidb = roidb
    for i, entry in enumerate(roidb):
        image_ids.append(entry['image'])
    args.image_ids = image_ids

    all_boxes = [[[] for _ in range(num_images)] for _ in range(cfg.MODEL.NUM_CLASSES)]
    if ind_range is not None:
        if cfg.TEST.SOFT_NMS.ENABLED:
            det_name = 'detection_range_%s_%s_soft_nms' % tuple(ind_range)
        else:
            det_name = 'detection_range_(%d_%d)_nms_%.1f' % (ind_range[0], ind_range[1], cfg.TEST.NMS)
        if cfg.TEST.BBOX_AUG.ENABLED:
            det_name += '_multiple_scale'
        det_name += '.pkl'
    else:
        det_name = 'detections.pkl'
    det_file = os.path.join(output_dir, det_name)

    file_complete_flag = [not os.path.exists(os.path.join(json_dir, entry['image'].split('/')[-1][:-4] + '.json')) for entry in roidb]
    # If we don't have the complete json file, we will load the model and execute the following:
    if np.sum(file_complete_flag) or not os.path.exists(det_file):
        model = initialize_model_from_cfg(args, gpu_id=gpu_id)
        for i in tqdm(range(len(roidb))):
            entry = roidb[i]
            if cfg.TEST.PRECOMPUTED_PROPOSALS:
                # The roidb may contain ground-truth rois (for example, if the roidb
                # comes from the training or val split). We only want to evaluate
                # detection on the *non*-ground-truth rois. We select only the rois
                # that have the gt_classes field set to 0, which means there's no
                # ground truth.
                box_proposals = entry['boxes'][entry['gt_classes'] == 0]
                if len(box_proposals) == 0:
                    continue
            else:
                # Faster R-CNN type models generate proposals on-the-fly with an
                # in-network RPN; 1-stage models don't require proposals.
                box_proposals = None

            im = cv2.imread(entry['image'])
            ignored_mask_img = os.path.join(('/').join(entry['image'].split('/')[:-2]), 'ignore_mask', entry['image'].split('/')[-1])
            ignored_mask = cv2.imread(ignored_mask_img, cv2.IMREAD_GRAYSCALE)
            ignored_mask_binary = np.zeros(ignored_mask.shape)
            ignored_mask_binary[ignored_mask > 250] = 1
            if cfg.MODEL.NON_LOCAL_TEST and not cfg.TEST.BBOX_AUG.ENABLED:
                cls_boxes_i, cls_segms_i, _, car_cls_i, euler_angle_i, trans_pred_i, f_div_C = im_detect_all(model, im, box_proposals, timers, dataset)
            else:
                cls_boxes_i, cls_segms_i, _, car_cls_i, euler_angle_i, trans_pred_i = im_detect_all(model, im, box_proposals, timers, dataset)
            extend_results(i, all_boxes, cls_boxes_i)

            # We draw the grid overlap with an image here
            if False:
                f_div_C_plot = f_div_C.copy()
                grid_size = 32  # This is the res5 output space
                fig = plt.figure()
                ax1 = fig.add_subplot(1, 2, 1)
                ax2 = fig.add_subplot(1, 2, 2)
                ax1.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
                ax1.grid(which='minor')

                # We choose the point here:
                # x, y = int(1757/grid_size), int(1040/grid_size)   # val 164
                x, y = int(1830/grid_size), int(1855/grid_size)

                # draw a patch hre
                rect = patches.Rectangle((x*grid_size-grid_size, y*grid_size-grid_size), grid_size*3, grid_size*3,
                                         linewidth=1, edgecolor='m', facecolor='m')
                ax1.add_patch(rect)
                #att_point_map = f_div_C_plot[106*x+y, :]
                att_point_map = f_div_C_plot[106*y+x, :]
                att_point_map = np.reshape(att_point_map, (85, 106))
                ax2.imshow(att_point_map, cmap='jet')

                # we draw 20 arrows
                for i in range(10):
                    x_max, y_max = np.unravel_index(att_point_map.argmax(), att_point_map.shape)
                    v = att_point_map[x_max, y_max]
                    att_point_map[x_max, y_max] = 0
                    ax1.arrow(x*grid_size, y*grid_size, (y_max-x)*grid_size, (x_max-y)*grid_size,
                              fc="r", ec="r", head_width=(10-i)*grid_size/2, head_length=grid_size)

            if i % 10 == 0:  # Reduce log file size
                ave_total_time = np.sum([t.average_time for t in timers.values()])
                eta_seconds = ave_total_time * (num_images - i - 1)
                eta = str(datetime.timedelta(seconds=int(eta_seconds)))
                det_time = timers['im_detect_bbox'].average_time
                triple_head_time = timers['triple_head'].average_time
                misc_time = (
                    timers['misc_bbox'].average_time +
                    timers['misc_mask'].average_time
                )
                logger.info(
                    (
                        'im_detect: range [{:d}, {:d}] of {:d}: '
                        '{:d}/{:d} det-time: {:.3f}s + triple-head-time: {:.3f}s + misc_time: {:.3f}s (eta: {})'
                    ).format(
                        start_ind + 1, end_ind, total_num_images, start_ind + i + 1,
                        start_ind + num_images, det_time, triple_head_time, misc_time, eta
                    )
                )

            im_name = os.path.splitext(os.path.basename(entry['image']))[0]
            vis_utils.write_pose_to_json(
                im_name=im_name,
                output_dir=json_dir,
                boxes=cls_boxes_i,
                car_cls_prob=car_cls_i,
                euler_angle=euler_angle_i,
                trans_pred=trans_pred_i,
                segms=cls_segms_i,
                dataset=dataset.Car3D,
                thresh=cfg.TEST.SCORE_THRESH_FOR_TRUTH_DETECTION,
                ignored_mask_binary=ignored_mask_binary.astype('uint8'),
                iou_ignore_threshold=args.iou_ignore_threshold
            )

            if cfg.VIS:
                vis_utils.vis_one_image_eccv2018_car_3d(
                    im[:, :, ::-1],
                    '{:d}_{:s}'.format(i, im_name),
                    os.path.join(output_dir, 'vis_'+args.list_flag),
                    boxes=cls_boxes_i,
                    car_cls_prob=car_cls_i,
                    euler_angle=euler_angle_i,
                    trans_pred=trans_pred_i,
                    car_models=dataset.Car3D.car_models,
                    intrinsic=dataset.Car3D.get_intrinsic_mat(),
                    segms=cls_segms_i,
                    keypoints=None,
                    thresh=0.9,
                    box_alpha=0.8,
                    dataset=dataset.Car3D)

        save_object(dict(all_boxes=all_boxes), det_file)

    # The following evaluate the detection result from Faster-RCNN Head
    # If we have already computed the boxes
    if os.path.exists(det_file):
        obj = load_object(det_file)
        all_boxes = obj['all_boxes']

    # this is a hack
    if False:

        import glob
        det_files = sorted(glob.glob(args.output_dir+'/detection_range_*.pkl'))
        det_files = [det_files[4], det_files[1], det_files[2], det_files[3]]
        obj = load_object(det_files[0])
        all_boxes = obj['all_boxes']
        for df in det_files:
            obj = load_object(df)
            boxes = obj['all_boxes']
            for i in range(len(boxes)):
                all_boxes[i] = all_boxes[i] + boxes[i]
        save_object(dict(all_boxes=all_boxes), det_file)

    results = task_evaluation.evaluate_boxes(dataset, all_boxes, output_dir, args)

    # The following evaluate the mAP of car poses
    args.test_dir = json_dir
    args.gt_dir = args.dataset_dir + 'car_poses'
    args.res_file = os.path.join(output_dir, 'json_'+args.list_flag+'_res.txt')
    args.simType = None
    det_3d_metric = Detect3DEval(args)
    det_3d_metric.evaluate()
    det_3d_metric.accumulate()
    det_3d_metric.summarize()
예제 #3
0
def test_net(args,
             dataset_name,
             proposal_file,
             output_dir,
             ind_range=None,
             gpu_id=0,
             early_stop=False):
    """Run inference on all images in a dataset or over an index range of images
    in a dataset using a single GPU.
    """
    # print('test_net')
    roidb, dataset, start_ind, end_ind, total_num_images = get_roidb_and_dataset(
        dataset_name, proposal_file, ind_range)
    model = initialize_model_from_cfg(args, gpu_id=gpu_id)
    num_images = len(roidb)
    num_classes = cfg.MODEL.NUM_CLASSES
    all_boxes = {}

    timers = defaultdict(Timer)

    if 'train' in dataset_name:
        if ind_range is not None:
            det_name = 'discovery_range_%s_%s.pkl' % tuple(ind_range)
        else:
            det_name = 'discovery.pkl'
    else:
        if ind_range is not None:
            det_name = 'detection_range_%s_%s.pkl' % tuple(ind_range)
        else:
            det_name = 'detections.pkl'

    det_file = os.path.join(output_dir, det_name)
    if os.path.exists(det_file):
        print('the file', det_file,
              'exists. I am loading detections from it...')
        return load_object(det_file)['all_boxes']

    for i, entry in enumerate(roidb):
        if early_stop and i > 10: break

        box_proposals = entry['boxes']
        if len(box_proposals) == 0:
            continue

        im = cv2.imread(entry['image'])
        # print(entry['image'])
        cls_boxes_i = im_detect_all(model, im, box_proposals, timers)

        all_boxes[entry['image']] = cls_boxes_i

        if i % 10 == 0:  # Reduce log file size
            ave_total_time = np.sum([t.average_time for t in timers.values()])
            eta_seconds = ave_total_time * (num_images - i - 1)
            eta = str(datetime.timedelta(seconds=int(eta_seconds)))

            det_time = (timers['im_detect_bbox'].average_time)

            logger.info((
                'im_detect: range [{:d}, {:d}] of {:d}:{:d}/{:d} {:.3f}s (eta: {})'
            ).format(start_ind + 1, end_ind, total_num_images,
                     start_ind + i + 1, start_ind + num_images, det_time, eta))

    cfg_yaml = yaml.dump(cfg)

    save_object(dict(all_boxes=all_boxes, cfg=cfg_yaml), det_file)
    logger.info('Wrote detections to: {}'.format(os.path.abspath(det_file)))
    return all_boxes