YOLO目标检测—XML标签文件与TXT标签文件相互转换

XML标签文件转换为TXT标签文件

import os
import xml.etree.ElementTree as ET

# 类别编号和名称的映射
class_mapping = {       # 替换为自己的类别编号和名称映射
    'person': '0',
    'car': '1',
    'bike': '2'
}

# 更新后的源文件夹和目标文件夹路径
source_folder = r'F:\data\xml'      # 替换为需要转换为txt的xml文件的路径
target_folder = r'F:\data\txt'      # 替换为txt文件的保存路径

# 确保目标文件夹存在
os.makedirs(target_folder, exist_ok=True)

# 初始化图像宽度和高度变量
image_width = 0
image_height = 0

# 遍历源文件夹中的所有XML文件
for xml_file in os.listdir(source_folder):
    if xml_file.endswith('.xml'):
        # 构建完整的文件路径
        xml_path = os.path.join(source_folder, xml_file)
        
        # 解析XML文件
        tree = ET.parse(xml_path)
        root = tree.getroot()
        
        # 获取图像尺寸
        size = root.find('size')
        if size is not None:
            width = int(size.find('width').text)
            height = int(size.find('height').text)
            # 更新图像宽度和高度
            image_width = max(image_width, width)
            image_height = max(image_height, height)
        
        # 创建TXT文件名
        txt_file_name = xml_file.replace('.xml', '.txt')
        txt_file_path = os.path.join(target_folder, txt_file_name)
        
        # 写入TXT文件
        with open(txt_file_path, 'w') as txt_file:
            # 遍历所有对象
            for obj in root.findall('object'):
                # 获取类别编号
                name = obj.find('name').text
                category_id = class_mapping.get(name, None)
                if category_id is None:
                    continue  # 如果类别名称不在映射中,则跳过
                
                # 获取边界框坐标
                bndbox = obj.find('bndbox')
                xmin = float(bndbox.find('xmin').text)
                ymin = float(bndbox.find('ymin').text)
                xmax = float(bndbox.find('xmax').text)
                ymax = float(bndbox.find('ymax').text)
                
                # 计算中心坐标 (x_center, y_center) 和宽高 (width, height)
                x_center = (xmin + xmax) / 2
                y_center = (ymin + ymax) / 2
                width = xmax - xmin
                height = ymax - ymin
                
                # 归一化中心坐标和宽高
                normalized_x_center = x_center / image_width
                normalized_y_center = y_center / image_height
                normalized_width = width / image_width
                normalized_height = height / image_height
                
                # 写入对象信息,格式为类别编号 x_center y_center width height
                txt_file.write(f'{category_id} {normalized_x_center} {normalized_y_center} {normalized_width} {normalized_height}\n')

## 打印完成信息
print('Conversion from XML to TXT completed.')

TXT标签文件转换为XML标签文件

import os
import xml.etree.ElementTree as ET
from PIL import Image

# 类别编号和名称的映射
class_mapping = {       # 替换为自己的类别编号和名称的映射
    '0': 'person',
    '1': 'car',
    '2': 'bike'
}

# 源文件夹和目标文件夹路径
source_folder = r'F:\data\txt'      # 替换为存放txt标签的文件夹路径
target_folder = r'F:\data\xml'      # 替换为保存xml文件的文件夹路径
image_folder = r'F:\data\images'    # 替换为存放图片的文件夹路径

# 确保目标文件夹存在
os.makedirs(target_folder, exist_ok=True)

# 遍历源文件夹中的所有TXT文件
for txt_file in os.listdir(source_folder):
    if txt_file.endswith('.txt'):
        # 构建完整的文件路径
        txt_path = os.path.join(source_folder, txt_file)
        
        # 创建XML文件名
        xml_file_name = txt_file.replace('.txt', '.xml')
        xml_file_path = os.path.join(target_folder, xml_file_name)
        
        # 获取图像文件名(假设图像文件和TXT文件同名)
        image_file_name = txt_file.replace('.txt', '.png')  # 图像文件是PNG格式
        image_path = os.path.join(image_folder, image_file_name)
        
        # 检查图像文件是否存在
        if not os.path.exists(image_path):
            print(f"Image file not found: {image_path}")
            continue
        
        # 使用PIL库获取图像尺寸
        with Image.open(image_path) as img:
            image_width, image_height = img.size
        
        # 解析TXT文件并创建XML结构
        with open(txt_path, 'r') as txt_file:
            tree = ET.ElementTree(ET.Element('annotation'))
            root = tree.getroot()
            
            # 添加folder, filename, path元素
            folder = ET.SubElement(root, 'folder')
            folder.text = os.path.basename(os.path.dirname(image_path))  # 获取图片所在的文件夹名称
            filename = ET.SubElement(root, 'filename')
            filename.text = image_file_name
            path = ET.SubElement(root, 'path')
            path.text = os.path.abspath(image_path)  # 获取图片的绝对路径
            
            # 添加source元素
            source = ET.SubElement(root, 'source')
            database = ET.SubElement(source, 'database')
            database.text = 'Unknown'
            
            # 添加size元素
            size = ET.SubElement(root, 'size')
            width = ET.SubElement(size, 'width')
            width.text = str(image_width)
            height = ET.SubElement(size, 'height')
            height.text = str(image_height)
            depth = ET.SubElement(size, 'depth')
            depth.text = '1'
            
            # 添加segmented元素
            segmented = ET.SubElement(root, 'segmented')
            segmented.text = '0'
            
            # 遍历TXT文件中的每一行
            for line in txt_file:
                values = line.strip().split()
                category_id = values[0]
                x_center = float(values[1]) * image_width
                y_center = float(values[2]) * image_height
                bbox_width = float(values[3]) * image_width
                bbox_height = float(values[4]) * image_height
                
                # 创建object元素
                obj = ET.SubElement(root, 'object')
                name = ET.SubElement(obj, 'name')
                name.text = class_mapping[category_id]
                pose = ET.SubElement(obj, 'pose')
                pose.text = 'Unspecified'
                truncated = ET.SubElement(obj, 'truncated')
                truncated.text = '0'
                difficult = ET.SubElement(obj, 'difficult')
                difficult.text = '0'
                
                # 创建bounding_box元素
                bndbox = ET.SubElement(obj, 'bndbox')
                xmin = ET.SubElement(bndbox, 'xmin')
                xmin.text = str(int(x_center - bbox_width / 2))
                ymin = ET.SubElement(bndbox, 'ymin')
                ymin.text = str(int(y_center - bbox_height / 2))
                xmax = ET.SubElement(bndbox, 'xmax')
                xmax.text = str(int(x_center + bbox_width / 2))
                ymax = ET.SubElement(bndbox, 'ymax')
                ymax.text = str(int(y_center + bbox_height / 2))
            
            # 保存XML文件
            tree.write(xml_file_path, encoding='utf-8', xml_declaration=True)

# 打印完成信息
print('Conversion from TXT to XML completed.')
posted @ 2024-12-23 14:38  顾北清  阅读(20)  评论(0编辑  收藏  举报