def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser() parser.add_argument('--input', type=str, help="Input json file of annotations to remap") parser.add_argument('--output', type=str, help="Output json file path for result.") args = parser.parse_args(argv) print("Loading source annotation file " + args.input + "...") annot = rvc_json_helper.load_json(args.input) anns = [] for a in annot['annotations']: file_name = a['file_name'] image_id = os.path.splitext(file_name)[0] for segment in a['segments_info']: segment['image_id'] = image_id anns.append(segment) annot['annotations'] = anns print("Saving target annotation file "+args.output+"...") rvc_json_helper.save_json(annot, args.output) return 0
def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser() parser.add_argument('--image_root', type=str, default=None, help="adds image root to each filepath") parser.add_argument( '--image_root_rel', type=str, default=None, help= "adds relative path between output json dir and this directory each filepath" ) parser.add_argument('--annotations_val', type=str, help="Validation annotation file to get categories") parser.add_argument('--output', type=str, help="Output json file path for result.") args = parser.parse_args(argv) if not args.image_root_rel is None: args.image_root_rel, args.image_root = get_relative_path( args.image_root_rel, args.output) args.image_root = fix_missing_slash(args.image_root) args.image_root_rel = fix_missing_slash(args.image_root_rel) # load annotations val_annot = rvc_json_helper.load_json(args.annotations_val) # process images images = [] image_files = os.listdir(args.image_root_rel) for file in tqdm(image_files, desc="Processing images ..."): # get relative filename file_name = args.image_root.format(file_name=file, file_name_su=file.split('_')) + file # get image size image_path = args.image_root_rel.format( file_name=file, file_name_su=file.split('_')) + file width, height = imagesize.get(image_path) # create image info img = { 'file_name': file_name, 'id': os.path.splitext(file)[0], 'width': width, 'height': height } images.append(img) # create dataset test_image_info = {'images': images, 'categories': val_annot['categories']} # save output print("Saving target annotation file " + args.output + "...") rvc_json_helper.save_json(test_image_info, args.output) return 0
def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser() parser.add_argument( '--join', type=str, help= "Coco json file(s) to join, seperate list entries by semicolon, merging is done in order from first to last" ) parser.add_argument('--output', type=str, help="Output json file path for result.") args = parser.parse_args(argv) annot = {} joint_image_id = 0 for j in args.join.split(';'): if not os.path.exists(j): print("Error: file " + j + " not found!") return 1 print("Loading coco annotation file " + j + "...") annot_add = rvc_json_helper.load_json(j) src_info_idx = len(annot_add.get("info", {}).get("datasets", [])) if not 'info' in annot_add: annot_add["info"] = {"description": " loaded " + j} if "licenses" in annot_add: annot_add["info"]["licenses"] = annot_add["licenses"] if src_info_idx == 0: annot['info'] = join_info(annot_add) annot['categories'] = len(annot_add['categories']) else: annot['info'] = join_info(annot['info'], annot_add['info']) if not check_versions_match(annot, annot_add): print( "Cannot merge new data to existing file; incompatible formats!" ) return -3 old_id_to_new = {} for i in annot_add['images']: #save original ids for reference i['ds_id'] = i['id'] i['ds_id'] = src_info_idx # idx from src_info old_id_to_new[i['id']] = joint_image_id i['id'] = joint_image_id joint_image_id += 1 annot['images'] = annot.get('images', []) + annot_add.pop('images') for a in annot_add['annotations']: a['image_id'] = old_id_to_new[a['image_id']] annot['annotations'] = annot.get('annotations', []) + annot_add.pop('annotations') del annot_add print("Saving result joint annotations to file " + args.output + "...") rvc_json_helper.save_json(annot, args.output) return 0
def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser() parser.add_argument('--predictions', type=str, help="Input json file of predictions to remap") parser.add_argument( '--annotations', type=str, help="annotations json file used to create the mapping") parser.add_argument('--mapping', type=str, default='./obj_det_mapping.csv', help="Csv file defining mapping") parser.add_argument( '--mapping_row', type=str, default=None, help="Row header from row in csv file to use; default: second row") parser.add_argument( '--map_to', type=str, default=id, help="Map to id, freebase_id or any other category type") parser.add_argument('--void_id', type=int, default=0, help="Void id for labels not found in mapping csv") parser.add_argument( '--remove_void', dest='remove_void', action='store_true', help="Only keep boxes with labels that can be remapped") parser.add_argument('--output', type=str, help="Output json file path for result.") parser.add_argument( '--reduce_boxable', dest='reduce_boxable', action='store_true', help="Only keep minimum of annotation data needed for boxable training." ) parser.add_argument( '--reduce_pano', dest='reduce_pano', action='store_true', help= "Only keep minimum of annotation data needed for panoptic/instance segm. training." ) parser.set_defaults(remove_void=False, reduce_boxable=False, reduce_pano=False) args = parser.parse_args(argv) print("Loading source predictions file " + args.predictions + "...") pred = rvc_json_helper.load_json(args.predictions) print("Loading annotation file " + args.annotations + "...") annot = rvc_json_helper.load_json(args.annotations) # load pre-defined mapping; first row is target label name, row from --mapping_row # defines source row for this input data; use semicolon from N->1 mappings # e.g. # animal,cat;dog # will map both cat and dog source labels to the target label animal with open(args.mapping, newline='') as ifile: mapping0 = list(csv.reader(ifile)) if args.mapping_row is None: idx_use = 1 else: idx_use = mapping0[0].index(args.mapping_row) trg_labels = {m[0]: m[idx_use] for m in mapping0[1:]} cats_sorted = list(sorted(trg_labels.keys())) trg_cats = { c: { 'supercategory': 'rvc_jls', 'id': id0 + 1, 'name': c } for id0, c in enumerate(cats_sorted) } src_cats = {c['name'].lower().strip(): c for c in annot['categories']} trg_to_src = {} for t, src_all in trg_labels.items(): t_id = trg_cats[t]['id'] for s in src_all.split(';'): #allows multi-to-one mappings if len(s) == 0: continue s = s.lower().strip() if not s in src_cats: #quick fix for mix of supercategory and name tag in some mvd json file; mix of name/id in oid cat. file check_cat = "freebase_id" if "freebase_id" in annot[ 'categories'][0] else 'supercategory' pot_supcat = [ c['name'].lower().strip() for c in annot['categories'] if c.get(check_cat, '') == s ] if len(pot_supcat) == 1: s = pot_supcat[0] if not s in src_cats: print("Warning: Unknown source cat " + s + " requested. Skipping.") continue trg_to_src[t_id] = src_cats[s][args.map_to] for p in tqdm(pred, desc='Remapping predictions '): if 'category_id' in p: p['category_id'] = trg_to_src.get(p['category_id'], args.void_id) p['bbox'] = [round(box, 2) for box in p['bbox']] p['score'] = round(p['score'], 4) if 'segments_info' in p: for s in p['segments_info']: s["category_id"] = trg_to_src.get(s['category_id'], args.void_id) s['bbox'] = [round(box, 2) for box in s['bbox']] p['score'] = round(p['score'], 4) if args.reduce_boxable or args.reduce_pano: p.pop('segmentation', None) if args.remove_void: if 'category_id' in pred[0]: pred = [p for p in pred if p['category_id'] != args.void_id] if 'segments_info' in pred[0]: pred = [[s for s in p if s['category_id'] != args.void_id] for p in pred] print("Saving target prediction file " + args.output + "...") rvc_json_helper.save_json(pred, args.output) return 0
def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser() parser.add_argument('--input', type=str, help="Coco json file to split") parser.add_argument( '--split_perc', type=str, help= "Percentage numbers semicolon seperated for splitting. Specify 70;30 for a result with two json files." ) parser.add_argument( '--output', type=str, default=None, help= "Output json file path for result; a _0, _1, _2 etc is added to the basename for each split." ) args = parser.parse_args(argv) if args.output is None: args.output = args.input print("Loading source coco annotation file " + args.input + "...") annot = rvc_json_helper.load_json(args.input) num_imgs = len(annot['images']) img_to_idx = {} for im_idx, i in enumerate(annot['images']): img_to_idx[im_idx] = i annot['images'] = [] annot_to_idx = {} for a in annot['annotations']: annot_to_idx[a['image_id']] = annot_to_idx.get(a['image_id'], []) + [a] annot['annotations'] = [] all_indices = np.arange(num_imgs) np.random.shuffle(all_indices) split_start = 0 for split_idx, split_perc in enumerate(args.split_perc.split(';')): trg_file = args.output.replace(".json", "_%i.json" % split_idx) split_num = min(int(float(split_perc) * 0.01 * num_imgs + 0.5), num_imgs - split_start) split_idc = list( sorted(all_indices[split_start:split_start + split_num])) split_start += split_num images0 = [] add_image_ids = [] for i in split_idc: img_entry = img_to_idx.pop(i) add_image_ids.append(img_entry['id']) images0.append(img_entry) annot0 = [] for a in add_image_ids: annot0 += annot_to_idx.pop(a) annot_split = annot annot_split["images"] = images0 annot_split["annotations"] = annot0 print("Saving %i images into coco annotation file " % split_num + trg_file + "...") rvc_json_helper.save_json(annot_split, trg_file) if len(img_to_idx) > 0: print( "Warning: A total of %i image entries are in neither of the resulting splitted json files." % len(img_to_idx)) if len(annot_to_idx) > 0: print( "Warning: A total of %i annotation entries are in neither of the resulting splitted json files." % len(annot_to_idx)) return 0
def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser() parser.add_argument('--input', type=str, help="Input json file of annotations to remap") parser.add_argument('--mapping', type=str, default='./obj_det_mapping.csv', help="Csv file defining mapping") parser.add_argument('--mapping_row', type=str, default=None, help="Row header from row in csv file to use; default: second row") parser.add_argument('--image_root', type=str, default=None, help="adds image root to each filepath") parser.add_argument('--image_root_rel', type=str, default=None, help="adds relative path between output json dir and this directory each filepath") parser.add_argument('--annotation_root', type=str, default=None, help="adds annotation mask root to each filepath") parser.add_argument('--annotation_root_rel', type=str, default=None, help="adds relative path between output json dir and annotation mask directory each filepath") parser.add_argument('--void_id', type=int, default=0, help="Void id for labels not found in mapping csv") parser.add_argument('--output', type=str, help="Output json file path for result.") parser.add_argument('--reduce_boxable', dest='reduce_boxable', action='store_true', help="Only keep minimum of annotation data needed for boxable training.") parser.add_argument('--reduce_pano', dest='reduce_pano', action='store_true', help="Only keep minimum of annotation data needed for panoptic/instance segm. training.") parser.set_defaults(do_merging=False, reduce_boxable=False, reduce_pano=False) args = parser.parse_args(argv) if not args.image_root_rel is None: args.image_root_rel, args.image_root = get_relative_path(args.image_root_rel, args.output) if not args.annotation_root_rel is None: args.annotation_root_rel, args.annotation_root = get_relative_path(args.annotation_root_rel, args.output) fix_missing_slash(args.image_root) fix_missing_slash(args.annotation_root) print("Loading source annotation file " + args.input + "...") annot = rvc_json_helper.load_json(args.input) # load pre-defined mapping; first row is target label name, row from --mapping_row # defines source row for this input data; use semicolon from N->1 mappings # e.g. # animal,cat;dog # will map both cat and dog source labels to the target label animal with open(args.mapping, newline='') as ifile: mapping0 = list(csv.reader(ifile)) if args.mapping_row is None: idx_use = 1 else: idx_use = mapping0[0].index(args.mapping_row) trg_labels = {m[0]:m[idx_use] for m in mapping0[1:]} cats_sorted = list(sorted(trg_labels.keys())) trg_cats = {c:{'supercategory':'rvc_jls', 'id': id0+1, 'name':c} for id0, c in enumerate(cats_sorted)} src_cats = {c['name'].lower().strip():c for c in annot['categories']} src_to_trg = {} for t, src_all in trg_labels.items(): t_id = trg_cats[t]['id'] for s in src_all.split(';'): #allows multi-to-one mappings if len(s) == 0: continue s = s.lower().strip() if not s in src_cats: #quick fix for mix of supercategory and name tag in some mvs json file; mix of name/id in oid cat. file check_cat = "freebase_id" if "freebase_id" in annot['categories'][0] else 'supercategory' pot_supcat = [c['name'].lower().strip() for c in annot['categories'] if c.get(check_cat,'') == s] if len(pot_supcat) == 1: s = pot_supcat[0] if not s in src_cats: print("Warning: Unknown source cat "+s+" requested. Skipping.") continue src_to_trg[src_cats[s]['id']]= t_id if 'categories' in annot: annot['categories'] = [trg_cats[c] for c in cats_sorted] if not args.image_root is None: if args.image_root[-1] != '/' and args.image_root[-1] != '\\': args.image_root += '/' for i in annot['images']: i['file_name'] = args.image_root.format(file_name=i['file_name'], file_name_su = i['file_name'].split('_')) + i['file_name'] if args.reduce_pano or args.reduce_boxable: reduce_size_entries = ["date_captured","coco_url","url","flickr_url"] for i in annot['images']: for e in reduce_size_entries: i.pop(e,None) if 'annotations' in annot: for a in tqdm.tqdm(annot['annotations'], desc='Remapping annotations '): if 'category_id' in a: a['category_id'] = src_to_trg.get(a['category_id'],args.void_id) if 'segments_info' in a: for s in a['segments_info']: s["category_id"] = src_to_trg.get(s['category_id'],args.void_id) if args.reduce_boxable or args.reduce_pano: a.pop('segmentation',None) if not args.annotation_root is None and 'file_name' in a: a['file_name'] = args.annotation_root.format(file_name=a['file_name'], file_name_su = a['file_name'].split('_')) + a['file_name'] print("Saving target annotation file "+args.output+"...") rvc_json_helper.save_json(annot, args.output) return 0