xml转txt,划分数据集(train、test、val)

python 复制代码
import os
import random


trainval_percent = 0.2
train_percent = 0.8
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
ftrainval = open('ImageSets/trainval.txt', 'w')
ftest = open('ImageSets/test.txt', 'w')
ftrain = open('ImageSets/train.txt', 'w')
fval = open('ImageSets/val.txt', 'w')

for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftest.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
python 复制代码
# xml解析包
import xml.etree.ElementTree as ET
import pickle
import os
# os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表
from os import listdir, getcwd
from os.path import join


sets = ['train', 'test', 'val']
classes = [ 'overflow','garbage_bin', 'garbage']


# 进行归一化操作
def convert(size, box): # size:(原图w,原图h) , box:(xmin,xmax,ymin,ymax)
    dw = 1./size[0]     # 1/w
    dh = 1./size[1]     # 1/h
    x = (box[0] + box[1])/2.0   # 物体在图中的中心点x坐标
    y = (box[2] + box[3])/2.0   # 物体在图中的中心点y坐标
    w = box[1] - box[0]         # 物体实际像素宽度
    h = box[3] - box[2]         # 物体实际像素高度
    x = x*dw    # 物体中心点x的坐标比(相当于 x/原图w)
    w = w*dw    # 物体宽度的宽度比(相当于 w/原图w)
    y = y*dh    # 物体中心点y的坐标比(相当于 y/原图h)
    h = h*dh    # 物体宽度的宽度比(相当于 h/原图h)
    return (x, y, w, h)    # 返回 相对于原图的物体中心点的x坐标比,y坐标比,宽度比,高度比,取值范围[0-1]


# year ='2012', 对应图片的id(文件名)
def convert_annotation(image_id):
    '''
    将对应文件名的xml文件转化为label文件,xml文件包含了对应的bunding框以及图片长款大小等信息,
    通过对其解析,然后进行归一化最终读到label文件中去,也就是说
    一张图片文件对应一个xml文件,然后通过解析和归一化,能够将对应的信息保存到唯一一个label文件中去
    labal文件中的格式:calss x y w h  同时,一张图片对应的类别有多个,所以对应的bunding的信息也有多个
    '''
    # 对应的通过year 找到相应的文件夹,并且打开相应image_id的xml文件,其对应bund文件
    in_file = open('Annotations/%s.xml' % (image_id), encoding='utf-8')
    # print(in_file.name)
    # 准备在对应的image_id 中写入对应的label,分别为
    # <object-class> <x> <y> <width> <height>
    out_file = open('labels/%s.txt' % (image_id), 'w', encoding='utf-8')
    # print(out_file.name)
    # 解析xml文件
    tree = ET.parse(in_file)
    # 获得对应的键值对
    root = tree.getroot()
    # 获得图片的尺寸大小
    size = root.find('size')
    # 获得宽
    w = int(size.find('width').text)
    # 获得高
    h = int(size.find('height').text)
    # 遍历目标obj
    for obj in root.iter('object'):
        # 获得difficult ??
        difficult = obj.find('difficult').text
        # 获得类别 =string 类型
        cls = obj.find('name').text
        # 如果类别不是对应在我们预定好的class文件中,或difficult==1则跳过
        if cls not in classes or int(difficult) == 1:
            continue
        # 通过类别名称找到id
        cls_id = classes.index(cls)
        # 找到bndbox 对象
        xmlbox = obj.find('bndbox')
        # 获取对应的bndbox的数组 = ['xmin','xmax','ymin','ymax']
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        print(image_id, cls, b)
        # 带入进行归一化操作
        # w = 宽, h = 高, b= bndbox的数组 = ['xmin','xmax','ymin','ymax']
        bb = convert((w, h), b)
        # bb 对应的是归一化后的(x,y,w,h)
        # 生成 calss x y w h 在label文件中
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


# 返回当前工作目录
wd = getcwd()
print(wd)


for image_set in sets:
    '''
    对所有的文件数据集进行遍历
    做了两个工作:
    1.讲所有图片文件都遍历一遍,并且将其所有的全路径都写在对应的txt文件中去,方便定位
    2.同时对所有的图片文件进行解析和转化,将其对应的bundingbox 以及类别的信息全部解析写到label 文件中去
         最后再通过直接读取文件,就能找到对应的label 信息
    '''
    # 先找labels文件夹如果不存在则创建
    if not os.path.exists('labels/'):
        os.makedirs('labels/')
    # 读取在ImageSets/Main 中的train、test..等文件的内容
    # 包含对应的文件名称
    image_ids = open('imageSets/%s.txt' % (image_set)).read().strip().split()
    # 打开对应的2012_train.txt 文件对其进行写入准备
    list_file = open('%s.txt' % (image_set), 'w')
    # 将对应的文件_id以及全路径写进去并换行
    for image_id in image_ids:
        list_file.write('images/%s.jpg\n' % (image_id))
        # 调用  year = 年份  image_id = 对应的文件名_id
        convert_annotation(image_id)
    # 关闭文件
    list_file.close()

