import os
import xml.etree.ElementTree as ET
import json
def parse_voc_xml(xml_file):
tree = ET.parse(xml_file)
root = tree.getroot()
objects = []
for obj in root.findall('object'):
name = obj.find('name').text
bndbox = obj.find('bndbox')
xmin = int(bndbox.find('xmin').text)
ymin = int(bndbox.find('ymin').text)
xmax = int(bndbox.find('xmax').text)
ymax = int(bndbox.find('ymax').text)
objects.append({
"label": name,
"bbox": [xmin, ymin, xmax, ymax]
})
return objects
def convert_to_label_studio_json(image_path, voc_objects):
label_studio_data = {
"image": image_path,
"predictions": []
}
for obj in voc_objects:
label_studio_data["predictions"].append({
"result": [{
"from_name": "label",
"to_name": "image",
"type": "rectanglelabels",
"value": {
"x": obj["bbox"][0],
"y": obj["bbox"][1],
"width": obj["bbox"][2] - obj["bbox"][0],
"height": obj["bbox"][3] - obj["bbox"][1],
"rectanglelabels": [obj["label"]]
}
}]
})
return label_studio_data
def convert_voc_to_label_studio(voc_dir, image_dir, output_json):
result = []
for xml_file in os.listdir(voc_dir):
if xml_file.endswith('.xml'):
xml_path = os.path.join(voc_dir, xml_file)
voc_objects = parse_voc_xml(xml_path)
image_file = xml_file.replace('.xml', '.jpg')
image_path = os.path.join(image_dir, image_file)
label_studio_data = convert_to_label_studio_json(image_path, voc_objects)
result.append(label_studio_data)
with open(output_json, 'w') as f:
json.dump(result, f, indent=4)
print(f"Conversion complete. JSON saved to {output_json}")
# Example usage
voc_directory = "/path/to/voc/xmls"
image_directory = "/path/to/images"
output_json_file = "/path/to/output/label_studio_predictions.json"
convert_voc_to_label_studio(voc_directory, image_directory, output_json_file)