Download tools/Yolo2Voc.py from voidljc/cherrydata: direct link, hf CLI and curl.
- Browser
- Download file 3.89 kB
-
https://huggingface.co/voidljc/cherrydata/resolve/main/tools/Yolo2Voc.py
- Command line
-
hf download hf://voidljc/cherrydata/tools/Yolo2Voc.py
-
curl -L -o Yolo2Voc.py https://huggingface.co/voidljc/cherrydata/resolve/main/tools/Yolo2Voc.py
3.89 kB
| 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 # 跳过这个标签文件 | |
| # 转换YOLO格式标签为VOC格式 | |
| 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') # 假设图片是.jpg格式 | |
| if not os.path.exists(image_file_path): # 如果是PNG或其他格式,也可以扩展检查 | |
| image_file_path = os.path.join(images_folder, label_name + '.png') | |
| image = Image.open(image_file_path) | |
| width, height = image.size | |
| # 创建VOC XML文件 | |
| 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' # 假设图片是RGB三通道 | |
| ET.SubElement(annotation, 'segmented').text = '0' | |
| # 对应每个标签进行转换 | |
| for line in lines: | |
| parts = line.strip().split() | |
| class_id = int(parts[0]) # 类别ID | |
| 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)) | |
| # 保存VOC格式的XML文件 | |
| 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) | |