python实现VOC格式(xml)标签批量转换为yolo格式(txt)标签

编程入门 行业动态 更新时间:2024-10-24 00:17:48

python实现VOC格式(xml)<a href=https://www.elefans.com/category/jswz/34/1770160.html style=标签批量转换为yolo格式(txt)标签"/>

python实现VOC格式(xml)标签批量转换为yolo格式(txt)标签

文章目录

  • 前言
  • 一、VOC格式标签
  • 二、YOLO格式标签
  • 三、voc_to_yolo.py转换脚本
    • 1.引入库
    • 2.定义转换逻辑
    • 3.实现转换函数
    • 4.实现入口主函数
  • 四、完整代码如下
  • 五、总结


前言

我们常见的目标检测算法使用的数据集对应标签格式多为四种,分别是voc格式、yolo格式、json格式、coco格式。本文将分享自己使用的voc转yolo格式的脚本文件,批量转换,非常高效,后续将继续分享yolo格式转voc格式脚本、voc转json格式脚本等,如果本文对你有帮助,谢谢阅览点赞收藏!


一、VOC格式标签

在转换voc格式标签之前,我们先了解下voc格式标签是什么样的,有哪些特点。典的开源数据集VOC2007、VOC2012、VOC2017这些数据集的标签格式为voc格式,即标签文件为xml文件,xml文件包含的主要信息如下图所示:

二、YOLO格式标签

上面我们了解了VOC格式标签的基本样子和主要包含的信息,下面介绍一下yolo格式标签,重点讲下txt文件中每行数字代表什么意思。如下图所示:

三、voc_to_yolo.py转换脚本

1.引入库

代码如下(示例):

import os
import cv2
import pickle
import xml.etree.ElementTree as ET
from os.path import join
from skimage import io
from os import listdir, getcwd
from PIL import Image

2.定义转换逻辑

代码如下(示例):

def convert(size, box):x_center = (box[0]+box[1])/2.0y_center = (box[2]+box[3])/2.0x = x_center / size[0]y = y_center / size[1]w = (box[1] - box[0]) / size[0]h = (box[3] - box[2]) / size[1]"""if x >= 1:x = 0.999if y >= 1:y = 0.999if w >= 1:w = 0.999if h >= 1:h = 0.999"""# print(x, y, w, h)return (x,y,w,h)

3.实现转换函数

def convert_annotation(xml_files_path, save_txt_files_path, classes):  line_data = []with open(xml_files_path,'r') as f:for line in f.readlines():line = line.strip()x = line.split(";",6)print(x)print(x[0])out_txt_path = os.path.join(save_txt_files_path, x[0].split('.')[0] + '.txt')if x[5] == 'warning':class_id = 0if x[5] == 'prohibitory':class_id = 1if x[5] == 'mandatory':class_id = 2b = (float(x[1]),float(x[3]),float(x[2]),float(x[4]))img = Image.open('F:/CCTSDB_one/GroundTruth/'+x[0])w, h = list(img.size)print(w,h,b)bb = convert((w,h), b)with open(out_txt_path, 'w') as f:f.write(str(class_id) + " " + " ".join([str(a) for a in bb]) + '\n')

4.实现入口主函数

if __name__ == "__main__":
#定义类别,先从voc格式标签中提取,搞清楚,一定要对应起来,不能多,也不能少,否则最后转换的txt文件容易出错。classes1 = ['warning','prohibitory','mandatory']# voc格式的xml标签文件路径GT_files1 = r'F:\CCTSDB_one\GroundTruth\GroundT'#转化为yolo格式的txt标签文件存储路径save_txt_files1 = r'F:\CCTSDB_one\GroundTruth\yolo_txt'convert_annotation(GT_files1, save_txt_files1, classes1)

四、完整代码如下

"""
voc格式xml转化为yolo中的txt
"""import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
from PIL import Image
import cv2
from skimage import iodef convert(size, box):# size=(width, height)  b=(xmin, xmax, ymin, ymax)# x_center = (xmax+xmin)/2        y_center = (ymax+ymin)/2# x = x_center / width            y = y_center / height# w = (xmax-xmin) / width         h = (ymax-ymin) / heightx_center = (box[0]+box[1])/2.0y_center = (box[2]+box[3])/2.0x = x_center / size[0]y = y_center / size[1]w = (box[1] - box[0]) / size[0]h = (box[3] - box[2]) / size[1]"""if x >= 1:x = 0.999if y >= 1:y = 0.999if w >= 1:w = 0.999if h >= 1:h = 0.999"""# print(x, y, w, h)return (x,y,w,h)def convert_annotation(xml_files_path, save_txt_files_path, classes):  #xml_files = open(xml_files_path,'r')#gt_files = open(xml_files_path,'r')#print(gt_files)line_data = []#root = r'F:\CCTSDB_one\GroundTruth\'with open(xml_files_path,'r') as f:for line in f.readlines():line = line.strip()x = line.split(";",6)print(x)print(x[0])out_txt_path = os.path.join(save_txt_files_path, x[0].split('.')[0] + '.txt')#out_txt_f = open(out_txt_path, 'w')if x[5] == 'warning':class_id = 0if x[5] == 'prohibitory':class_id = 1if x[5] == 'mandatory':class_id = 2b = (float(x[1]),float(x[3]),float(x[2]),float(x[4]))img = Image.open('F:/CCTSDB_one/GroundTruth/'+x[0])w, h = list(img.size)print(w,h,b)bb = convert((w,h), b)with open(out_txt_path, 'w') as f:f.write(str(class_id) + " " + " ".join([str(a) for a in bb]) + '\n')"""       for xml_name in xml_files:print(xml_name)xml_file = os.path.join(xml_files_path, xml_name)out_txt_path = os.path.join(save_txt_files_path, xml_name.split('.')[0] + '.txt')out_txt_f = open(out_txt_path, 'w')tree=ET.parse(xml_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):difficult = obj.find('difficult').textcls = obj.find('name').textif cls not in classes or int(difficult) == 1:continuecls_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))# b=(xmin, xmax, ymin, ymax)print(w, h, b)bb = convert((w,h), b)out_txt_f.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
"""if __name__ == "__main__":    #================================================================================================classes1 = ['warning','prohibitory','mandatory']# 2、voc格式的xml标签文件路径GT_files1 = r'F:\CCTSDB_one\GroundTruth\GroundT.txt'# 3、转化为yolo格式的txt标签文件存储路径save_txt_files1 = r'F:\CCTSDB_one\GroundTruth\yolo_txt'convert_annotation(GT_files1, save_txt_files1, classes1)

五、总结

本文见本使用起来方便快捷。学好python,大大提高工作效率!觉得还不错的,感谢关注收藏,后续还会继续分享好用的数据处理脚本。

更多推荐

python实现VOC格式(xml)标签批量转换为yolo格式(txt)标签

本文发布于:2024-02-17 18:37:18,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1695076.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:标签   格式   转换为   批量   VOC

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!