一、正矩形框
1、xml的第一种格式为:
<annotation><source><filename>1501.tif</filename><origin>SAR</origin></source><research><version>1.0</version><author>team name</author><pluginclass>Detection</pluginclass><time>2021-07-2021-11</time></research><size><width>1024</width><height>1024</height></size><objects><object><coordinate>pixel</coordinate><type>rectangle</type><description>None</description><possibleresult><name>ARJ21</name><probability>1</probability></possibleresult><points><point>396.000000,719.000000</point><point>447.000000,719.000000</point><point>447.000000,765.000000</point><point>396.000000,765.000000</point><point>396.000000,719.000000</point></points></object></objects>
</annotation>
对应的python代码如下:
import xml.etree.ElementTree as ET
import osclass_names = ['A220', 'A330', 'A320/321', 'Boeing737-800', 'Boeing787', 'ARJ21', 'other']
xmlpath = 'E:/plane/sar/xmllabels/' # 原xml路径
txtpath = 'E:/plane/sar/txtlabels/' # 转换后txt文件存放路径
if not os.path.exists(txtpath):os.makedirs(txtpath)
files = []for root, dirs, files in os.walk(xmlpath):Nonenumber = len(files)
print("文件数为", number)
i = 0
while i < number:name = files[i][0:-4]xml_name = name + ".xml"txt_name = name + ".txt"xml_file_name = xmlpath + xml_nametxt_file_name = txtpath + txt_namexml_file = open(xml_file_name)tree = ET.parse(xml_file)root = tree.getroot()source = root.find("source")filename = source.find('filename').text# 图片名称image_name = source.find('filename').textw = int(root.find('size').find('width').text)h = int(root.find('size').find('height').text)f_txt = open(txt_file_name, 'w+')content = ""first = Truefor obj in root.find("objects").iter('object'):# 分类名称name = obj.find("possibleresult").find('name').text# 分类编号class_num = class_names.index(name)points = obj.find('points')# 获取第一个和第三个point元素的值first_point = points.findall('point')[0].textthird_point = points.findall('point')[2].text# 将点的值解析为浮点数列表first_point_values = list(map(float, first_point.split(',')))third_point_values = list(map(float, third_point.split(',')))# 打印结果print(int(first_point_values[0]), first_point_values[1], third_point_values[0], third_point_values[1])# 左上角点x坐标x1 = int(first_point_values[0])# 右下角点x坐标x2 = int(third_point_values[0])# 左上角点y坐标y1 = int(first_point_values[1])# 右下角点y坐标y2 = int(third_point_values[1])if first:content += str(class_num) + " " + \str((x1 + x2) / 2 / w) + " " + str((y1 + y2) / 2 / h) + " " + \str((x2 - x1) / w) + " " + str((y2 - y1) / h)first = Falseelse:content += "\n" + \str(class_num) + " " + \str((x1 + x2) / 2 / w) + " " + str((y1 + y2) / 2 / h) + " " + \str((x2 - x1) / w) + " " + str((y2 - y1) / h)# print(str(i / (number - 1) * 100) + "%\n")print(content)f_txt.write(content)f_txt.close()xml_file.close()i += 1print("done!")
2、xml的第二种格式为:
<annotation><folder>PCB</folder><filename>l_light_01_missing_hole_01_1_600</filename><source><database>My Database</database><annotation>PCB</annotation><image>flickr</image><flickrid>NULL</flickrid></source><owner><flickrid>NULL</flickrid><name>idaneel</name></owner><size><width>600</width><height>600</height><depth>3</depth></size><segmented>0</segmented><object><name>missing_hole</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>240</xmin><ymin>404</ymin><xmax>282</xmax><ymax>437</ymax></bndbox></object>
</annotation>
对应的python代码为:
import os.path
import xml.etree.ElementTree as ET
import os
import random
# class_names = ['palm', 'stone', 'scissor', 'awesome', 'heartB', 'OK', 'ROCK', 'one', 'swear', 'thanks', 'heartA',
# 'heartC', 'good', 'bad', 'pray', 'call', 'take_picture', 'salute']
class_names = ['menopause', 'hairball', 'broken yarn', 'hole','stains']
xmlpath = 'F:/Project_code/yolov7-main/VOCdevkit/VOC2007/Annotations/' # 原xml路径
txtpath = 'F:/Project_code/yolov7-main/VOCdevkit/VOC2007/labels_copy/' # 转换后txt文件存放路径
if not os.path.exists(txtpath):os.makedirs(txtpath)
files = []for root, dirs, files in os.walk(xmlpath):Nonenumber = len(files)
print(number)
i = 0
while i < number:name = files[i][0:-4]xml_name = name + ".xml"txt_name = name + ".txt"xml_file_name = xmlpath + xml_nametxt_file_name = txtpath + txt_namexml_file = open(xml_file_name)tree = ET.parse(xml_file)root = tree.getroot()filename = root.find('filename').textimage_name = root.find('filename').textw = int(root.find('size').find('width').text)h = int(root.find('size').find('height').text)f_txt = open(txt_file_name, 'w+')content = ""first = Truefor obj in root.iter('object'):name = obj.find('name').textclass_num = class_names.index(name)xmlbox = obj.find('bndbox')x1 = int(xmlbox.find('xmin').text)x2 = int(xmlbox.find('xmax').text)y1 = int(xmlbox.find('ymin').text)y2 = int(xmlbox.find('ymax').text)if first:content += str(class_num) + " " + \str((x1 + x2) / 2 / w) + " " + str((y1 + y2) / 2 / h) + " " + \str((x2 - x1) / w) + " " + str((y2 - y1) / h)first = Falseelse:content += "\n" + \str(class_num) + " " + \str((x1 + x2) / 2 / w) + " " + str((y1 + y2) / 2 / h) + " " + \str((x2 - x1) / w) + " " + str((y2 - y1) / h)# print(str(i / (number - 1) * 100) + "%\n")print(content)f_txt.write(content)f_txt.close()xml_file.close()i += 1print("done!")
二、斜矩形框
<object><coordinate>pixel</coordinate><type>rectangle</type><description>None</description><possibleresult><name>A220</name></possibleresult><points><point>316.000000,544.000000</point><point>281.000000,575.000000</point><point>250.000000,540.000000</point><point>285.000000,509.000000</point><point>316.000000,544.000000</point></points>
</object>
1、先将xml格式转化为dota数据集格式
import os
import xml.etree.ElementTree as ET# 定义一个函数来处理单个 XML 文件
def convert_xml_to_txt(xml_file, txt_file):# 解析 XML 文件tree = ET.parse(xml_file)root = tree.getroot()# 打开一个 txt 文件用于存储结果with open(txt_file, 'w') as f:# 遍历 XML 文件中的每个对象for obj in root.findall('.//object'):# 获取对象的名称name = obj.find('possibleresult/name').text# 获取对象的前四个点坐标,并将它们转换为整数points = obj.find('points')point_values = []for i in range(4):point = points.findall('point')[i].text.split(',')point_values.extend([int(float(p)) for p in point])# 将整数坐标值、名称和0写入 txt 文件f.write(f'{" ".join(map(str, point_values))} {name} 0\n')# 定义要处理的文件夹路径和目标文件夹路径
source_folder_path = './xml_labels' # 替换为你的源文件夹路径
target_folder_path = './txt_labels' # 替换为你的目标文件夹路径# 遍历源文件夹中的所有 XML 文件,并将每个文件转换为 TXT 文件保存到目标文件夹中
for filename in os.listdir(source_folder_path):if filename.endswith('.xml'):# 获取 XML 文件的完整路径xml_file = os.path.join(source_folder_path, filename)# 获取目标 TXT 文件的完整路径,并确保文件名一致txt_file = os.path.join(target_folder_path, filename.replace('.xml', '.txt'))# 调用函数将 XML 文件转换为 TXT 文件convert_xml_to_txt(xml_file, txt_file)
2、再通过以下文章中代码修改
全网首发!Yolov8_obb旋转框训练、测试、推理手把手教学(DOTA1.0数据集map50已达80%)