目录
xml格式转yolo格式(txt)
修改xml的name
xml格式转yolo格式(txt)
xml2yolo.py:?
"""
功能:
xml格式转为yolo(txt)格式标注,生成的文件自动放在[TxtPath]文件夹
提示:
1、将xml放在当前目录的[XmlPath]文件夹内
2、修改XmlPath、TxtPath变量为实际的路径
3、修改代码第3行的类别为数据集中包含的实际类别
"""
# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
XmlPath = './label_xml/'
TxtPath = './label_txt_test/'
classes = ["airship", "airshAip", "2", "3"] # 类别,此处需要修改为数据集中包含的实际类别
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
def mkdir(path):
folder = os.path.exists(path)
if not folder: # 判断是否存在文件夹如果不存在则创建为文件夹
os.makedirs(path) # makedirs 创建文件时如果路径不存在会创建这个路径
print("因没有输出文件夹,所以新建文件夹" + path)
def convert(size, box):
dw = 1. / size[0]
dh = 1. / size[1]
x = (box[0] + box[1]) / 2.0
y = (box[2] + box[3]) / 2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x * dw
w = w * dw
y = y * dh
h = h * dh
return (x, y, w, h)
def convert_annotation(image_id):
in_file = open(XmlPath + '%s.xml' % (image_id), encoding='UTF-8')
out_file = open(TxtPath + '%s.txt' % (image_id), 'w') # 生成txt格式文件
tree = ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
# print(w,h)
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
float(xmlbox.find('ymax').text))
bb = convert((w, h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
mkdir(TxtPath)
xml_path = os.path.join(CURRENT_DIR, XmlPath)
# xml list
img_xmls = os.listdir(xml_path)
for img_xml in img_xmls:
label_name = img_xml.split('.')[0]
print(label_name)
convert_annotation(label_name)
print("输出文件在" + TxtPath + "内")
参考链接:参考了一位博主的链接,但是忘记了,欢迎提醒
修改xml的name
ChangeXmlName.py:
"""
功能:
修改xml文件内的标注name,修改好的xml存放在[new_ann_dir]文件夹
提示:
1、修改origin_ann_dir为原始xml文件所在文件夹
2、修改new_ann_dir为新生成的xml文件夹路径
3、修改name_rename_origin为需要修改的名字
4、修改name_rename为修改的目标名字
"""
# !/usr/bin/env python2
# -*- coding: utf-8 -*-
import os
import xml.etree.ElementTree as ET
origin_ann_dir = './label_xml/' # 设置原始标签路径为 Annos
new_ann_dir = './label_xml_new_test/' # 设置新标签路径 Annotations
name_rename_origin = ["airshAip"]
name_rename = "airship"
num = 0
def mkdir(path):
folder = os.path.exists(path)
if not folder: # 判断是否存在文件夹如果不存在则创建为文件夹
os.makedirs(path) # makedirs 创建文件时如果路径不存在会创建这个路径
print("因没有输出文件夹,所以新建文件夹" + path)
mkdir(new_ann_dir)
for dirpaths, dirnames, filenames in os.walk(origin_ann_dir): # os.walk游走遍历目录名
print('开始处理')
for filename in filenames:
num += 1
print("正在处理第%d个文件:" % num)
if os.path.isfile(r'%s%s' % (origin_ann_dir, filename)): # 获取原始xml文件绝对路径,isfile()检测是否为文件 isdir检测是否为目录
origin_ann_path = os.path.join(r'%s%s' % (origin_ann_dir, filename)) # 如果是,获取绝对路径(重复代码)
new_ann_path = os.path.join(r'%s%s' % (new_ann_dir, filename))
tree = ET.parse(origin_ann_path) # ET是一个xml文件解析库,ET.parse()打开xml文件。parse--"解析"
root = tree.getroot() # 获取根节点
# print(filename)
for object in root.findall('object'): # 找到根节点下所有“object”节点
name = str(object.find('name').text) # 找到object节点下name子节点的值(字符串)
# 如果name等于str,则删除该节点
# if (name in ["car_head"]):
# root.remove(object)
# 如果name等于str,则修改name
if (name in name_rename_origin):
print("修改%s为%s" % (name, name_rename))
object.find('name').text = name_rename
# 检查是否存在labelmap中没有的类别
# for object in root.findall('object'):
# name = str(object.find('name').text)
# if not (name in ["airship", "airshAip"]):
# print(filename + "------------->label is error--->" + name)
tree.write(new_ann_path) # tree为文件,write写入新的文件中。
print("输出文件在" + new_ann_dir + "内")
参考链接:参考了一位博主的链接,但是忘记了,欢迎提醒
|