| import os |
| import xml.etree.ElementTree as ET |
| from shutil import move |
| from PIL import Image |
|
|
| def yolo_to_voc(yolo_label_folder, images_folder, voc_output_folder): |
| |
| if not os.path.exists(voc_output_folder): |
| os.makedirs(voc_output_folder) |
| |
| |
| yolo_labels = [f for f in os.listdir(yolo_label_folder) if f.endswith('.txt')] |
| image_files = [f for f in os.listdir(images_folder) if f.endswith(('.jpg', '.png', '.jpeg'))] |
|
|
| |
| image_files_set = {os.path.splitext(f)[0] for f in image_files} |
|
|
| for label_file in yolo_labels: |
| label_name = os.path.splitext(label_file)[0] |
| label_path = os.path.join(yolo_label_folder, label_file) |
| |
| |
| if label_name not in image_files_set: |
| os.remove(label_path) |
| print(f'Removed label file: {label_file}') |
| continue |
|
|
| |
| voc_xml_path = os.path.join(voc_output_folder, label_name + '.xml') |
|
|
| with open(label_path, 'r') as f: |
| lines = f.readlines() |
|
|
| |
| image_file_path = os.path.join(images_folder, label_name + '.jpg') |
| if not os.path.exists(image_file_path): |
| image_file_path = os.path.join(images_folder, label_name + '.png') |
|
|
| image = Image.open(image_file_path) |
| width, height = image.size |
| |
| |
| annotation = ET.Element('annotation') |
| ET.SubElement(annotation, 'folder').text = images_folder |
| ET.SubElement(annotation, 'filename').text = label_name + '.jpg' |
| ET.SubElement(annotation, 'path').text = image_file_path |
|
|
| source = ET.SubElement(annotation, 'source') |
| ET.SubElement(source, 'database').text = 'Unknown' |
|
|
| size = ET.SubElement(annotation, 'size') |
| ET.SubElement(size, 'width').text = str(width) |
| ET.SubElement(size, 'height').text = str(height) |
| ET.SubElement(size, 'depth').text = '3' |
|
|
| ET.SubElement(annotation, 'segmented').text = '0' |
|
|
| |
| for line in lines: |
| parts = line.strip().split() |
| class_id = int(parts[0]) |
| xmin = float(parts[1]) * width |
| ymin = float(parts[2]) * height |
| xmax = float(parts[3]) * width |
| ymax = float(parts[4]) * height |
| |
| obj = ET.SubElement(annotation, 'object') |
| ET.SubElement(obj, 'name').text = str(class_id) |
| ET.SubElement(obj, 'pose').text = 'Unspecified' |
| ET.SubElement(obj, 'truncated').text = '0' |
| ET.SubElement(obj, 'difficult').text = '0' |
|
|
| bndbox = ET.SubElement(obj, 'bndbox') |
| ET.SubElement(bndbox, 'xmin').text = str(int(xmin)) |
| ET.SubElement(bndbox, 'ymin').text = str(int(ymin)) |
| ET.SubElement(bndbox, 'xmax').text = str(int(xmax)) |
| ET.SubElement(bndbox, 'ymax').text = str(int(ymax)) |
|
|
| |
| tree = ET.ElementTree(annotation) |
| tree.write(voc_xml_path) |
| print(f'Converted {label_file} to VOC format and saved as {voc_xml_path}') |
|
|
| |
| yolo_label_folder = '/home/lab/LJ/wampee/WampeeDataSets/train/labels' |
| images_folder = '/home/lab/LJ/wampee/WampeeDataSets/train/images' |
| voc_output_folder = '/home/lab/LJ/wampee/Wampee_datasets_Voc' |
|
|
| yolo_to_voc(yolo_label_folder, images_folder, voc_output_folder) |
|
|