def dump_dict(record_dict, json_out): # dump result json dict with open(json_out, 'a+') as f: mmcv.dump(record_dict, f, file_format='json') f.write('\n')
def bbox2result_kitti(self, net_outputs, class_names, pklfile_prefix=None, submission_prefix=None): """Convert results to kitti format for evaluation and test submission. Args: net_outputs (List[np.ndarray]): list of array storing the bbox and score class_nanes (List[String]): A list of class names pklfile_prefix (str | None): The prefix of pkl file. submission_prefix (str | None): The prefix of submission file. Returns: List[dict]: A list of dict have the kitti 3d format """ assert len(net_outputs) == len(self.data_infos), \ 'invalid list length of network outputs' if submission_prefix is not None: mmcv.mkdir_or_exist(submission_prefix) det_annos = [] print('\nConverting prediction to KITTI format') for idx, pred_dicts in enumerate( mmcv.track_iter_progress(net_outputs)): annos = [] info = self.data_infos[idx] sample_idx = info['image']['image_idx'] image_shape = info['image']['image_shape'][:2] box_dict = self.convert_valid_bboxes(pred_dicts, info) if len(box_dict['bbox']) > 0: box_2d_preds = box_dict['bbox'] box_preds = box_dict['box3d_camera'] scores = box_dict['scores'] box_preds_lidar = box_dict['box3d_lidar'] label_preds = box_dict['label_preds'] anno = { 'name': [], 'truncated': [], 'occluded': [], 'alpha': [], 'bbox': [], 'dimensions': [], 'location': [], 'rotation_y': [], 'score': [] } for box, box_lidar, bbox, score, label in zip( box_preds, box_preds_lidar, box_2d_preds, scores, label_preds): bbox[2:] = np.minimum(bbox[2:], image_shape[::-1]) bbox[:2] = np.maximum(bbox[:2], [0, 0]) anno['name'].append(class_names[int(label)]) anno['truncated'].append(0.0) anno['occluded'].append(0) anno['alpha'].append( -np.arctan2(-box_lidar[1], box_lidar[0]) + box[6]) anno['bbox'].append(bbox) anno['dimensions'].append(box[3:6]) anno['location'].append(box[:3]) anno['rotation_y'].append(box[6]) anno['score'].append(score) anno = {k: np.stack(v) for k, v in anno.items()} annos.append(anno) if submission_prefix is not None: curr_file = f'{submission_prefix}/{sample_idx:07d}.txt' with open(curr_file, 'w') as f: bbox = anno['bbox'] loc = anno['location'] dims = anno['dimensions'] # lhw -> hwl for idx in range(len(bbox)): print('{} -1 -1 {:.4f} {:.4f} {:.4f} {:.4f} ' '{:.4f} {:.4f} {:.4f} ' '{:.4f} {:.4f} {:.4f} {:.4f} {:.4f} {:.4f}'. format(anno['name'][idx], anno['alpha'][idx], bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3], dims[idx][1], dims[idx][2], dims[idx][0], loc[idx][0], loc[idx][1], loc[idx][2], anno['rotation_y'][idx], anno['score'][idx]), file=f) else: annos.append({ 'name': np.array([]), 'truncated': np.array([]), 'occluded': np.array([]), 'alpha': np.array([]), 'bbox': np.zeros([0, 4]), 'dimensions': np.zeros([0, 3]), 'location': np.zeros([0, 3]), 'rotation_y': np.array([]), 'score': np.array([]), }) annos[-1]['sample_idx'] = np.array([sample_idx] * len(annos[-1]['score']), dtype=np.int64) det_annos += annos if pklfile_prefix is not None: if not pklfile_prefix.endswith(('.pkl', '.pickle')): out = f'{pklfile_prefix}.pkl' mmcv.dump(det_annos, out) print(f'Result is saved to {out}.') return det_annos
def main(): args = parse_args() cfg = mmcv.Config.fromfile(args.config) if args.options is not None: cfg.merge_from_dict(args.options) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None cfg.data.test.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader dataset = build_dataset(cfg.data.test) data_loader = build_dataloader(dataset, samples_per_gpu=cfg.data.samples_per_gpu, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False, round_up=False) # build the model and load checkpoint model = build_classifier(cfg.model) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader) else: model = MMDistributedDataParallel( model.cuda(), device_ids=[torch.cuda.current_device()], broadcast_buffers=False) outputs = multi_gpu_test(model, data_loader, args.tmpdir, args.gpu_collect) rank, _ = get_dist_info() if rank == 0: if args.metric != '': results = dataset.evaluate(outputs, args.metric) for topk, acc in results.items(): print(f'\n{topk} accuracy: {acc:.2f}') else: scores = np.vstack(outputs) pred_score = np.max(scores, axis=1) pred_label = np.argmax(scores, axis=1) if 'CLASSES' in checkpoint['meta']: CLASSES = checkpoint['meta']['CLASSES'] else: from mmcls.datasets import ImageNet warnings.simplefilter('once') warnings.warn('Class names are not saved in the checkpoint\'s ' 'meta data, use imagenet by default.') CLASSES = ImageNet.CLASSES pred_class = [CLASSES[lb] for lb in pred_label] results = { 'pred_score': pred_score, 'pred_label': pred_label, 'pred_class': pred_class } if not args.out: print('\nthe predicted result for the first element is ' f'pred_score = {pred_score[0]:.2f}, ' f'pred_label = {pred_label[0]} ' f'and pred_class = {pred_class[0]}. ' 'Specify --out to save all results to files.') if args.out and rank == 0: print(f'\nwriting results to {args.out}') mmcv.dump(results, args.out)
def create_waymotrainval_info_file(data_path, pkl_prefix='waymo', save_path=None, relative_path=True, max_sweeps=5): """Create info file of waymo dataset. Given the raw data, generate its related info file in pkl format. Args: data_path (str): Path of the data root. pkl_prefix (str): Prefix of the info file to be generated. save_path (str | None): Path to save the info file. relative_path (bool): Whether to use relative path. max_sweeps (int): Max sweeps before the detection frame to be used. """ imageset_folder = Path(data_path) / 'ImageSets' train_img_ids = _read_imageset_file(str(imageset_folder / 'train.txt')) val_img_ids = _read_imageset_file(str(imageset_folder / 'val.txt')) trainval_img_ids = _read_imageset_file(str(imageset_folder / 'trainval.txt')) #test_img_ids = _read_imageset_file(str(imageset_folder / 'test.txt')) print('Generate info. this may take several minutes.') if save_path is None: save_path = Path(data_path) else: save_path = Path(save_path) waymo_infos_train = get_waymo_image_info( data_path, training=True, velodyne=True, calib=True, pose=True, image_ids=train_img_ids, relative_path=relative_path, max_sweeps=max_sweeps) _calculate_num_points_in_gt( data_path, waymo_infos_train, relative_path, num_features=4,#6 remove_outside=False) filename = save_path / f'{pkl_prefix}_infos_train.pkl' print(f'Waymo info train file is saved to {filename}') mmcv.dump(waymo_infos_train, filename) waymo_infos_val = get_waymo_image_info( data_path, training=True, velodyne=True, calib=True, pose=True, image_ids=val_img_ids, relative_path=relative_path, max_sweeps=max_sweeps) _calculate_num_points_in_gt( data_path, waymo_infos_val, relative_path, num_features=4,#6 remove_outside=False) filename = save_path / f'{pkl_prefix}_infos_val.pkl' print(f'Waymo info val file is saved to {filename}') mmcv.dump(waymo_infos_val, filename) waymo_infos_trainval = get_waymo_image_info( data_path, training=True, velodyne=True, calib=True, pose=True, image_ids=trainval_img_ids, relative_path=relative_path, max_sweeps=max_sweeps) _calculate_num_points_in_gt( data_path, waymo_infos_trainval, relative_path, num_features=4, remove_outside=False) filename = save_path / f'{pkl_prefix}_infos_trainval.pkl' print(f'Waymo info trainval file is saved to {filename}') mmcv.dump(waymo_infos_trainval, filename)
def create_indoor_info_file(data_path, pkl_prefix='sunrgbd', save_path=None, use_v1=False, workers=4): """Create indoor information file. Get information of the raw data and save it to the pkl file. Args: data_path (str): Path of the data. pkl_prefix (str): Prefix of the pkl to be saved. Default: 'sunrgbd'. save_path (str): Path of the pkl to be saved. Default: None. use_v1 (bool): Whether to use v1. Default: False. workers (int): Number of threads to be used. Default: 4. """ assert os.path.exists(data_path) assert pkl_prefix in ['sunrgbd', 'scannet', 's3dis'], \ f'unsupported indoor dataset {pkl_prefix}' save_path = data_path if save_path is None else save_path assert os.path.exists(save_path) # generate infos for both detection and segmentation task if pkl_prefix in ['sunrgbd', 'scannet']: train_filename = os.path.join(save_path, f'{pkl_prefix}_infos_train.pkl') val_filename = os.path.join(save_path, f'{pkl_prefix}_infos_val.pkl') if pkl_prefix == 'sunrgbd': # SUN RGB-D has a train-val split train_dataset = SUNRGBDData(root_path=data_path, split='train', use_v1=use_v1) val_dataset = SUNRGBDData(root_path=data_path, split='val', use_v1=use_v1) else: # ScanNet has a train-val-test split train_dataset = ScanNetData(root_path=data_path, split='train') val_dataset = ScanNetData(root_path=data_path, split='val') test_dataset = ScanNetData(root_path=data_path, split='test') test_filename = os.path.join(save_path, f'{pkl_prefix}_infos_test.pkl') infos_train = train_dataset.get_infos(num_workers=workers, has_label=True) mmcv.dump(infos_train, train_filename, 'pkl') print(f'{pkl_prefix} info train file is saved to {train_filename}') infos_val = val_dataset.get_infos(num_workers=workers, has_label=True) mmcv.dump(infos_val, val_filename, 'pkl') print(f'{pkl_prefix} info val file is saved to {val_filename}') if pkl_prefix == 'scannet': infos_test = test_dataset.get_infos(num_workers=workers, has_label=False) mmcv.dump(infos_test, test_filename, 'pkl') print(f'{pkl_prefix} info test file is saved to {test_filename}') # generate infos for the semantic segmentation task # e.g. re-sampled scene indexes and label weights # scene indexes are used to re-sample rooms with different number of points # label weights are used to balance classes with different number of points if pkl_prefix == 'scannet': # label weight computation function is adopted from # https://github.com/charlesq34/pointnet2/blob/master/scannet/scannet_dataset.py#L24 train_dataset = ScanNetSegData( data_root=data_path, ann_file=train_filename, split='train', num_points=8192, label_weight_func=lambda x: 1.0 / np.log(1.2 + x)) # TODO: do we need to generate on val set? val_dataset = ScanNetSegData( data_root=data_path, ann_file=val_filename, split='val', num_points=8192, label_weight_func=lambda x: 1.0 / np.log(1.2 + x)) # no need to generate for test set train_dataset.get_seg_infos() val_dataset.get_seg_infos() else: # S3DIS doesn't have a fixed train-val split # it has 6 areas instead, so we generate info file for each of them # in training, we will use dataset to wrap different areas splits = [f'Area_{i}' for i in [1, 2, 3, 4, 5, 6]] for split in splits: dataset = S3DISData(root_path=data_path, split=split) info = dataset.get_infos(num_workers=workers, has_label=True) filename = os.path.join(save_path, f'{pkl_prefix}_infos_{split}.pkl') mmcv.dump(info, filename, 'pkl') print(f'{pkl_prefix} info {split} file is saved to {filename}') seg_dataset = S3DISSegData( data_root=data_path, ann_file=filename, split=split, num_points=4096, label_weight_func=lambda x: 1.0 / np.log(1.2 + x)) seg_dataset.get_seg_infos()
def main(): args = parse_args() assert args.out or args.show, \ ('Please specify at least one operation (save or show the results) ' 'with the argument "--out" or "--show"') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') cfg = mmcv.Config.fromfile(args.config) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None cfg.data.test.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader # TODO: support multiple images per gpu (only minor changes are needed) dataset = build_dataset(cfg.data.test) data_loader = build_dataloader( dataset, imgs_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) # build the model and load checkpoint model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') # old versions did not save class info in checkpoints, this walkaround is # for backward compatibility if 'CLASSES' in checkpoint['meta']: model.CLASSES = checkpoint['meta']['CLASSES'] else: model.CLASSES = dataset.CLASSES if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader, args.show) else: model = MMDistributedDataParallel(model.cuda()) outputs = multi_gpu_test(model, data_loader, args.tmpdir) rank, _ = get_dist_info() if rank == 0: if 'seg' in outputs[0]: # print("123") # preds = numpy. preds = [result['seg']['pred'] for result in outputs] gt_segs = [np.squeeze(result['seg']['gt_seg'], axis=1) for result in outputs] seg_scores = scores(gt_segs, preds, n_class=182) print(seg_scores) mmcv.dump(seg_scores, args.out) if 'cap' in outputs[0]: hypotheses = [result['cap']['hypothesis'] for result in outputs] references = [result['cap']['reference'] for result in outputs] print(hypotheses[0]) print(references[0]) print(len(hypotheses)) print(len(references)) bleu4 = corpus_bleu(references, hypotheses) print("bleu4: ", bleu4) mmcv.dump({'bleu4': bleu4}, args.out)
def main(): args = parse_args() cfg = mmcv.Config.fromfile(args.config) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None cfg.data.test.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader # TODO: support multiple images per gpu (only minor changes are needed) dataset = build_dataset(cfg.data.test) data_loader = build_dataloader( dataset, imgs_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) if args.out is None: dataset_name = dataset.name if hasattr(dataset, 'name') else 'val' if hasattr(cfg.data.test, 'task'): dataset_name = dataset_name + '_' + cfg.data.test.task model_name = os.path.basename(args.checkpoint).split('.')[0] model_dir = os.path.dirname(args.checkpoint) args.out = os.path.join(model_dir, 'raw_results', dataset_name + '_' + model_name + '.pkl') elif not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') mmcv.mkdir_or_exist(os.path.dirname(args.out)) rank, _ = get_dist_info() eval_types = args.eval if not os.path.isfile(args.out): # build the model and load checkpoint model = build_detector( cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) checkpoint = load_checkpoint( model, args.checkpoint, map_location='cpu') # old versions did not save class info in checkpoints, this walkaround is # for backward compatibility if 'CLASSES' in checkpoint['meta']: model.CLASSES = checkpoint['meta']['CLASSES'] else: model.CLASSES = dataset.CLASSES if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader, args.show) else: model = MMDistributedDataParallel(model.cuda()) outputs = multi_gpu_test(model, data_loader, args.tmpdir) if rank == 0: if hasattr(dataset, 'raw_annotations'): filenames = [ dataset.raw_annotations[dataset.ids[i]]['filename'] for i in range(len(dataset)) ] else: filenames = [ img_info['filename'] for img_info in dataset.img_infos ] print('\nwriting results to {}'.format(args.out)) results = { 'file_names': filenames, 'outputs': outputs, } mmcv.dump(results, args.out, protocol=2) elif rank == 0: results = mmcv.load(args.out, encoding='latin1') outputs = results['outputs'] if eval_types and rank == 0: print('Starting evaluate {}'.format(' and '.join(eval_types))) if not hasattr(dataset, 'coco'): if hasattr(dataset, 'raw_annotations'): gt_bboxes = [ dataset.raw_annotations[dataset.ids[i]]['ann']['bboxes'] for i in range(len(dataset)) ] gt_labels = [ dataset.raw_annotations[dataset.ids[i]]['ann']['classes'] for i in range(len(dataset)) ] if cfg.data.test.with_ignore: gt_ignores = [l <= 0 for l in gt_labels] else: gt_ignores = [l == 0 for l in gt_labels] gt_labels = [np.abs(l) for l in gt_labels] if 'corners' in eval_types: gt_corners = [ dataset.raw_annotations[dataset.ids[i]]['ann'] ['corners'] for i in range(len(dataset)) ] gt_poses = [ dataset.raw_annotations[dataset.ids[i]]['ann']['poses'] for i in range(len(dataset)) ] eval_corners( outputs, gt_corners, gt_poses, gt_labels, gt_ignores, gt_bboxes=gt_bboxes, display=True) det_bboxes = corners2bboxes(outputs, len(dataset.CLASSES) - 1) eval_map( det_bboxes, gt_bboxes, gt_labels, gt_ignore=gt_ignores) else: eval_map( outputs, gt_bboxes, gt_labels, gt_ignore=gt_ignores) else: gt_bboxes = [ img_info['ann']['bboxes'] for img_info in dataset.img_infos ] gt_labels = [ img_info['ann']['labels'] for img_info in dataset.img_infos ] if len(outputs[0]) == 5: outputs = corners2bboxes(outputs, len(dataset.classes) - 1) eval_map(outputs, gt_bboxes, gt_labels, iou_thr=0.4) else: if eval_types == ['proposal_fast']: result_file = args.out coco_eval(result_file, eval_types, dataset.coco, CLASSES=dataset.CLASSES) else: if not isinstance(outputs[0], dict): result_files = results2json(dataset, outputs, args.out) coco_eval(result_files, eval_types, dataset.coco, CLASSES=dataset.CLASSES, show=True) else: for name in outputs[0]: print('\nEvaluating {}'.format(name)) outputs_ = [out[name] for out in outputs] result_file = args.out + '.{}'.format(name) result_files = results2json(dataset, outputs_, result_file) coco_eval(result_files, eval_types, dataset.coco, CLASSES=dataset.CLASSES, show=True)
def main(): args = parse_args() checkpoint_list = os.listdir(args.checkpoint_dir) print(checkpoint_list) cfg = mmcv.Config.fromfile(args.config) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) rank, _ = get_dist_info() # set random seeds if args.seed is not None: if rank == 0: print('set random seed to', args.seed) set_random_seed(args.seed, deterministic=args.deterministic) # build the dataloader # TODO: support multiple images per gpu (only minor changes are needed) dataset = build_dataset(cfg.data.test) data_loader = build_dataloader( dataset, samples_per_gpu=1, workers_per_gpu=cfg.data.get('val_workers_per_gpu', cfg.data.workers_per_gpu), dist=distributed, shuffle=False) # build the model and load checkpoint model = build_model(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) args.save_image = args.save_path is not None if not distributed: for checkpoint in checkpoint_list: if '.pth' in checkpoint: print(checkpoint) _ = load_checkpoint(model, os.path.join(args.checkpoint_dir, checkpoint), map_location='cpu') model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test( model, data_loader, save_path=args.save_path, save_image=args.save_image) if rank == 0: # print metrics stats = dataset.evaluate(outputs) write_file = open(os.path.join(args.checkpoint_dir, 'eval_result_new.txt'), 'a') for stat in stats: print('{}: Eval-{}: {}'.format(checkpoint, stat, stats[stat])) write_file.write('{}: Eval-{}: {} '.format(checkpoint, stat, stats[stat])) write_file.write('\n') write_file.close() # save result pickle if args.out: print('writing results to {}'.format(args.out)) mmcv.dump(outputs, args.out) else: find_unused_parameters = cfg.get('find_unused_parameters', False) model = DistributedDataParallelWrapper( model, device_ids=[torch.cuda.current_device()], broadcast_buffers=False, find_unused_parameters=find_unused_parameters) device_id = torch.cuda.current_device() for checkpoint in checkpoint_list: if '.pth' in checkpoint: print(checkpoint) _ = load_checkpoint( model, os.path.join(args.checkpoint_dir, checkpoint), map_location=lambda storage, loc: storage.cuda(device_id)) outputs = multi_gpu_test( model, data_loader, args.tmpdir, args.gpu_collect, save_path=args.save_path, save_image=args.save_image) if rank == 0: # print metrics stats = dataset.evaluate(outputs) write_file = open(os.path.join(args.checkpoint_dir, 'eval_result_new.txt'), 'a') for stat in stats: print('{}: Eval-{}: {}'.format(checkpoint, stat, stats[stat])) write_file.write('{}: Eval-{}: {} '.format(checkpoint, stat, stats[stat])) write_file.write('\n') write_file.close() # save result pickle if args.out: print('writing results to {}'.format(args.out)) mmcv.dump(outputs, args.out)
def _format_bbox(self, results, jsonfile_prefix=None): """Convert the results to the standard format. Args: results (list[dict]): Testing results of the dataset. jsonfile_prefix (str): The prefix of the output jsonfile. You can specify the output directory/filename by modifying the jsonfile_prefix. Default: None. Returns: str: Path of the output json file. """ nusc_annos = {} mapped_class_names = self.CLASSES print('Start to convert detection format...') CAM_NUM = 6 for sample_id, det in enumerate(mmcv.track_iter_progress(results)): if sample_id % CAM_NUM == 0: boxes_per_frame = [] attrs_per_frame = [] # need to merge results from images of the same sample annos = [] boxes, attrs = output_to_nusc_box(det) sample_token = self.data_infos[sample_id]['token'] boxes, attrs = cam_nusc_box_to_global(self.data_infos[sample_id], boxes, attrs, mapped_class_names, self.eval_detection_configs, self.eval_version) boxes_per_frame.extend(boxes) attrs_per_frame.extend(attrs) # Remove redundant predictions caused by overlap of images if (sample_id + 1) % CAM_NUM != 0: continue boxes = global_nusc_box_to_cam( self.data_infos[sample_id + 1 - CAM_NUM], boxes_per_frame, mapped_class_names, self.eval_detection_configs, self.eval_version) cam_boxes3d, scores, labels = nusc_box_to_cam_box3d(boxes) # box nms 3d over 6 images in a frame # TODO: move this global setting into config nms_cfg = dict(use_rotate_nms=True, nms_across_levels=False, nms_pre=4096, nms_thr=0.05, score_thr=0.01, min_bbox_size=0, max_per_frame=500) from mmcv import Config nms_cfg = Config(nms_cfg) cam_boxes3d_for_nms = xywhr2xyxyr(cam_boxes3d.bev) boxes3d = cam_boxes3d.tensor # generate attr scores from attr labels attrs = labels.new_tensor([attr for attr in attrs_per_frame]) boxes3d, scores, labels, attrs = box3d_multiclass_nms( boxes3d, cam_boxes3d_for_nms, scores, nms_cfg.score_thr, nms_cfg.max_per_frame, nms_cfg, mlvl_attr_scores=attrs) cam_boxes3d = CameraInstance3DBoxes(boxes3d, box_dim=9) det = bbox3d2result(cam_boxes3d, scores, labels, attrs) boxes, attrs = output_to_nusc_box(det) boxes, attrs = cam_nusc_box_to_global( self.data_infos[sample_id + 1 - CAM_NUM], boxes, attrs, mapped_class_names, self.eval_detection_configs, self.eval_version) for i, box in enumerate(boxes): name = mapped_class_names[box.label] attr = self.get_attr_name(attrs[i], name) nusc_anno = dict(sample_token=sample_token, translation=box.center.tolist(), size=box.wlh.tolist(), rotation=box.orientation.elements.tolist(), velocity=box.velocity[:2].tolist(), detection_name=name, detection_score=box.score, attribute_name=attr) annos.append(nusc_anno) # other views results of the same frame should be concatenated if sample_token in nusc_annos: nusc_annos[sample_token].extend(annos) else: nusc_annos[sample_token] = annos nusc_submissions = { 'meta': self.modality, 'results': nusc_annos, } mmcv.mkdir_or_exist(jsonfile_prefix) res_path = osp.join(jsonfile_prefix, 'results_nusc.json') print('Results writes to', res_path) mmcv.dump(nusc_submissions, res_path) return res_path
def main(): args = parse_args() assert args.out or args.eval or args.format_only or args.show \ or args.show_dir, \ ('Please specify at least one operation (save/eval/format/show the ' 'results / save the results) with the argument "--out", "--eval"' ', "--format-only", "--show" or "--show-dir"') if args.eval and args.format_only: raise ValueError('--eval and --format_only cannot be both specified') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') cfg = Config.fromfile(args.config) if args.cfg_options is not None: cfg.merge_from_dict(args.cfg_options) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None necks = cfg.model.get('neck') if necks: necks = necks if isinstance(necks, list) else [necks] for neck in necks: if neck.get('rfp_backbone'): if neck.rfp_backbone.get('pretrained'): neck.rfp_backbone.pretrained = None cfg.data.test.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader # TODO: support multiple images per gpu (only minor changes are needed) dataset = build_dataset(cfg.data.test) data_loader = build_dataloader( dataset, samples_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) # build the model and load checkpoint model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') # perform model surgery classes_rearrange = cfg.get('classes_rearrange', False) if classes_rearrange: model = rearrange_classes(model, cfg.classes, cfg.dataset_type) if args.fuse_conv_bn: model = fuse_module(model) # old versions did not save class info in checkpoints, this walkaround is # for backward compatibility if 'CLASSES' in checkpoint['meta']: model.CLASSES = checkpoint['meta']['CLASSES'] else: model.CLASSES = dataset.CLASSES if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader, args.show, args.show_dir, args.show_score_thr) else: model = MMDistributedDataParallel( model.cuda(), device_ids=[torch.cuda.current_device()], broadcast_buffers=False) outputs = multi_gpu_test(model, data_loader, args.tmpdir, args.gpu_collect) rank, _ = get_dist_info() if rank == 0: if args.out: print(f'\nwriting results to {args.out}') mmcv.dump(outputs, args.out) kwargs = {} if args.options is None else args.options if args.format_only: dataset.format_results(outputs, **kwargs) if args.eval: dataset.evaluate(outputs, args.eval, **kwargs)
def _create_dummy_icdar_json(json_name): image_1 = { 'id': 0, 'width': 640, 'height': 640, 'file_name': 'fake_name.jpg', } image_2 = { 'id': 1, 'width': 640, 'height': 640, 'file_name': 'fake_name1.jpg', } annotation_1 = { 'id': 1, 'image_id': 0, 'category_id': 0, 'area': 400, 'bbox': [50, 60, 20, 20], 'iscrowd': 0, 'segmentation': [[50, 60, 70, 60, 70, 80, 50, 80]] } annotation_2 = { 'id': 2, 'image_id': 0, 'category_id': 0, 'area': 900, 'bbox': [100, 120, 30, 30], 'iscrowd': 0, 'segmentation': [[100, 120, 130, 120, 120, 150, 100, 150]] } annotation_3 = { 'id': 3, 'image_id': 0, 'category_id': 0, 'area': 1600, 'bbox': [150, 160, 40, 40], 'iscrowd': 1, 'segmentation': [[150, 160, 190, 160, 190, 200, 150, 200]] } annotation_4 = { 'id': 4, 'image_id': 0, 'category_id': 0, 'area': 10000, 'bbox': [250, 260, 100, 100], 'iscrowd': 1, 'segmentation': [[250, 260, 350, 260, 350, 360, 250, 360]] } annotation_5 = { 'id': 5, 'image_id': 1, 'category_id': 0, 'area': 10000, 'bbox': [250, 260, 100, 100], 'iscrowd': 1, 'segmentation': [[250, 260, 350, 260, 350, 360, 250, 360]] } categories = [{ 'id': 0, 'name': 'text', 'supercategory': 'text', }] fake_json = { 'images': [image_1, image_2], 'annotations': [annotation_1, annotation_2, annotation_3, annotation_4, annotation_5], 'categories': categories } mmcv.dump(fake_json, json_name)
def main(): args = parse_args() if not osp.isdir(args.output): os.makedirs(args.output) sets = ['train', 'test'] if args.split_train: sets += ['half-train', 'half-val'] vid_id, img_id, ann_id = 1, 1, 1 for subset in sets: ins_id = 0 print(f'Converting {subset} set to COCO format') if 'half' in subset: in_folder = osp.join(args.input, 'train') else: in_folder = osp.join(args.input, subset) out_file = osp.join(args.output, f'{subset}_cocoformat.json') outputs = defaultdict(list) outputs['categories'] = [dict(id=1, name='pedestrian')] if args.convert_det: det_file = osp.join(args.output, f'{subset}_detections.pkl') detections = dict(det_bboxes=dict()) video_names = os.listdir(in_folder) for video_name in tqdm(video_names): # basic params parse_gt = 'test' not in subset ins_maps = dict() # load video infos video_folder = osp.join(in_folder, video_name) infos = mmcv.list_from_file(f'{video_folder}/seqinfo.ini') # video-level infos assert video_name == infos[1].strip().split('=')[1] img_folder = infos[2].strip().split('=')[1] img_names = os.listdir(f'{video_folder}/{img_folder}') img_names = sorted(img_names) fps = int(infos[3].strip().split('=')[1]) num_imgs = int(infos[4].strip().split('=')[1]) assert num_imgs == len(img_names) width = int(infos[5].strip().split('=')[1]) height = int(infos[6].strip().split('=')[1]) video = dict(id=vid_id, name=video_name, fps=fps, width=width, height=height) # parse annotations if parse_gt: gts = mmcv.list_from_file(f'{video_folder}/gt/gt.txt') if 'MOT15' in video_folder: img2gts = parse_gts(gts, True) else: img2gts = parse_gts(gts, False) if args.convert_det: dets = mmcv.list_from_file(f'{video_folder}/det/det.txt') img2dets = parse_dets(dets) # make half sets if 'half' in subset: split_frame = num_imgs // 2 + 1 if 'train' in subset: img_names = img_names[:split_frame] elif 'val' in subset: img_names = img_names[split_frame:] else: raise ValueError( 'subset must be named with `train` or `val`') mot_frame_ids = [str(int(_.split('.')[0])) for _ in img_names] with open(f'{video_folder}/gt/gt_{subset}.txt', 'wt') as f: for gt in gts: if gt.split(',')[0] in mot_frame_ids: f.writelines(f'{gt}\n') # image and box level infos for frame_id, name in enumerate(img_names): img_name = osp.join(video_name, img_folder, name) mot_frame_id = int(name.split('.')[0]) image = dict(id=img_id, video_id=vid_id, file_name=img_name, height=height, width=width, frame_id=frame_id, mot_frame_id=mot_frame_id) if parse_gt: gts = img2gts[mot_frame_id] for gt in gts: gt.update(id=ann_id, image_id=img_id) mot_ins_id = gt['mot_instance_id'] if mot_ins_id in ins_maps: gt['instance_id'] = ins_maps[mot_ins_id] else: gt['instance_id'] = ins_id ins_maps[mot_ins_id] = ins_id ins_id += 1 outputs['annotations'].append(gt) ann_id += 1 if args.convert_det: dets = np.array(img2dets[mot_frame_id]) if dets.ndim == 1: assert len(dets) == 0 dets = np.zeros((0, 5)) detections['det_bboxes'][img_name] = [dets] outputs['images'].append(image) img_id += 1 outputs['videos'].append(video) vid_id += 1 outputs['num_instances'] = ins_id print(f'{subset} has {ins_id} instances.') mmcv.dump(outputs, out_file) if args.convert_det: mmcv.dump(detections, det_file) print(f'Done! Saved as {out_file} and {det_file}') else: print(f'Done! Saved as {out_file}')
def main(): args = parse_args() assert args.out or args.show or args.json_out, \ ('Please specify at least one operation (save or show the results) ' 'with the argument "--out" or "--show" or "--json_out"') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') if args.json_out is not None and args.json_out.endswith('.json'): args.json_out = args.json_out[:-5] cfg = mmcv.Config.fromfile(args.config) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None # cfg.model.rpn_pretrained = None # cfg.model.rcnn_pretrained = None cfg.data.test.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader # TODO: support multiple images per gpu (only minor changes are needed) dataset = build_dataset(cfg.data.test) data_loader = build_dataloader(dataset, imgs_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) # build the model and load checkpoint model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') # old versions did not save class info in checkpoints, this walkaround is # for backward compatibility if 'CLASSES' in checkpoint['meta']: model.CLASSES = checkpoint['meta']['CLASSES'] else: model.CLASSES = dataset.CLASSES if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader, args.show, cfg) else: model = MMDistributedDataParallel(model.cuda()) outputs = multi_gpu_test(model, data_loader, args.tmpdir) rank, _ = get_dist_info() if args.out and rank == 0: print('\nwriting results to {}'.format(args.out)) mmcv.dump(outputs, args.out) eval_types = args.eval data_name = args.data if data_name == 'coco': if eval_types: print('Starting evaluate {}'.format(' and '.join(eval_types))) if eval_types == ['proposal_fast']: result_file = args.out coco_eval(result_file, eval_types, dataset.coco) else: if not isinstance(outputs[0], dict): result_files = results2json(dataset, outputs, args.out) coco_eval(result_files, eval_types, dataset.coco) else: for name in outputs[0]: print('\nEvaluating {}'.format(name)) outputs_ = [out[name] for out in outputs] result_file = args.out + '.{}'.format(name) result_files = results2json( dataset, outputs_, result_file) coco_eval(result_files, eval_types, dataset.coco) elif data_name in ['dota', 'hrsc2016']: eval_kwargs = cfg.get('evaluation', {}).copy() work_dir = osp.dirname(args.out) dataset.evaluate(outputs, work_dir, **eval_kwargs) elif data_name in ['dsv2']: from mmdet.core import outputs_rotated_box_to_poly_np # for page in outputs: # for cla in page: # for detec in cla: # if min(detec[:4]) < 0: # detec[:4][detec[:4] < 0] = 0 #TODO: fix ugly hack to make the labels match import numpy as np for page in outputs: page.insert(0, np.array([])) outputs = outputs_rotated_box_to_poly_np(outputs) work_dir = osp.dirname(args.out) dataset.evaluate(outputs, work_dir=work_dir) # print("asdfsdf") # for page in outputs: # for cla in page: # for detec in cla: # if min(detec[:4]) < 0: # print(detec) # Save predictions in the COCO json format if args.json_out and rank == 0: if not isinstance(outputs[0], dict): results2json(dataset, outputs, args.json_out) else: for name in outputs[0]: outputs_ = [out[name] for out in outputs] result_file = args.json_out + '.{}'.format(name) results2json(dataset, outputs_, result_file)
if segm_only: mask = masks[ii][0]; score = masks[ii][1] else: x1, y1, x2, y2, score = bboxes[ii] # x = (x1 + x2) / 2; y = (y1 + y2) / 2 # w = x2 - x1 + 1; h = y2 - y1 + 1 mask = masks[ii] res = { 'image_id': anno['id'], 'category_id': cid + 1, 'segmentation': {'size': mask['size'], 'counts': mask['counts'].decode('utf-8')}, 'score': float(score), } anno_list.append(res) img_list = [] for img_info in val_anno['images']: res = { 'image_id': img_info['id'], 'width': img_info['width'], 'height': img_info['height'], 'file_name': img_info['file_name'] } img_list.append(res) submit = {} submit['images'] = img_list submit['annotations'] = anno_list mmcv.dump(submit, 'segmentation_results.json')
for event_id, event_anno in v.items(): timestamps = event_anno['timestamps'][0] start_time, end_time = timestamps event_name = k + '_' + event_id output_filename = event_name + '.mp4' command = [ 'ffmpeg', '-i', '"%s"' % video_path, '-ss', str(start_time), '-t', str(end_time - start_time), '-c:v', 'libx264', '-c:a', 'copy', '-threads', '8', '-loglevel', 'panic', '"%s"' % osp.join(event_root, output_filename) ] command = ' '.join(command) try: subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: print(f'Trimming of the Event {event_name} of Video {k} Failed', flush=True) segments = event_anno['segments'] if segments is not None: event_annotation[event_name] = segments mmcv.dump(event_annotation, event_anno_file)
def __call__(self): """ Load light-weight instance annotations of all images into a list of dicts in Detectron2 format. Do not load heavy data into memory in this file, since we will load the annotations of all images into memory. """ # cache the dataset_dicts to avoid loading masks from files hashed_file_name = hashlib.md5( ("".join([str(fn) for fn in self.objs]) + "dataset_dicts_{}_{}_{}_{}_{}".format(self.name, self.dataset_root, self.with_masks, self.with_depth, osp.abspath(__file__))).encode("utf-8")).hexdigest() cache_path = osp.join(self.dataset_root, "dataset_dicts_{}_{}.pkl".format(self.name, hashed_file_name)) if osp.exists(cache_path) and self.use_cache: logger.info("load cached dataset dicts from {}".format(cache_path)) return mmcv.load(cache_path) t_start = time.perf_counter() logger.info("loading dataset dicts: {}".format(self.name)) self.num_instances_without_valid_segmentation = 0 self.num_instances_without_valid_box = 0 dataset_dicts = [] ####################################################### im_id_global = 0 for scene_id in self.scene_ids: scene_root = osp.join(self.dataset_root, f"{scene_id:06d}") cam_dict = mmcv.load(osp.join(scene_root, "scene_camera.json")) gt_dict = mmcv.load(osp.join(scene_root, "scene_gt.json")) gt_info_dict = mmcv.load(osp.join(scene_root, "scene_gt_info.json")) for str_im_id in tqdm(gt_dict, postfix=f"{scene_id}"): im_id = int(str_im_id) rgb_path = osp.join(scene_root, "rgb/{:06d}.png").format(im_id) assert osp.exists(rgb_path), rgb_path depth_path = osp.join(scene_root, "depth/{:06d}.png".format(im_id)) scene_id = int(rgb_path.split('/')[-3]) cam = np.array(cam_dict[str_im_id]['cam_K'], dtype=np.float32).reshape(3, 3) depth_factor = 1000. / cam_dict[str_im_id]['depth_scale'] record = { "dataset_name": self.name, 'file_name': osp.relpath(rgb_path, PROJ_ROOT), 'depth_file': osp.relpath(depth_path, PROJ_ROOT), "depth_factor": depth_factor, 'height': self.height, 'width': self.width, 'image_id': im_id_global, # unique image_id in the dataset, for coco evaluation "scene_im_id": "{}/{}".format(scene_id, im_id), # for evaluation "cam": cam, "img_type": 'real' } im_id_global += 1 insts = [] for anno_i, anno in enumerate(gt_dict[str_im_id]): obj_id = anno['obj_id'] if ref.hb.id2obj[obj_id] not in self.select_objs: continue cur_label = self.cat2label[obj_id] # 0-based label R = np.array(anno['cam_R_m2c'], dtype='float32').reshape(3, 3) t = np.array(anno['cam_t_m2c'], dtype='float32') / 1000.0 pose = np.hstack([R, t.reshape(3, 1)]) quat = mat2quat(R).astype('float32') allo_q = mat2quat(egocentric_to_allocentric(pose)[:3, :3]).astype('float32') proj = (record["cam"] @ t.T).T proj = proj[:2] / proj[2] bbox_visib = gt_info_dict[str_im_id][anno_i]['bbox_visib'] bbox_obj = gt_info_dict[str_im_id][anno_i]['bbox_obj'] x1, y1, w, h = bbox_visib if self.filter_invalid: if h <= 1 or w <= 1: self.num_instances_without_valid_box += 1 continue mask_file = osp.join(scene_root, "mask/{:06d}_{:06d}.png".format(im_id, anno_i)) mask_visib_file = osp.join(scene_root, "mask_visib/{:06d}_{:06d}.png".format(im_id, anno_i)) assert osp.exists(mask_file), mask_file assert osp.exists(mask_visib_file), mask_visib_file # load mask visib TODO: load both mask_visib and mask_full mask_single = mmcv.imread(mask_visib_file, "unchanged") area = mask_single.sum() if area < 3: # filter out too small or nearly invisible instances self.num_instances_without_valid_segmentation += 1 continue mask_rle = binary_mask_to_rle(mask_single, compressed=True) inst = { 'category_id': cur_label, # 0-based label 'bbox': bbox_visib, # TODO: load both bbox_obj and bbox_visib 'bbox_mode': BoxMode.XYWH_ABS, 'pose': pose, "quat": quat, "trans": t, "allo_quat": allo_q, "centroid_2d": proj, # absolute (cx, cy) "segmentation": mask_rle, "mask_full_file": mask_file, # TODO: load as mask_full, rle } insts.append(inst) if len(insts) == 0: # filter im without anno continue record['annotations'] = insts dataset_dicts.append(record) if self.num_instances_without_valid_segmentation > 0: logger.warning("Filtered out {} instances without valid segmentation. " "There might be issues in your dataset generation process.".format( self.num_instances_without_valid_segmentation)) if self.num_instances_without_valid_box > 0: logger.warning("Filtered out {} instances without valid box. " "There might be issues in your dataset generation process.".format( self.num_instances_without_valid_box)) ########################################################################## if self.num_to_load > 0: self.num_to_load = min(int(self.num_to_load), len(dataset_dicts)) dataset_dicts = dataset_dicts[:self.num_to_load] logger.info("loaded dataset dicts, num_images: {}, using {}s".format( len(dataset_dicts), time.perf_counter() - t_start)) mmcv.dump(dataset_dicts, cache_path, protocol=4) logger.info("Dumped dataset_dicts to {}".format(cache_path)) return dataset_dicts
def bbox2result_kitti2d(self, net_outputs, class_names, pklfile_prefix=None, submission_prefix=None): """Convert 2D detection results to kitti format for evaluation and test submission. Args: net_outputs (list[np.ndarray]): List of array storing the \ inferenced bounding boxes and scores. class_names (list[String]): A list of class names. pklfile_prefix (str | None): The prefix of pkl file. submission_prefix (str | None): The prefix of submission file. Returns: list[dict]: A list of dictionaries have the kitti format """ assert len(net_outputs) == len(self.data_infos), \ 'invalid list length of network outputs' det_annos = [] print('\nConverting prediction to KITTI format') for i, bboxes_per_sample in enumerate( mmcv.track_iter_progress(net_outputs)): annos = [] anno = dict(name=[], truncated=[], occluded=[], alpha=[], bbox=[], dimensions=[], location=[], rotation_y=[], score=[]) sample_idx = self.data_infos[i]['image']['image_idx'] num_example = 0 for label in range(len(bboxes_per_sample)): bbox = bboxes_per_sample[label] for i in range(bbox.shape[0]): anno['name'].append(class_names[int(label)]) anno['truncated'].append(0.0) anno['occluded'].append(0) anno['alpha'].append(0.0) anno['bbox'].append(bbox[i, :4]) # set dimensions (height, width, length) to zero anno['dimensions'].append( np.zeros(shape=[3], dtype=np.float32)) # set the 3D translation to (-1000, -1000, -1000) anno['location'].append( np.ones(shape=[3], dtype=np.float32) * (-1000.0)) anno['rotation_y'].append(0.0) anno['score'].append(bbox[i, 4]) num_example += 1 if num_example == 0: annos.append( dict( name=np.array([]), truncated=np.array([]), occluded=np.array([]), alpha=np.array([]), bbox=np.zeros([0, 4]), dimensions=np.zeros([0, 3]), location=np.zeros([0, 3]), rotation_y=np.array([]), score=np.array([]), )) else: anno = {k: np.stack(v) for k, v in anno.items()} annos.append(anno) annos[-1]['sample_idx'] = np.array([sample_idx] * num_example, dtype=np.int64) det_annos += annos if pklfile_prefix is not None: # save file in pkl format pklfile_path = (pklfile_prefix[:-4] if pklfile_prefix.endswith( ('.pkl', '.pickle')) else pklfile_prefix) mmcv.dump(det_annos, pklfile_path) if submission_prefix is not None: # save file in submission format mmcv.mkdir_or_exist(submission_prefix) print(f'Saving KITTI submission to {submission_prefix}') for i, anno in enumerate(det_annos): sample_idx = self.data_infos[i]['image']['image_idx'] cur_det_file = f'{submission_prefix}/{sample_idx:06d}.txt' with open(cur_det_file, 'w') as f: bbox = anno['bbox'] loc = anno['location'] dims = anno['dimensions'][::-1] # lhw -> hwl for idx in range(len(bbox)): print( '{} -1 -1 {:4f} {:4f} {:4f} {:4f} {:4f} {:4f} ' '{:4f} {:4f} {:4f} {:4f} {:4f} {:4f} {:4f}'.format( anno['name'][idx], anno['alpha'][idx], *bbox[idx], # 4 float *dims[idx], # 3 float *loc[idx], # 3 float anno['rotation_y'][idx], anno['score'][idx]), file=f, ) print('Result is saved to {}'.format(submission_prefix)) return det_annos
def main(): args = parse_args() cfg = mmcv.Config.fromfile(args.config) # set multi-process settings setup_multi_processes(cfg) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) rank, _ = get_dist_info() # set random seeds if args.seed is not None: if rank == 0: print('set random seed to', args.seed) set_random_seed(args.seed, deterministic=args.deterministic) # build the dataloader # TODO: support multiple images per gpu (only minor changes are needed) dataset = build_dataset(cfg.data.test) loader_cfg = { **dict((k, cfg.data[k]) for k in ['workers_per_gpu'] if k in cfg.data), **dict( samples_per_gpu=1, drop_last=False, shuffle=False, dist=distributed), **cfg.data.get('test_dataloader', {}) } data_loader = build_dataloader(dataset, **loader_cfg) # build the model and load checkpoint model = build_model(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) args.save_image = args.save_path is not None empty_cache = cfg.get('empty_cache', False) if not distributed: _ = load_checkpoint(model, args.checkpoint, map_location='cpu') model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test( model, data_loader, save_path=args.save_path, save_image=args.save_image) else: find_unused_parameters = cfg.get('find_unused_parameters', False) model = DistributedDataParallelWrapper( model, device_ids=[torch.cuda.current_device()], broadcast_buffers=False, find_unused_parameters=find_unused_parameters) device_id = torch.cuda.current_device() _ = load_checkpoint( model, args.checkpoint, map_location=lambda storage, loc: storage.cuda(device_id)) outputs = multi_gpu_test( model, data_loader, args.tmpdir, args.gpu_collect, save_path=args.save_path, save_image=args.save_image, empty_cache=empty_cache) if rank == 0 and 'eval_result' in outputs[0]: print('') # print metrics stats = dataset.evaluate(outputs) for stat in stats: print('Eval-{}: {}'.format(stat, stats[stat])) # save result pickle if args.out: print('writing results to {}'.format(args.out)) mmcv.dump(outputs, args.out)
def main(): args = [ './configs/DOTA_hbb/retinanet_r50_fpn_2x_dota.py', './results/retinanet_hbb_tv/epoch_24.pth', '--out', './results/retinanet_hbb_tv/result.pkl', '--eval', 'bbox' ] args = parse_args(args) print(args) assert args.out or args.eval or args.format_only or args.show \ or args.show_dir, \ ('Please specify at least one operation (save/eval/format/show the ' 'results / save the results) with the argument "--out", "--eval"' ', "--format-only", "--show" or "--show-dir"') if args.eval and args.format_only: raise ValueError('--eval and --format_only cannot be both specified') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') cfg = Config.fromfile(args.config) if args.cfg_options is not None: cfg.merge_from_dict(args.cfg_options) # import modules from string list. if cfg.get('custom_imports', None): from mmcv.utils import import_modules_from_strings import_modules_from_strings(**cfg['custom_imports']) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None if cfg.model.get('neck'): if isinstance(cfg.model.neck, list): for neck_cfg in cfg.model.neck: if neck_cfg.get('rfp_backbone'): if neck_cfg.rfp_backbone.get('pretrained'): neck_cfg.rfp_backbone.pretrained = None elif cfg.model.neck.get('rfp_backbone'): if cfg.model.neck.rfp_backbone.get('pretrained'): cfg.model.neck.rfp_backbone.pretrained = None # in case the test dataset is concatenated if isinstance(cfg.data.test, dict): cfg.data.test.test_mode = True elif isinstance(cfg.data.test, list): for ds_cfg in cfg.data.test: ds_cfg.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader samples_per_gpu = cfg.data.test.pop('samples_per_gpu', 1) if samples_per_gpu > 1: # Replace 'ImageToTensor' to 'DefaultFormatBundle' cfg.data.test.pipeline = replace_ImageToTensor(cfg.data.test.pipeline) dataset = build_dataset(cfg.data.test) data_loader = build_dataloader(dataset, samples_per_gpu=samples_per_gpu, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) # build the model and load checkpoint model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') if args.fuse_conv_bn: model = fuse_conv_bn(model) # old versions did not save class info in checkpoints, this walkaround is # for backward compatibility if 'CLASSES' in checkpoint['meta']: model.CLASSES = checkpoint['meta']['CLASSES'] else: model.CLASSES = dataset.CLASSES if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader, args.show, args.show_dir, args.show_score_thr) else: model = MMDistributedDataParallel( model.cuda(), device_ids=[torch.cuda.current_device()], broadcast_buffers=False) outputs = multi_gpu_test(model, data_loader, args.tmpdir, args.gpu_collect) rank, _ = get_dist_info() if rank == 0: if args.out: print(f'\nwriting results to {args.out}') mmcv.dump(outputs, args.out) kwargs = {} if args.eval_options is None else args.eval_options if args.format_only: dataset.format_results(outputs, **kwargs) if args.eval: eval_kwargs = cfg.get('evaluation', {}).copy() # hard-code way to remove EvalHook args for key in ['interval', 'tmpdir', 'start', 'gpu_collect']: eval_kwargs.pop(key, None) eval_kwargs.update(dict(metric=args.eval, **kwargs)) print(dataset.evaluate(outputs, **eval_kwargs))
def test_load_kinetics_pose(): def get_mode(arr): cnt = defaultdict(lambda: 0) for num in arr: cnt[num] += 1 max_val = max(cnt.values()) return [k for k in cnt if cnt[k] == max_val], max_val with tempfile.TemporaryDirectory() as tmpdir: filename = osp.join(tmpdir, 'tmp.pkl') total_frames = 100 img_shape = (224, 224) frame_inds = np.random.choice(range(100), size=120) frame_inds.sort() anno_flag = np.random.random(120) > 0.1 anno_inds = np.array([i for i, f in enumerate(anno_flag) if f]) kp = np.random.random([120, 17, 3]) dump(kp, filename) results = dict( filename=filename, total_frames=total_frames, img_shape=img_shape, frame_inds=frame_inds) inp = cp.deepcopy(results) with pytest.raises(NotImplementedError): LoadKineticsPose(squeeze=True, max_person=100, source='xxx') load_kinetics_pose = LoadKineticsPose( squeeze=True, max_person=100, source='openpose-18') assert str(load_kinetics_pose) == ( 'LoadKineticsPose(io_backend=disk, ' 'squeeze=True, max_person=100, ' "keypoint_weight={'face': 1, " "'torso': 2, 'limb': 3}, " 'source=openpose-18, kwargs={})') return_results = load_kinetics_pose(inp) assert return_results['keypoint'].shape[:-1] == \ return_results['keypoint_score'].shape num_person = return_results['keypoint'].shape[0] num_frame = return_results['keypoint'].shape[1] assert num_person == get_mode(frame_inds)[1] assert np.max(return_results['keypoint']) > 1 assert num_frame == len(set(frame_inds)) inp = cp.deepcopy(results) load_kinetics_pose = LoadKineticsPose( squeeze=False, max_person=100, source='openpose-18') return_results = load_kinetics_pose(inp) assert return_results['keypoint'].shape[:-1] == \ return_results['keypoint_score'].shape num_person = return_results['keypoint'].shape[0] num_frame = return_results['keypoint'].shape[1] assert num_person == get_mode(frame_inds)[1] assert np.max(return_results['keypoint']) > 1 assert num_frame == total_frames inp = cp.deepcopy(results) inp['anno_inds'] = anno_inds load_kinetics_pose = LoadKineticsPose( squeeze=True, max_person=100, source='mmpose') return_results = load_kinetics_pose(inp) assert return_results['keypoint'].shape[:-1] == \ return_results['keypoint_score'].shape num_person = return_results['keypoint'].shape[0] num_frame = return_results['keypoint'].shape[1] assert num_person == get_mode(frame_inds[anno_inds])[1] assert np.max(return_results['keypoint']) <= 1 assert num_frame == len(set(frame_inds[anno_inds])) inp = cp.deepcopy(results) inp['anno_inds'] = anno_inds load_kinetics_pose = LoadKineticsPose( squeeze=True, max_person=2, source='mmpose') return_results = load_kinetics_pose(inp) assert return_results['keypoint'].shape[:-1] == \ return_results['keypoint_score'].shape num_person = return_results['keypoint'].shape[0] num_frame = return_results['keypoint'].shape[1] assert num_person <= 2 assert np.max(return_results['keypoint']) <= 1 assert num_frame == len(set(frame_inds[anno_inds]))
def create_nuscenes_infos( root_path, info_prefix, version="v1.0-trainval", max_prev_samples=10 ): """Create info file of nuscene dataset. Given the raw data, generate its related info file in pkl format. Args: root_path (str): Path of the data root. info_prefix (str): Prefix of the info file to be generated. version (str): Version of the data. Default: 'v1.0-trainval' max_prev_samples (int): Max number of previous samples to include per sample. Default: 10 """ from nuscenes.nuscenes import NuScenes nusc = NuScenes(version=version, dataroot=root_path, verbose=True) from nuscenes.utils import splits available_vers = ["v1.0-trainval", "v1.0-test", "v1.0-mini"] assert version in available_vers if version == "v1.0-trainval": train_scenes = splits.train val_scenes = splits.val elif version == "v1.0-test": train_scenes = splits.test val_scenes = [] elif version == "v1.0-mini": train_scenes = splits.mini_train val_scenes = splits.mini_val else: raise ValueError("unknown") # filter existing scenes. available_scenes = get_available_scenes(nusc) available_scene_names = [s["name"] for s in available_scenes] train_scenes = list(filter(lambda x: x in available_scene_names, train_scenes)) val_scenes = list(filter(lambda x: x in available_scene_names, val_scenes)) train_scenes = set( [ available_scenes[available_scene_names.index(s)]["token"] for s in train_scenes ] ) val_scenes = set( [available_scenes[available_scene_names.index(s)]["token"] for s in val_scenes] ) test = "test" in version if test: print("test scene: {}".format(len(train_scenes))) else: print( "train scene: {}, val scene: {}".format(len(train_scenes), len(val_scenes)) ) train_nusc_infos, val_nusc_infos = _fill_trainval_infos( nusc, train_scenes, val_scenes, test, max_prev_samples=max_prev_samples ) metadata = dict(version=version) if test: print("test sample: {}".format(len(train_nusc_infos))) data = dict(infos=train_nusc_infos, metadata=metadata) info_path = osp.join(root_path, "{}_infos_test.pkl".format(info_prefix)) mmcv.dump(data, info_path) else: print( "train sample: {}, val sample: {}".format( len(train_nusc_infos), len(val_nusc_infos) ) ) data = dict(infos=train_nusc_infos, metadata=metadata) info_path = osp.join(root_path, "{}_infos_train.pkl".format(info_prefix)) mmcv.dump(data, info_path) data["infos"] = val_nusc_infos info_val_path = osp.join(root_path, "{}_infos_val.pkl".format(info_prefix)) mmcv.dump(data, info_val_path)
def dump_results(self, results, out): """Dump data to json/yaml/pickle strings or files.""" return mmcv.dump(results, out)
lst_cnt_i = lst_cnt.copy() np.random.seed(20+ rnd +i) np.random.shuffle(lst_cnt_i) cnt_lst_idx = np.setdiff1d(list(range(len_sub_lst)), orig_sub_idx) sub_lst[cnt_lst_idx] = lst_cnt_i lst_new = np.concatenate((lst_new,sub_lst.copy())) lst = lst_new.copy() assert str(lst.shape[0]) in glob(data_dir+f'seg_incl_test_rnd{rnd}_{sampled.cnt.sum()}.csv' )[0] lst_all = np.concatenate((lst_all, lst.copy())) #mmcv.dump(lst_all, data_dir + 'mmdet_anno/seg_oversample_test_rnd9to15_filenames_3147572.pkl') lst_all = mmcv.load(data_dir + 'mmdet_anno/seg_oversample_test_rnd9to15_filenames_3147572.pkl') all_ann = mmcv.load(data_dir + 'mmdet_anno/seg_train_275_leave_cls_ann.pkl') +\ mmcv.load(data_dir + 'mmdet_anno/seg_val_275_leave_cls_ann.pkl') +\ mmcv.load(data_dir + 'mmdet_anno/seg_test_leaves_ann.pkl') d_all_ann = {all_ann[i]['filename'][:-4]:i for i in range(len(all_ann))} final_ann = [all_ann[d_all_ann[img]] for img in lst_all] mmcv.dump(final_ann, data_dir+ 'seg_oversample_test_rnd9to15_ann_3147572.pkl')
def main(): args = parse_args() assert args.out or args.eval or args.format_only or args.show \ or args.show_dir, \ ('Please specify at least one operation (save/eval/format/show the ' 'results / save the results) with the argument "--out", "--eval"' ', "--format-only", "--show" or "--show-dir"') if args.eval and args.format_only: raise ValueError('--eval and --format_only cannot be both specified') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') cfg = mmcv.Config.fromfile(args.config) if args.options is not None: cfg.merge_from_dict(args.options) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True if args.aug_test: # hard code index cfg.data.test.pipeline[1].img_ratios = [ 0.5, 0.75, 1.0, 1.25, 1.5, 1.75 ] cfg.data.test.pipeline[1].flip = True cfg.model.pretrained = None cfg.data.test.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader # TODO: support multiple images per gpu (only minor changes are needed) dataset = build_dataset(cfg.data.test) data_loader = build_dataloader(dataset, samples_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) # build the model and load checkpoint cfg.model.train_cfg = None model = build_segmentor(cfg.model, test_cfg=cfg.get('test_cfg')) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') model.CLASSES = checkpoint['meta']['CLASSES'] model.PALETTE = checkpoint['meta']['PALETTE'] efficient_test = False if args.eval_options is not None: efficient_test = args.eval_options.get('efficient_test', False) if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader, args.show, args.show_dir, efficient_test, args.opacity) else: model = MMDistributedDataParallel( model.cuda(), device_ids=[torch.cuda.current_device()], broadcast_buffers=False) outputs = multi_gpu_test(model, data_loader, args.tmpdir, args.gpu_collect, efficient_test) rank, _ = get_dist_info() if rank == 0: if args.out: print(f'\nwriting results to {args.out}') mmcv.dump(outputs, args.out) kwargs = {} if args.eval_options is None else args.eval_options if args.format_only: dataset.format_results(outputs, **kwargs) if args.eval: dataset.evaluate(outputs, args.eval, **kwargs)
def main(): args = parse_args() if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') cfg = mmcv.Config.fromfile(args.config) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.data.test.test_mode = True if cfg.data.test.oversample == 'three_crop': cfg.model.spatial_temporal_module.spatial_size = 8 dataset = obj_from_dict(cfg.data.test, datasets, dict(test_mode=True)) if args.gpus == 1: model = build_recognizer(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) load_checkpoint(model, args.checkpoint, strict=True) model = MMDataParallel(model, device_ids=[0]) data_loader = build_dataloader( dataset, imgs_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, num_gpus=1, dist=False, shuffle=False) outputs = single_test(model, data_loader) else: model_args = cfg.model.copy() model_args.update(train_cfg=None, test_cfg=cfg.test_cfg) model_type = getattr(recognizers, model_args.pop('type')) outputs = parallel_test(model_type, model_args, args.checkpoint, dataset, _data_func, range(args.gpus), workers_per_gpu=args.proc_per_gpu) if args.out: print('writing results to {}'.format(args.out)) mmcv.dump(outputs, args.out) gt_labels = [] for i in range(len(dataset)): ann = dataset.get_ann_info(i) gt_labels.append(ann['label']) if args.use_softmax: print("Averaging score over {} clips with softmax".format( outputs[0].shape[0])) results = [softmax(res, dim=1).mean(axis=0) for res in outputs] else: print("Averaging score over {} clips without softmax (ie, raw)".format( outputs[0].shape[0])) results = [res.mean(axis=0) for res in outputs] top1, top5 = top_k_accuracy(results, gt_labels, k=(1, 5)) mean_acc = mean_class_accuracy(results, gt_labels) print("Mean Class Accuracy = {:.02f}".format(mean_acc * 100)) print("Top-1 Accuracy = {:.02f}".format(top1 * 100)) print("Top-5 Accuracy = {:.02f}".format(top5 * 100))
else: metrics = f'{model_performance["bbox_mAP"]}' row_num = sheet_info.get(config, None) if row_num: table.write(row_num, args.ncol, metrics) else: table.write(total_nrows, 0, config) table.write(total_nrows, args.ncol, metrics) total_nrows += 1 else: print(f'{config} not exist: {ckpt_path}') else: print(f'not exist: {config}') # 4 save or print results if metrics_out: mmcv.mkdir_or_exist(metrics_out) mmcv.dump(result_dict, osp.join(metrics_out, 'model_metric_info.json')) if not args.not_show: print('===================================') for config_name, metrics in result_dict.items(): print(config_name, metrics) print('===================================') if args.excel: filename, sufflx = osp.splitext(args.excel) xlrw.save(f'{filename}_o{sufflx}') print(f'>>> Output {filename}_o{sufflx}')
def main(): args = parse_args() assert args.out or args.show or args.json_out, \ ('Please specify at least one operation (save or show the results) ' 'with the argument "--out" or "--show" or "--json_out"') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') if args.json_out is not None and args.json_out.endswith('.json'): args.json_out = args.json_out[:-5] cfg = mmcv.Config.fromfile(args.config) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True cfg.model.pretrained = None cfg.data.test.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader # TODO: support multiple images per gpu (only minor changes are needed) dataset = build_dataset(cfg.data.test) data_loader = build_dataloader(dataset, imgs_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) # build the model and load checkpoint model = build_detector(cfg.model, train_cfg=None, test_cfg=cfg.test_cfg) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') # old versions did not save class info in checkpoints, this walkaround is # for backward compatibility if 'CLASSES' in checkpoint['meta']: # 训练时保存了最终分类的类别信息 model.CLASSES = checkpoint['meta']['CLASSES'] else: model.CLASSES = dataset.CLASSES if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader, args.show) else: model = MMDistributedDataParallel(model.cuda()) outputs = multi_gpu_test(model, data_loader, args.tmpdir, args.gpu_collect) rank, _ = get_dist_info() if args.out and rank == 0: print('\nwriting results to {}'.format(args.out)) mmcv.dump(outputs, args.out) eval_types = args.eval if eval_types: print('Starting evaluate {}'.format(' and '.join(eval_types))) if eval_types == ['proposal_fast']: result_file = args.out coco_eval(result_file, eval_types, dataset.coco) else: if not isinstance(outputs[0], dict): # print(outputs) result_files = results2json(dataset, outputs, args.out) # print("result_files:") # print(result_files) # print(json.load(open(result_files['bbox']))) coco_eval(result_files, eval_types, dataset.coco) else: for name in outputs[0]: print('\nEvaluating {}'.format(name)) outputs_ = [out[name] for out in outputs] result_file = args.out + '.{}'.format(name) result_files = results2json(dataset, outputs_, result_file) coco_eval(result_files, eval_types, dataset.coco) # Save predictions in the COCO json format if args.json_out and rank == 0: if not isinstance(outputs[0], dict): results2json(dataset, outputs, args.json_out) else: for name in outputs[0]: outputs_ = [out[name] for out in outputs] result_file = args.json_out + '.{}'.format(name) results2json(dataset, outputs_, result_file)
def main(): args = parse_args() assert args.out or args.eval or args.format_only or args.show \ or args.show_dir, \ ('Please specify at least one operation (save/eval/format/show the ' 'results / save the results) with the argument "--out", "--eval"' ', "--format-only", "--show" or "--show-dir"') if args.eval and args.format_only: raise ValueError('--eval and --format_only cannot be both specified') if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): raise ValueError('The output file must be a pkl file.') cfg = Config.fromfile(args.config) cfg.model.pretrains = {} if cfg.get('USE_MMDET', False): from mmdet.apis import multi_gpu_test, single_gpu_test from mmdet.datasets import build_dataloader from mmdet.models import build_detector as build_model else: from mmtrack.apis import multi_gpu_test, single_gpu_test from mmtrack.datasets import build_dataloader from mmtrack.models import build_model if args.cfg_options is not None: cfg.merge_from_dict(args.cfg_options) # set cudnn_benchmark if cfg.get('cudnn_benchmark', False): torch.backends.cudnn.benchmark = True # cfg.model.pretrains = None if hasattr(cfg.model, 'detector'): cfg.model.detector.pretrained = None cfg.data.test.test_mode = True # init distributed env first, since logger depends on the dist info. if args.launcher == 'none': distributed = False else: distributed = True init_dist(args.launcher, **cfg.dist_params) # build the dataloader dataset = build_dataset(cfg.data.test) limit = cfg.data.get('limit_eval') if limit is not None: dataset.reduce_to_subset(range(limit)) data_loader = build_dataloader(dataset, samples_per_gpu=1, workers_per_gpu=cfg.data.workers_per_gpu, dist=distributed, shuffle=False) # build the model and load checkpoint if cfg.get('test_cfg', False): model = build_model(cfg.model, train_cfg=cfg.train_cfg, test_cfg=cfg.test_cfg) else: model = build_model(cfg.model) fp16_cfg = cfg.get('fp16', None) if fp16_cfg is not None: wrap_fp16_model(model) if args.checkpoint is not None: checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') if 'CLASSES' in checkpoint['meta']: model.CLASSES = checkpoint['meta']['CLASSES'] if not hasattr(model, 'CLASSES'): model.CLASSES = dataset.CLASSES if args.fuse_conv_bn: model = fuse_conv_bn(model) if not distributed: model = MMDataParallel(model, device_ids=[0]) outputs = single_gpu_test(model, data_loader, args.show, args.show_dir, args.show_score_thr) else: model = MMDistributedDataParallel( model.cuda(), device_ids=[torch.cuda.current_device()], broadcast_buffers=False) outputs = multi_gpu_test(model, data_loader, args.tmpdir, args.gpu_collect) rank, _ = get_dist_info() if rank == 0: if args.out: print(f'\nwriting results to {args.out}') mmcv.dump(outputs, args.out) kwargs = {} if args.eval_options is None else args.eval_options if args.format_only: dataset.format_results(outputs, **kwargs) if args.eval: eval_kwargs = cfg.get('evaluation', {}).copy() # hard-code way to remove EvalHook args for key in ['interval', 'tmpdir', 'start', 'gpu_collect']: eval_kwargs.pop(key, None) eval_kwargs.update(dict(metric=args.eval, **kwargs)) eval_kwargs['bbox_kwargs'] = {'classwise': True} print(dataset.evaluate(outputs, **eval_kwargs))
def create_nuscenes_infos(root_path, info_prefix, version='v1.0-trainval', max_sweeps=10): """Create info file of nuscene dataset. Given the raw data, generate its related info file in pkl format. Args: root_path (str): Path of the data root. info_prefix (str): Prefix of the info file to be generated. version (str): Version of the data. Default: 'v1.0-trainval' max_sweeps (int): Max number of sweeps. Default: 10 """ from nuscenes.nuscenes import NuScenes nusc = NuScenes(version=version, dataroot=root_path, verbose=True) from nuscenes.utils import splits available_vers = ['v1.0-trainval', 'v1.0-test', 'v1.0-mini'] assert version in available_vers if version == 'v1.0-trainval': train_scenes = splits.train val_scenes = splits.val elif version == 'v1.0-test': train_scenes = splits.test val_scenes = [] elif version == 'v1.0-mini': train_scenes = splits.mini_train val_scenes = splits.mini_val else: raise ValueError('unknown') # filter existing scenes. available_scenes = get_available_scenes(nusc) available_scene_names = [s['name'] for s in available_scenes] train_scenes = list( filter(lambda x: x in available_scene_names, train_scenes)) val_scenes = list(filter(lambda x: x in available_scene_names, val_scenes)) train_scenes = set([ available_scenes[available_scene_names.index(s)]['token'] for s in train_scenes ]) val_scenes = set([ available_scenes[available_scene_names.index(s)]['token'] for s in val_scenes ]) test = 'test' in version if test: print('test scene: {}'.format(len(train_scenes))) else: print('train scene: {}, val scene: {}'.format( len(train_scenes), len(val_scenes))) train_nusc_infos, val_nusc_infos = _fill_trainval_infos( nusc, train_scenes, val_scenes, test, max_sweeps=max_sweeps) metadata = dict(version=version) if test: print('test sample: {}'.format(len(train_nusc_infos))) data = dict(infos=train_nusc_infos, metadata=metadata) info_path = osp.join(root_path, '{}_infos_test.pkl'.format(info_prefix)) mmcv.dump(data, info_path) else: print('train sample: {}, val sample: {}'.format( len(train_nusc_infos), len(val_nusc_infos))) data = dict(infos=train_nusc_infos, metadata=metadata) info_path = osp.join(root_path, '{}_infos_train.pkl'.format(info_prefix)) mmcv.dump(data, info_path) data['infos'] = val_nusc_infos info_val_path = osp.join(root_path, '{}_infos_val.pkl'.format(info_prefix)) mmcv.dump(data, info_val_path)
def main(): args = parse_args() models_root = args.root models_out = args.out mmcv.mkdir_or_exist(models_out) # find all models in the root directory to be gathered raw_configs = list(mmcv.scandir('./configs', '.py', recursive=True)) # filter configs that is not trained in the experiments dir used_configs = [] for raw_config in raw_configs: if osp.exists(osp.join(models_root, raw_config)): used_configs.append(raw_config) print(f'Find {len(used_configs)} models to be gathered') # find final_ckpt and log file for trained each config # and parse the best performance model_infos = [] for used_config in used_configs: exp_dir = osp.join(models_root, used_config) by_epoch = is_by_epoch(used_config) # check whether the exps is finished if args.best is True: final_model, final_epoch_or_iter = get_best_epoch_or_iter(exp_dir) else: final_epoch_or_iter = get_final_epoch_or_iter(used_config) final_model = '{}_{}.pth'.format('epoch' if by_epoch else 'iter', final_epoch_or_iter) model_path = osp.join(exp_dir, final_model) # skip if the model is still training if not osp.exists(model_path): continue # get the latest logs log_json_path = list(sorted(glob.glob(osp.join(exp_dir, '*.log.json'))))[-1] log_txt_path = list(sorted(glob.glob(osp.join(exp_dir, '*.log'))))[-1] cfg = mmcv.Config.fromfile('./configs/' + used_config) results_lut = cfg.evaluation.metric if not isinstance(results_lut, list): results_lut = [results_lut] # case when using VOC, the evaluation key is only 'mAP' # when using Panoptic Dataset, the evaluation key is 'PQ'. for i, key in enumerate(results_lut): if 'mAP' not in key and 'PQ' not in key: results_lut[i] = key + 'm_AP' model_performance = get_final_results(log_json_path, final_epoch_or_iter, results_lut, by_epoch) if model_performance is None: continue model_time = osp.split(log_txt_path)[-1].split('.')[0] model_info = dict(config=used_config, results=model_performance, model_time=model_time, final_model=final_model, log_json_path=osp.split(log_json_path)[-1]) model_info['epochs' if by_epoch else 'iterations'] =\ final_epoch_or_iter model_infos.append(model_info) # publish model for each checkpoint publish_model_infos = [] for model in model_infos: model_publish_dir = osp.join(models_out, model['config'].rstrip('.py')) mmcv.mkdir_or_exist(model_publish_dir) model_name = osp.split(model['config'])[-1].split('.')[0] model_name += '_' + model['model_time'] publish_model_path = osp.join(model_publish_dir, model_name) trained_model_path = osp.join(models_root, model['config'], model['final_model']) # convert model final_model_path = process_checkpoint(trained_model_path, publish_model_path) # copy log shutil.copy( osp.join(models_root, model['config'], model['log_json_path']), osp.join(model_publish_dir, f'{model_name}.log.json')) shutil.copy( osp.join(models_root, model['config'], model['log_json_path'].rstrip('.json')), osp.join(model_publish_dir, f'{model_name}.log')) # copy config to guarantee reproducibility config_path = model['config'] config_path = osp.join( 'configs', config_path) if 'configs' not in config_path else config_path target_config_path = osp.split(config_path)[-1] shutil.copy(config_path, osp.join(model_publish_dir, target_config_path)) model['model_path'] = final_model_path publish_model_infos.append(model) models = dict(models=publish_model_infos) print(f'Totally gathered {len(publish_model_infos)} models') mmcv.dump(models, osp.join(models_out, 'model_info.json')) pwc_files = convert_model_info_to_pwc(publish_model_infos) for name in pwc_files: with open(osp.join(models_out, name + '_metafile.yml'), 'w') as f: ordered_yaml_dump(pwc_files[name], f, encoding='utf-8')