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
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()
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