划分数据集

python 复制代码
import os
import random
from shutil import copy2

datadir_normal = "label"  # 更换为自己刚刚转换出来的txt路径     修改1
datadir_normal1 = 'JPEGImages' # 所有的图像路径          修改2

all_data = os.listdir(datadir_normal)  # (图片文件夹)
num_all_data = len(all_data)
print("总数量: " + str(num_all_data))
index_list = list(range(num_all_data))
print(index_list)

# 生成随机种子,使得每一次划分的数据一样,如果没有要求,可以删除本段代码
random.seed(2)
random.shuffle(index_list)
print(index_list)
# 生成随机种子,使得每一次划分的数据一样,如果没有要求,可以删除本段代码

num_train = int(num_all_data * 0.7)
num_valid = int(num_all_data * 0.2)
num_test = num_all_data - num_train - num_valid

trainDir = "labels/train"  # (将训练集txt放在这个文件夹下)    不用修改
if not os.path.exists(trainDir):
    os.makedirs(trainDir)
validDir = 'labels/valid'  # (将验证集txt放在这个文件夹下)     修改3
if not os.path.exists(validDir):
    os.makedirs(validDir)
testDir = 'labels/test'  # (将测试集txt放在这个文件夹下)      修改3
if not os.path.exists(testDir):
    os.makedirs(testDir)
trainDir1 = 'images/train'  # (将训练集图片放在这个文件夹下)   不用修改
if not os.path.exists(trainDir1):
    os.makedirs(trainDir1)
validDir1 = 'images/valid'  # (将验证集图片放在这个文件夹下)   修改3
if not os.path.exists(validDir1):
    os.makedirs(validDir1)
testDir1 = 'images/test'  # (将测试集图片放在这个文件夹下)    修改3
if not os.path.exists(testDir1):
    os.makedirs(testDir1)

for i in index_list[:num_train]:
    fileName = os.path.join(datadir_normal, all_data[i])
    copy2(fileName, trainDir)
    fileName = os.path.join(datadir_normal1, all_data[i].replace("txt","jpg"))
    copy2(fileName, trainDir1)

for i in index_list[num_train:num_train+num_valid]:
    fileName = os.path.join(datadir_normal, all_data[i])
    copy2(fileName, validDir)
    fileName = os.path.join(datadir_normal1, all_data[i].replace("txt","jpg"))
    copy2(fileName, validDir1)

for i in index_list[num_train+num_valid:]:
    fileName = os.path.join(datadir_normal, all_data[i])
    copy2(fileName, testDir)
    fileName = os.path.join(datadir_normal1, all_data[i].replace("txt","jpg"))
    copy2(fileName, testDir1)

【yolo数据集】xml格式转换txt,划分数据集,亲测有效_xml转txt-CSDN博客

相关推荐
itachi-uchiha5 小时前
awk处理xml文件&&封装集合变量和调用
xml·shell·awk
武子康3 天前
Java-39 深入浅出 Spring - AOP切面增强 核心概念 通知类型 XML+注解方式 附代码
xml·java·大数据·开发语言·后端·spring
Ll13045252984 天前
基于 COM 的 XML 解析技术(MSXML) 的总结
xml
在代码的海洋中寻找亚特兰蒂斯5 天前
AJAX对于XML和JSON的处理
xml·ajax·json
BinField6 天前
ToolsSet之:XML工具
xml·windows·microsoft
SEO-狼术6 天前
Connect Directly to Oracle XML Data
xml·数据库·oracle
YSoup7 天前
2025年目前最新版本Android Studio自定义xml预览的屏幕分辨率
android·xml·android studio
abcnull8 天前
mybatis的mapper对应的xml写法
xml·sql·spring·mybatis·mapper
Blue桃之夭夭8 天前
HTML、XML、JSON 是什么?有什么区别?又是做什么的?
xml·html·json
小于村8 天前
pom.xml 文件中配置你项目中的外部 jar 包打包方式
xml·java·jar