-
-
Save goodhamgupta/7ca514458d24af980669b8b1c8bcdafd to your computer and use it in GitHub Desktop.
# Script to convert yolo annotations to voc format | |
# Sample format | |
# <annotation> | |
# <folder>_image_fashion</folder> | |
# <filename>brooke-cagle-39574.jpg</filename> | |
# <size> | |
# <width>1200</width> | |
# <height>800</height> | |
# <depth>3</depth> | |
# </size> | |
# <segmented>0</segmented> | |
# <object> | |
# <name>head</name> | |
# <pose>Unspecified</pose> | |
# <truncated>0</truncated> | |
# <difficult>0</difficult> | |
# <bndbox> | |
# <xmin>549</xmin> | |
# <ymin>251</ymin> | |
# <xmax>625</xmax> | |
# <ymax>335</ymax> | |
# </bndbox> | |
# </object> | |
# <annotation> | |
import os | |
import xml.etree.cElementTree as ET | |
from PIL import Image | |
ANNOTATIONS_DIR_PREFIX = "annotations" | |
DESTINATION_DIR = "converted_labels" | |
CLASS_MAPPING = { | |
'0': 'name' | |
# Add your remaining classes here. | |
} | |
def create_root(file_prefix, width, height): | |
root = ET.Element("annotations") | |
ET.SubElement(root, "filename").text = "{}.jpg".format(file_prefix) | |
ET.SubElement(root, "folder").text = "images" | |
size = ET.SubElement(root, "size") | |
ET.SubElement(size, "width").text = str(width) | |
ET.SubElement(size, "height").text = str(height) | |
ET.SubElement(size, "depth").text = "3" | |
return root | |
def create_object_annotation(root, voc_labels): | |
for voc_label in voc_labels: | |
obj = ET.SubElement(root, "object") | |
ET.SubElement(obj, "name").text = voc_label[0] | |
ET.SubElement(obj, "pose").text = "Unspecified" | |
ET.SubElement(obj, "truncated").text = str(0) | |
ET.SubElement(obj, "difficult").text = str(0) | |
bbox = ET.SubElement(obj, "bndbox") | |
ET.SubElement(bbox, "xmin").text = str(voc_label[1]) | |
ET.SubElement(bbox, "ymin").text = str(voc_label[2]) | |
ET.SubElement(bbox, "xmax").text = str(voc_label[3]) | |
ET.SubElement(bbox, "ymax").text = str(voc_label[4]) | |
return root | |
def create_file(file_prefix, width, height, voc_labels): | |
root = create_root(file_prefix, width, height) | |
root = create_object_annotation(root, voc_labels) | |
tree = ET.ElementTree(root) | |
tree.write("{}/{}.xml".format(DESTINATION_DIR, file_prefix)) | |
def read_file(file_path): | |
file_prefix = file_path.split(".txt")[0] | |
image_file_name = "{}.jpg".format(file_prefix) | |
img = Image.open("{}/{}".format("images", image_file_name)) | |
w, h = img.size | |
with open(file_path, 'r') as file: | |
lines = file.readlines() | |
voc_labels = [] | |
for line in lines: | |
voc = [] | |
line = line.strip() | |
data = line.split() | |
voc.append(CLASS_MAPPING.get(data[0])) | |
bbox_width = float(data[3]) * w | |
bbox_height = float(data[4]) * h | |
center_x = float(data[1]) * w | |
center_y = float(data[2]) * h | |
voc.append(center_x - (bbox_width / 2)) | |
voc.append(center_y - (bbox_height / 2)) | |
voc.append(center_x + (bbox_width / 2)) | |
voc.append(center_y + (bbox_height / 2)) | |
voc_labels.append(voc) | |
create_file(file_prefix, w, h, voc_labels) | |
print("Processing complete for file: {}".format(file_path)) | |
def start(dir_name): | |
if not os.path.exists(DESTINATION_DIR): | |
os.makedirs(DESTINATION_DIR) | |
for filename in os.listdir(ANNOTATIONS_DIR_PREFIX): | |
if filename.endswith('txt'): | |
read_file(filename) | |
else: | |
print("Skipping file: {}".format(filename)) | |
if __name__ == "__main__": | |
start() |
hello. Just change the Annotations_dir_prefix and DESTINATION_DIR files and your code will run perfectly given that YOU HAVE THE ANNOTATIONS AND IMAGES IN THE SAME FOLDER.
`import os
import xml.etree.cElementTree as ET
from PIL import Image
ANNOTATIONS_DIR_PREFIX = "C:/Users/Murtaza Kazmi/Folder/"
DESTINATION_DIR = "C:/Users/Murtaza Kazmi/Corrected_Annotations_to_XML/"
CLASS_MAPPING = {
'0': '0',
'1':'1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6':'6',
'7':'7',
'8':'8',
'9':'9',
# Add your remaining classes here.
}
def create_root(file_prefix, width, height):
root = ET.Element("annotations")
ET.SubElement(root, "filename").text = "{}.jpg".format(file_prefix)
ET.SubElement(root, "folder").text = "images"
size = ET.SubElement(root, "size")
ET.SubElement(size, "width").text = str(width)
ET.SubElement(size, "height").text = str(height)
ET.SubElement(size, "depth").text = "3"
return root
def create_object_annotation(root, voc_labels):
for voc_label in voc_labels:
obj = ET.SubElement(root, "object")
ET.SubElement(obj, "name").text = voc_label[0]
ET.SubElement(obj, "pose").text = "Unspecified"
ET.SubElement(obj, "truncated").text = str(0)
ET.SubElement(obj, "difficult").text = str(0)
bbox = ET.SubElement(obj, "bndbox")
ET.SubElement(bbox, "xmin").text = str(voc_label[1])
ET.SubElement(bbox, "ymin").text = str(voc_label[2])
ET.SubElement(bbox, "xmax").text = str(voc_label[3])
ET.SubElement(bbox, "ymax").text = str(voc_label[4])
return root
def create_file(file_prefix, width, height, voc_labels):
root = create_root(file_prefix, width, height)
root = create_object_annotation(root, voc_labels)
tree = ET.ElementTree(root)
tree.write("{}/{}.xml".format(DESTINATION_DIR, file_prefix))
def read_file(file_path):
file_prefix = file_path.split(".txt")[0]
image_file_name = "{}.jpg".format(file_prefix)
img = Image.open(image_file_name)
w, h = img.size
print(file_path, '101')
with open(ANNOTATIONS_DIR_PREFIX + file_path, 'r') as file:
lines = file.readlines()
voc_labels = []
for line in lines:
voc = []
line = line.strip()
data = line.split()
voc.append(CLASS_MAPPING.get(data[0]))
bbox_width = float(data[3]) * w
bbox_height = float(data[4]) * h
center_x = float(data[1]) * w
center_y = float(data[2]) * h
voc.append(center_x - (bbox_width / 2))
voc.append(center_y - (bbox_height / 2))
voc.append(center_x + (bbox_width / 2))
voc.append(center_y + (bbox_height / 2))
voc_labels.append(voc)
create_file(file_prefix, w, h, voc_labels)
print("Processing complete for file: {}".format(file_path))
def start():
if not os.path.exists(DESTINATION_DIR):
os.makedirs(DESTINATION_DIR)
for filename in os.listdir(ANNOTATIONS_DIR_PREFIX):
if filename.endswith('txt'):
read_file(filename)
else:
print("Skipping file: {}".format(filename))
if name == "main":
start()
`
this code works
import os
from xml.dom import minidom
import xml.etree.cElementTree as ET
from PIL import Image
ANNOTATIONS_DIR_PREFIX = "path to your yolo annotations"
DESTINATION_DIR = "output path"
CLASS_MAPPING = {
'1': 'Char'
}
def formatter(elem):
"""Return a pretty-printed XML string for the Element.
"""
rough_string = ET.tostring(elem, 'utf-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=" ")
def create_root(file_prefix, width, height):
root = ET.Element("annotation")
ET.SubElement(root, "filename").text = "{}.jpg".format(file_prefix)
size = ET.SubElement(root, "size")
ET.SubElement(size, "width").text = str(width)
ET.SubElement(size, "height").text = str(height)
ET.SubElement(size, "depth").text = "3"
return root
def create_object_annotation(root, voc_labels):
for voc_label in voc_labels:
obj = ET.SubElement(root, "object")
ET.SubElement(obj, "name").text = voc_label[0]
bbox = ET.SubElement(obj, "bndbox")
ET.SubElement(bbox, "xmin").text = str(voc_label[1])
ET.SubElement(bbox, "ymin").text = str(voc_label[2])
ET.SubElement(bbox, "xmax").text = str(voc_label[3])
ET.SubElement(bbox, "ymax").text = str(voc_label[4])
return root
def create_file(file_prefix, width, height, voc_labels):
root = create_root(file_prefix, width, height)
root = create_object_annotation(root, voc_labels)
with open("{}/{}.xml".format(DESTINATION_DIR, file_prefix), "w") as f:
f.write(formatter(root))
f.close()
def read_file(file_path):
file_prefix = file_path.split(".txt")[0]
image_file_name = "{}.jpg".format(file_prefix)
img = Image.open("{}/{}".format("sites", image_file_name))
w, h = img.size
with open("labels/"+file_path, 'r') as file:
lines = file.readlines()
voc_labels = []
for line in lines:
voc = []
line = line.strip()
data = line.split()
voc.append(CLASS_MAPPING.get(data[0]))
bbox_width = float(data[3]) * w
bbox_height = float(data[4]) * h
center_x = float(data[1]) * w
center_y = float(data[2]) * h
voc.append(round(center_x - (bbox_width / 2)))
voc.append(round(center_y - (bbox_height / 2)))
voc.append(round(center_x + (bbox_width / 2)))
voc.append(round(center_y + (bbox_height / 2)))
voc_labels.append(voc)
create_file(file_prefix, w, h, voc_labels)
def start():
if not os.path.exists(DESTINATION_DIR):
os.makedirs(DESTINATION_DIR)
for filename in os.listdir(ANNOTATIONS_DIR_PREFIX):
if filename.endswith('txt'):
read_file(filename)
else:
print("Skipping file: {}".format(filename))
if __name__ == "__main__":
start()
Thanks @goodhamgupta @mjahanifar