def convert(imgdir, annpath, result_dir): ''' :param imgdir: directory for your images :param annpath: path for your annotations :return: coco_output is a dictionary of coco style which you could dump it into a json file as for keywords 'info','licenses','categories',you should modify them manually ''' coco_output = {} coco_output['info'] = { "description": "Example Dataset", "url": "", "version": "1.0", "year": 2019, "contributor": "Black Jack", "date_created": datetime.datetime.utcnow().isoformat(' ') } coco_output['licenses'] = [{ "id": 1, "name": "Attribution-NonCommercial-ShareAlike License", "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/" }] coco_output['categories'] = [{ "supercategory": "fish", "id": 1, "name": "fish", "keypoints": [ "Head", "Caudal", ], "skeleton": [ [1, 2], ] }] coco_output['images'] = [] coco_output['annotations'] = [] ann = json.load(open(annpath)) # annotations id start from zero ann_id = 0 num_invalid_images = 0 cat_id = 1 # 我直接默认所有类别为"fish",所以只有一个cat_id,其值为1 iscrowd = 0 #in VIA annotations, keys are image name for img_id, key in enumerate(ann.keys()): ann_num = 0 regions = ann[key]["regions"] shapes = [r['shape_attributes']['name'] for r in regions] if 'polygon' not in shapes: continue i1 = shapes.index('polygon') region_polygon = regions[i1] points_x = region_polygon['shape_attributes']['all_points_x'] points_y = region_polygon['shape_attributes']['all_points_y'] # if filename == 'data2_385.0.png': # print(len(points_x), len(points_y), 'polygonlen') assert len(points_x) == len(points_y), \ "in via json file polygon, length of all_points_x must equal to length of all_points_y. " area = getArea.GetAreaOfPolyGon(points_x, points_y) if not area: continue min_x = min(points_x) max_x = max(points_x) min_y = min(points_y) max_y = max(points_y) box = [min_x, min_y, max_x - min_x, max_y - min_y] # 仔细分析json分拣,VIA直接导出的COCO格式的json文件其实是不对的,使用mmdetection库进行训练时,根本不能识别出标注数据。 # 其中非常明显的就是 segmentation不对。 segmentation = get_segmenation(points_x, points_y) # keypoints kp_names = ['head', 'tail'] keypoints = [0] * (len(kp_names) * 3) ik = [i for i, r in enumerate(shapes) if r == 'point'] num_keypoints = len(ik) if len(ik) > 0: for i, kp_name in enumerate(kp_names): for ik_ in ik: region_kp = regions[ik_] if kp_name in region_kp["region_attributes"].values(): keypoints[i * 3 + 0] = region_kp["shape_attributes"]["cx"] keypoints[i * 3 + 1] = region_kp["shape_attributes"]["cy"] keypoints[i * 3 + 2] = 2 break # make annotations info and storage it in coco_output['annotations'] ann_info = create_annotation_info(ann_id, img_id, cat_id, iscrowd, area, box, segmentation, keypoints, num_keypoints) coco_output['annotations'].append(ann_info) ann_id = ann_id + 1 ann_num += 1 if ann_num > 0: filename = ann[key]['filename'] print(filename) img = cv2.imread(osp.join(imgdir, filename)) # make image info and storage it in coco_output['images'] image_info = create_image_info(img_id, os.path.basename(filename), img.shape[:2]) coco_output['images'].append(image_info) shutil.copy(osp.join(imgdir, filename), osp.join(result_dir, 'imgs', filename)) else: num_invalid_images += 1 print('total invalid image number is {}'.format(num_invalid_images)) return coco_output
def convert(imgdir, annpath, result_dir): ''' :param imgdir: directory for your images :param annpath: path for your annotations :return: coco_output is a dictionary of coco style which you could dump it into a json file as for keywords 'info','licenses','categories',you should modify them manually ''' coco_output = {} coco_output['info'] = { "description": "Example Dataset", "url": "", "version": "1.0", "year": 2019, "contributor": "Black Jack", "date_created": datetime.datetime.utcnow().isoformat(' ') } coco_output['licenses'] = [{ "id": 1, "name": "Attribution-NonCommercial-ShareAlike License", "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/" }] coco_output['categories'] = [{ "supercategory": "fish", "id": 1, "name": "fish", "keypoints": [ "Head", "Caudal", ], "skeleton": [ [1, 2], ] }] coco_output['images'] = [] coco_output['annotations'] = [] ann = json.load(open(annpath)) # annotations id start from zero ann_id = 0 num_invalid_images = 0 cat_id = 1 # 我直接默认所有类别为"fish",所以只有一个cat_id,其值为1 iscrowd = 0 kp_names = ['Head', 'Caudal'] #in VIA annotations, keys are image name for img_id, key in enumerate(ann.keys()): ann_num = 0 lab = ann[key] filename = lab["filename"] img_path = osp.join(imgdir, filename) scatter_kps = [ (reg["region_attributes"]["keypoint"], reg["shape_attributes"]["cx"], reg["shape_attributes"]["cy"]) # (kp_name, x, y) for reg in lab["regions"] if reg["shape_attributes"]["name"] == "point" and "keypoint" in reg["region_attributes"].keys() ] mask_polygons = [ list( zip(reg["shape_attributes"]["all_points_x"], reg["shape_attributes"]["all_points_y"])) for reg in lab["regions"] if reg["shape_attributes"]["name"] == "polygon" ] if len(mask_polygons) < 0 or not osp.exists(img_path): continue img = cv2.imread(img_path) for polygon in mask_polygons: points_x = [] points_y = [] for x, y in polygon: points_x.append(x) points_y.append(y) mask = np.zeros_like(img[:, :, 0]) mask = cv2.fillPoly( img=mask, pts=[np.expand_dims(np.array(polygon), axis=1)], color=(1, )) keypoints = [] num_keypoints = 0 for kp_name in kp_names: chosen = None candidates = [kp for kp in scatter_kps if kp[0] == kp_name] for kp in candidates: if mask[kp[2], kp[1]] == 1: chosen = [kp[1], kp[2], 2] # (x, y, visibility) num_keypoints += 1 break if chosen is None: chosen = [0, 0, 0] keypoints.extend(chosen) assert len(points_x) == len(points_y), \ "in via json file polygon, length of all_points_x must equal to length of all_points_y. " area = getArea.GetAreaOfPolyGon(points_x, points_y) if not area: continue min_x = min(points_x) max_x = max(points_x) min_y = min(points_y) max_y = max(points_y) box = [min_x, min_y, max_x - min_x, max_y - min_y] # 仔细分析json分拣,VIA直接导出的COCO格式的json文件其实是不对的,使用mmdetection库进行训练时,根本不能识别出标注数据。 # 其中非常明显的就是 segmentation不对。 segmentation = get_segmenation(points_x, points_y) # make annotations info and storage it in coco_output['annotations'] ann_info = create_annotation_info(ann_id, img_id, cat_id, iscrowd, area, box, segmentation, keypoints, num_keypoints) coco_output['annotations'].append(ann_info) ann_id = ann_id + 1 ann_num += 1 if ann_num > 0: print(filename) # make image info and storage it in coco_output['images'] image_info = create_image_info(img_id, os.path.basename(filename), img.shape[:2]) coco_output['images'].append(image_info) shutil.copy(img_path, osp.join(result_dir, 'imgs', filename)) else: num_invalid_images += 1 print('total invalid image number is {}'.format(num_invalid_images)) return coco_output
def convert(imgdir, annpath, result_path): ''' :param imgdir: directory for your images :param annpath: path for your annotations :return: coco_output is a dictionary of coco style which you could dump it into a json file as for keywords 'info','licenses','categories',you should modify them manually ''' via_output = {} ann = json.load(open(annpath)) # annotations id start from zero num_invalid_images = 0 #in VIA annotations, keys are image name for img_id, key in enumerate(ann.keys()): imgs_valid_list = os.listdir(imgdir) regions = ann[key]["regions"] filename = ann[key]['filename'] size = ann[key]["size"] if filename not in imgs_valid_list: continue # img = cv2.imread(os.path.join(imgdir, filename)) num_mask = 0 regions_new = [] # for one image ,there are many regions,they share the same img id for region in regions: # # 这里也需要修改。原作者是region['region_attributes']['label'], # # #但是其实应该是region['region_attributes']['supercategory_name'] # cat = region['region_attributes']['type'] #我的返回的子类的编号,所以其实不需要这一段, # print(cat) # assert cat in ['fish',]# 如果你的返回的是子类名字。那么这一段就需要。assert cat in ['name1', 'name2', 'name3',...] # if cat == 'fish': # if cat == 'name1': # cat_id = 1 cat_id = 1 # 我直接默认所有类别为"fish",所以只有一个cat_id,其值为1 iscrowd = 0 if 'cx' in region['shape_attributes']: regions_new.append(region) continue points_x = region['shape_attributes']['all_points_x'] points_y = region['shape_attributes']['all_points_y'] # if filename == 'data2_385.0.png': # print(len(points_x), len(points_y), 'polygonlen') assert len(points_x) == len(points_y), \ "in via json file polygon, length of all_points_x must equal to length of all_points_y. " area = getArea.GetAreaOfPolyGon(points_x, points_y) if area <= 0: continue # min_x = min(points_x) # max_x = max(points_x) # min_y = min(points_y) # max_y = max(points_y) # box = [min_x, min_y, max_x-min_x, max_y-min_y] # # patch = img[min_y: max_y, min_x: max_x] # # patch_name = filename[:-4]+'_'+str(num_mask)+'.jpg' # # cv2.imwrite(os.path.join(result_path, patch_name), patch) # points_x = [i - min_x for i in points_x] # points_y = [i - min_y for i in points_y] region_new = { "shape_attributes": { "name": "polygon", "all_points_x": points_x, "all_points_y": points_y }, "region_attributes": { "type": "fish" } } regions_new.append(region_new) num_mask += 1 if num_mask > 0: shutil.copy(os.path.join(imgdir, filename), os.path.join(result_path, filename)) print(filename) else: num_invalid_images += 1 via_output[filename + str(size)] = { 'filename': filename, 'size': size, 'regions': regions_new, "file_attributes": {} } print('total invalid image number is {}'.format(num_invalid_images)) return via_output
def vgg_to_labelme(img_dir, out_dir): ''' :param img_dir: 图片和json文件位于同一个目录下 :param out_dir: 输出路径 :return: ''' # 获取所有json文件全路径 vgg_json = glob.glob(os.path.join(img_dir, "*.json")) # 遍历文件夹中所有的json文件 for num, json_file in enumerate(vgg_json): coco_output = {} coco_output['version'] = "4.2.9" coco_output['flags'] = {} coco_output['shapes'] = [] shapes_info = [] # shapes的结果 json_file_name = os.path.basename(json_file) img_file_name = json_file_name.replace(".json", ".jpg") img_path = os.path.join(img_dir, img_file_name) img = cv2.imread(img_path) # 用 base64 将图片保存为字符串 # 读取二进制图片,获得原始字节码,注意 'rb' with open(img_path, 'rb') as jpg_file: byte_content = jpg_file.read() # 把原始字节码编码成 base64 字节码 base64_bytes = b64encode(byte_content) # 将 base64 字节码解码成 utf-8 格式的字符串 base64_string = base64_bytes.decode('utf-8') data = json.load(open(json_file)) for img_id, key in enumerate(data.keys()): filename = data[key]['filename'] regions = data[key]["regions"] for region in regions: shapes_sample = {} shape_att = region["shape_attributes"] if shape_att['name'] == 'polygon': shapes_sample['label'] = 'building' all_points_x = shape_att["all_points_x"] all_points_y = shape_att["all_points_y"] area = getArea.GetAreaOfPolyGon(all_points_x, all_points_y) points = _get_point(all_points_x, all_points_y) shapes_sample['points'] = points shapes_sample['group_id'] = None shapes_sample['shape_type'] = "polygon" shapes_sample['flags'] = {} #shapes_sample['area'] = area if area < 2: continue shapes_info.append(shapes_sample) coco_output["shapes"] = shapes_info coco_output['imagePath'] = os.path.basename(img_file_name) coco_output['imageData'] = base64_string coco_output['imageHeight'] = img.shape[0] coco_output['imageWidth'] = img.shape[1] # 把结果导出json文件 out_path = os.path.join(out_dir, json_file_name) with open(out_path, 'w', encoding='utf8') as file_obj: json.dump(coco_output, file_obj, indent=2)
def convert(VIA_ORIGINAL_ANNOTATIONS_NAME, imgdir, annpath): """ :param imgdir: directory for your images :param annpath: path for your annotations :return: coco_output is a dictionary of coco style which you could dump it into a json file as for keywords 'info','licenses','categories',you should modify them manually """ annotations = json.load( open(VIA_ORIGINAL_ANNOTATIONS_NAME, encoding="utf-8")) annotations = list(annotations.values()) # don't need the dict keys annotations = [a for a in annotations if a['regions']] name_supercategory_dict = {} for a in annotations: names = [r['region_attributes']['name'] for r in a['regions']] supercategories = ["part" for r in a['regions']] for index, name in enumerate(names): if name not in name_supercategory_dict.keys(): name_supercategory_dict[name] = supercategories[index] coco_output = {} coco_output['info'] = { "description": "CAR Dataset", "url": "https://github.com/Lplenka/", "version": "0.1.0", "year": 2020, "contributor": "Lplenka", "date_created": datetime.datetime.utcnow().isoformat(' ') } coco_output['licenses'] = [{ "id": 1, "name": "Attribution-NonCommercial-ShareAlike License", "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/" }] # coco_output['categories'] = [{ # 'id': 1, # 'name': "中性杆状核粒细胞", # 'supercategory': "粒細胞系", # }, # { # 'id': 2, # 'name': '中性中幼粒细胞', # 'supercategory': '粒細胞系', # }, # . # . # . # ] # get the coco category from dict coco_output['categories'] = [] for i in range(len(name_supercategory_dict)): category = { 'id': i + 1, 'name': list(name_supercategory_dict)[i], 'supercategory': name_supercategory_dict[list(name_supercategory_dict)[i]] } coco_output['categories'].append(category) coco_output['images'] = [] coco_output['annotations'] = [] ########################################################################################################## ann = json.load(open(annpath, encoding="utf-8")) # annotations id start from zero ann_id = 0 # in VIA annotations, [key]['filename'] are image name for img_id, key in enumerate(ann.keys()): filename = ann[key]['filename'] img = cv2.imread(imgdir + filename) # make image info and storage it in coco_output['images'] image_info = create_image_info(img_id, os.path.basename(filename), img.shape[:2]) coco_output['images'].append(image_info) regions = ann[key]["regions"] # for one image ,there are many regions,they share the same img id for region in regions: cate = region['region_attributes']['name'] # cate must in categories assert cate in [i['name'] for i in coco_output['categories']] # get the cate_id cate_id = 0 for category in coco_output['categories']: if cate == category['name']: cate_id = category['id'] #################################################################################################### iscrowd = 0 points_x = region['shape_attributes']['all_points_x'] points_y = region['shape_attributes']['all_points_y'] area = getArea.GetAreaOfPolyGon(points_x, points_y) min_x = min(points_x) max_x = max(points_x) min_y = min(points_y) max_y = max(points_y) box = [min_x, min_y, max_x - min_x, max_y - min_y] segmentation = get_segmenation(points_x, points_y) # make annotations info and storage it in coco_output['annotations'] ann_info = create_annotation_info(ann_id, img_id, cate_id, iscrowd, area, box, segmentation) coco_output['annotations'].append(ann_info) ann_id = ann_id + 1 return coco_output
def convert(imgdir, annpath): ''' :param imgdir: directory for your images :param annpath: path for your annotations :return: coco_output is a dictionary of coco style which you could dump it into a json file as for keywords 'info','licenses','categories',you should modify them manually ''' coco_output = {} coco_output['info'] = { "description": "Example Dataset", "url": "https://triasoft.wordpress.com/", "version": "0.1.0", "year": 2019, "contributor": "schwabse", "date_created": datetime.datetime.utcnow().isoformat(' ') } coco_output['licenses'] = [{ "id": 1, "name": "Attribution-NonCommercial-ShareAlike License", "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/" }] coco_output['categories'] = [{ 'id': 1, 'name': 'vertebrae', 'supercategory': 'spine', }, { 'id': 2, 'name': 'vertebrae', 'supercategory': 'spine', }] coco_output['images'] = [] coco_output['annotations'] = [] ann = json.load(open(annpath)) # annotations id start from zero ann_id = 0 # in VIA annotations, keys are image name for img_id, key in enumerate(ann.keys()): filename = ann[key]['filename'] img = cv2.imread(imgdir + filename) # make image info and storage it in coco_output['images'] image_info = create_image_info(img_id, os.path.basename(filename), img.shape[:2]) coco_output['images'].append(image_info) regions = ann[key]["regions"] # for one image ,there are many regions,they share the same img id for region in regions: cur = regions[region] try: cat = cur['region_attributes']['label'] print(cat) assert cat in ['vertebrae', 'S'] except: cat = '' if cat == 'rib': cat_id = 1 else: cat_id = 2 iscrowd = 0 points_x = cur['shape_attributes']['all_points_x'] points_y = cur['shape_attributes']['all_points_y'] area = getArea.GetAreaOfPolyGon(points_x, points_y) min_x = min(points_x) max_x = max(points_x) min_y = min(points_y) max_y = max(points_y) box = [min_x, min_y, max_x - min_x, max_y - min_y] segmentation = get_segmenation(points_x, points_y) # make annotations info and storage it in coco_output['annotations'] ann_info = create_annotation_info(ann_id, img_id, cat_id, iscrowd, area, box, segmentation) coco_output['annotations'].append(ann_info) ann_id = ann_id + 1 return coco_output
def convert(imgdir, annpath, result_dir): ''' :param imgdir: directory for your images :param annpath: path for your annotations :return: coco_output is a dictionary of coco style which you could dump it into a json file as for keywords 'info','licenses','categories',you should modify them manually ''' coco_output = {} coco_output['info'] = { "description": "Example Dataset", "url": "", "version": "1.0", "year": 2019, "contributor": "Black Jack", "date_created": datetime.datetime.utcnow().isoformat(' ') } coco_output['licenses'] = [{ "id": 1, "name": "Attribution-NonCommercial-ShareAlike License", "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/" }] coco_output['categories'] = [ { 'id': 1, 'name': 'shrimp', 'supercategory': 'allShrimp', }, ] coco_output['images'] = [] coco_output['annotations'] = [] ann = json.load(open(annpath)) # annotations id start from zero ann_id = 0 num_invalid_images = 0 cat_id = 1 # 我直接默认所有类别为"fish",所以只有一个cat_id,其值为1 iscrowd = 0 #in VIA annotations, keys are image name for img_id, key in enumerate(ann.keys()): ann_num = 0 regions = ann[key]["regions"] filename = ann[key]['filename'] img_path = osp.join(imgdir, filename) if not osp.exists(img_path): continue # for one image ,there are many regions,they share the same img id for region in regions: if region['shape_attributes']['name'] == "point": x = region['shape_attributes']['x'] y = region['shape_attributes']['y'] width = region['shape_attributes']['width'] height = region['shape_attributes']['height'] box = [x, y, width, height] area = 0 segmentation = [[]] ann_info = create_annotation_info(ann_id, img_id, cat_id, iscrowd, area, box, segmentation) coco_output['annotations'].append(ann_info) ann_id = ann_id + 1 # # 这里也需要修改。原作者是region['region_attributes']['label'], # # #但是其实应该是region['region_attributes']['supercategory_name'] # cat = region['region_attributes']['type'] #我的返回的子类的编号,所以其实不需要这一段, # print(cat) # assert cat in ['fish',]# 如果你的返回的是子类名字。那么这一段就需要。assert cat in ['name1', 'name2', 'name3',...] # if cat == 'fish': # if cat == 'name1': # cat_id = 1 elif region['shape_attributes']['name'] == "polygon": points_x = region['shape_attributes']['all_points_x'] points_y = region['shape_attributes']['all_points_y'] # if filename == 'data2_385.0.png': # print(len(points_x), len(points_y), 'polygonlen') assert len(points_x) == len(points_y), \ "in via json file polygon, length of all_points_x must equal to length of all_points_y. " area = getArea.GetAreaOfPolyGon(points_x, points_y) if not area: continue min_x = min(points_x) max_x = max(points_x) min_y = min(points_y) max_y = max(points_y) box = [min_x, min_y, max_x - min_x, max_y - min_y] # 仔细分析json分拣,VIA直接导出的COCO格式的json文件其实是不对的,使用mmdetection库进行训练时,根本不能识别出标注数据。 #其中非常明显的就是 segmentation不对。 segmentation = get_segmenation(points_x, points_y) # make annotations info and storage it in coco_output['annotations'] ann_info = create_annotation_info(ann_id, img_id, cat_id, iscrowd, area, box, segmentation) coco_output['annotations'].append(ann_info) ann_id = ann_id + 1 ann_num += 1 if ann_num > 0: print(filename) img = cv2.imread(img_path) # make image info and storage it in coco_output['images'] image_info = create_image_info(img_id, os.path.basename(filename), img.shape[:2]) coco_output['images'].append(image_info) shutil.copy(img_path, osp.join(result_dir, 'imgs', filename)) else: num_invalid_images += 1 print('total invalid image number is {}'.format(num_invalid_images)) return coco_output
def convert( imgdir, annpath, categories=None, super_categories=None, output_file_name=None, first_class_index=1, # typically, 0 or 1 ): """ :param imgdir: directory for your images :param annpath: path for your annotations :return: coco_output is a dictionary of coco style which you could dump it into a json file as for keywords 'info','licenses','categories',you should modify them manually """ if categories is None: categories = ["rib", "clavicle"] default_category = categories[0] category_dict = dict() for (cat_id, cat_name) in enumerate(categories, start=first_class_index): category_dict[cat_name] = cat_id if super_categories is None: default_super_category = "bone" super_categories = [default_super_category for _ in categories] coco_output = {} coco_output["info"] = { "description": "Example Dataset", "url": "https://github.com/waspinator/pycococreator", "version": "0.1.0", "year": 2018, "contributor": "waspinator", "date_created": datetime.datetime.utcnow().isoformat(" "), } coco_output["licenses"] = [{ "id": 1, "name": "Attribution-NonCommercial-ShareAlike License", "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/", }] coco_output["categories"] = [{ "id": category_dict[cat_name], "name": cat_name, "supercategory": super_cat_name, } for (cat_name, super_cat_name) in zip(categories, super_categories)] coco_output["images"] = [] coco_output["annotations"] = [] ann = json.load(open(annpath)) # annotations id start from zero ann_id = 0 # in VIA annotations, keys are image name for img_id, key in enumerate(ann.keys()): filename = ann[key]["filename"] img = Image.open(imgdir + filename) # make image info and storage it in coco_output['images'] image_info = create_image_info(img_id, os.path.basename(filename), image_size=img.size) # Caveat: image shapes are conventionally (height, width) whereas image sizes are conventionally (width, height) # References: # - https://note.nkmk.me/en/python-opencv-pillow-image-size/ # - https://github.com/facebookresearch/detectron2/blob/master/detectron2/data/detection_utils.py#L189 coco_output["images"].append(image_info) regions = ann[key]["regions"] # for one image ,there are many regions,they share the same img id for region in regions: region_attributes = regions[region]["region_attributes"] try: cat_name = region_attributes["label"] except KeyError: cat_name = default_category try: cat_id = category_dict[cat_name] except KeyError: print("Skipping unknown category {} in {}".format( cat_name, filename)) continue iscrowd = 0 shape_attributes = regions[region]["shape_attributes"] points_x = shape_attributes["all_points_x"] points_y = shape_attributes["all_points_y"] area = getArea.GetAreaOfPolyGon(points_x, points_y) min_x = min(points_x) max_x = max(points_x) min_y = min(points_y) max_y = max(points_y) box = [min_x, min_y, max_x - min_x, max_y - min_y] segmentation = get_segmenation(points_x, points_y) # make annotations info and storage it in coco_output['annotations'] ann_info = create_annotation_info(ann_id, img_id, cat_id, iscrowd, area, box, segmentation) coco_output["annotations"].append(ann_info) ann_id = ann_id + 1 if output_file_name is not None: print("Saving to {}".format(output_file_name)) with open(output_file_name, "w") as f: json.dump(coco_output, f) return coco_output
def convert(xmls): json_dict = { "images": [], "type": "instances", "annotations": [], "categories": [] } bnd_id = START_BOUNDING_BOX_ID image_id = START_IMAGE_ID # categories = ['人物', '背景', '天空', '轿车', '其他', '巴士', '狗', '马'] for i, xml in enumerate(xmls): print(i, xml) name = xml.split('/')[-1].replace('.xml', '.jpg') tree = ET.parse(xml) root = tree.getroot() size = get_and_check(root, 'size', 1) width = int(get_and_check(size, 'width', 1).text) height = int(get_and_check(size, 'height', 1).text) image = { 'file_name': name, 'height': height, 'width': width, 'id': image_id } json_dict['images'].append(image) for obj in get(root, 'object'): category = get_and_check(obj, 'name', 1).text # if category not in categories: # categories.append(category) try: category_id = CATEGORIES[category] bndbox = get_and_check(obj, 'bndbox', 1) assert len(bndbox) % 2 == 0 points = [] for i in range(len(bndbox) // 2): points.append( float( get_and_check(bndbox, 'x{}'.format(i + 1), 1).text)) points.append( float( get_and_check(bndbox, 'y{}'.format(i + 1), 1).text)) all_x, all_y = points[0::2], points[1::2] xmin, xmax = min(all_x), max(all_x) ymin, ymax = min(all_y), max(all_y) o_width = xmax - xmin o_height = ymax - ymin area = getArea.GetAreaOfPolyGon(all_x, all_y) ann = { 'image_id': image_id, 'bbox': [xmin, ymin, o_width, o_height], 'area': area, 'iscrowd': 0, 'ignore': 0, 'category_id': category_id, 'id': bnd_id, 'segmentation': [points] } json_dict['annotations'].append(ann) bnd_id += 1 except: continue image_id += 1 categories = [ { 'supercategory': 'background', 'id': 0, 'name': 'background' }, { 'supercategory': 'person', 'id': 1, 'name': 'person' }, { 'supercategory': 'dog', 'id': 3, 'name': 'dog' }, ] json_dict['catgories'] = categories return json_dict
def convert(imgdir, annpath): ''' :param imgdir: directory for your images :param annpath: path for your annotations :return: coco_output is a dictionary of coco style which you could dump it into a json file as for keywords 'info','licenses','categories',you should modify them manually ''' coco_output = {} coco_output['info'] = { "description": "Example Dataset", "url": "", "version": "1.0", "year": 2019, "contributor": "Black Jack", "date_created": datetime.datetime.utcnow().isoformat(' ') } coco_output['licenses'] = [ { "id": 1, "name": "Attribution-NonCommercial-ShareAlike License", "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/" } ] coco_output['categories'] = [ { 'id': 1, 'name': 'papercup', 'supercategory': 'rubbish', }, { 'id': 2, 'name': 'can', 'supercategory': 'rubbish', }, { 'id': 3, 'name': 'plasticbottle', 'supercategory': 'rubbish', }, { 'id': 4, 'name': 'hand', 'supercategory': 'rubbish', } ] coco_output['images'] = [] coco_output['annotations'] = [] ann = json.load(open(annpath)) # annotations id start from zero ann_id = 0 #in VIA annotations, keys are image name for img_id, key in enumerate(ann.keys()): filename = ann[key]['filename'] print(filename) img = cv2.imread(imgdir+filename) # make image info and storage it in coco_output['images'] image_info = create_image_info(img_id, os.path.basename(filename), img.shape[:2]) coco_output['images'].append(image_info) regions = ann[key]["regions"] # for one image ,there are many regions,they share the same img id for region in regions: # 这里也需要修改。原作者是region['region_attributes']['label'], # #但是其实应该是region['region_attributes']['supercategory_name'] cat = region['region_attributes']['rubbish'] #我的返回的子类的编号,所以其实不需要这一段, print(cat) assert cat in ['1', '2', '3', '4']# 如果你的返回的是子类名字。那么这一段就需要。assert cat in ['name1', 'name2', 'name3',...] if cat == '1': # if cat == 'name1': cat_id = 1 elif cat == '2': cat_id = 2 elif cat == '3': cat_id = 3 else: cat_id = 4 iscrowd = 0 points_x = region['shape_attributes']['all_points_x'] points_y = region['shape_attributes']['all_points_y'] area = getArea.GetAreaOfPolyGon(points_x, points_y) min_x = min(points_x) max_x = max(points_x) min_y = min(points_y) max_y = max(points_y) box = [min_x, min_y, max_x-min_x, max_y-min_y] # 仔细分析json分拣,VIA直接导出的COCO格式的json文件其实是不对的,使用mmdetection库进行训练时,根本不能识别出标注数据。 #其中非常明显的就是 segmentation不对。 segmentation = get_segmenation(points_x, points_y) # make annotations info and storage it in coco_output['annotations'] ann_info = create_annotation_info(ann_id, img_id, cat_id, iscrowd, area, box, segmentation) coco_output['annotations'].append(ann_info) ann_id = ann_id + 1 return coco_output