예제 #1
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('--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
예제 #3
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
예제 #4
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
예제 #5
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
예제 #6
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