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.')