in utils_cv/detection/references/anno_coco2voc.py [0:0]
def parse_instance(content, outdir, download_images = False):
categories = {d['id']: d['name'] for d in content['categories']}
# EDITED - make sure image_id is of type int (and not of type string)
for i in range(len(content['annotations'])):
content['annotations'][i]['image_id'] = int(content['annotations'][i]['image_id'])
# EDITED - save all annotation .xml files into same sub-directory
anno_dir = os.path.join(outdir, "annotations")
if not os.path.exists(anno_dir):
os.makedirs(anno_dir)
# EDITED - download images
if download_images:
im_dir = os.path.join(outdir, "images")
if not os.path.exists(im_dir):
os.makedirs(im_dir)
for index, obj in enumerate(content['images']):
print(f"Downloading image {index} of {len(content['images'])} from: {obj['coco_url']}")
# Update 'filename' field to be a (local) filename and not a url
im_local_filename = os.path.splitext(os.path.basename(obj['file_name']))[0] + ".jpg"
obj['file_name'] = im_local_filename
# download image
dst_path = os.path.join(im_dir, im_local_filename)
urllib.request.urlretrieve(obj['coco_url'], dst_path)
# merge images and annotations: id in images vs image_id in annotations
merged_info_list = list(map(cytoolz.merge, cytoolz.join('id', content['images'], 'image_id', content['annotations'])))
# convert category id to name
for instance in merged_info_list:
assert 'category_id' in instance, f"WARNING: annotation error: image {instance['file_name']} has a rectangle without a 'category_id' field."
instance['category_id'] = categories[instance['category_id']]
# group by filename to pool all bbox in same file
img_filenames = {}
names_groups = cytoolz.groupby('file_name', merged_info_list).items()
for index, (name, groups) in enumerate(names_groups):
print(f"Converting annotations for image {index} of {len(names_groups)}: {name}")
assert not name.lower().startswith(("http:","https:")), "Image seems to be a url rather than local. Need to set 'download_images' = False"
anno_tree = instance2xml_base(groups[0], download_images)
# if one file have multiple different objects, save it in each category sub-directory
filenames = []
for group in groups:
filename = os.path.splitext(name)[0] + ".xml"
# EDITED - save all annotations in single folder, rather than separate folders for each object
#filenames.append(os.path.join(outdir, re.sub(" ", "_", group['category_id']), filename))
filenames.append(os.path.join(anno_dir, filename))
anno_tree.append(instance2xml_bbox(group, bbox_type='xyxy'))
for filename in filenames:
etree.ElementTree(anno_tree).write(filename, pretty_print=True)