数据集VOC转YOLOV8方法

首先转为yolov5,然后通过label_convert工具转换yolov5到yolov8。

VOC数据格式如下
在这里插入图片描述

根据该文件夹,使用代码images_tag.py

# images_tag.py   该脚本文件需要修改第11-12行,设置train、val、test的切分的比率
import os
import random
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--xml_path', default=r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1\Annotations', type=str,
                    help='input xml label path')
parser.add_argument('--txt_path', default=r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1/imagesets', type=str,
                    help='output txt label path')
opt = parser.parse_args()

trainval_percent = 0.9
train_percent = 0.7  # 这里的train_percent 是指占trainval_percent中的
xmlfilepath = opt.xml_path
txtsavepath = opt.txt_path
total_xml = os.listdir(xmlfilepath)
if not os.path.exists(txtsavepath):
    os.makedirs(txtsavepath)

num = len(total_xml)
list_index = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list_index, tv)
train = random.sample(trainval, tr)

file_trainval = open(txtsavepath + '/trainval.txt', 'w', encoding='utf-8')
file_test = open(txtsavepath + '/test.txt', 'w', encoding='utf-8')
file_train = open(txtsavepath + '/train.txt', 'w', encoding='utf-8')
file_val = open(txtsavepath + '/val.txt', 'w', encoding='utf-8')

for i in list_index:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        file_trainval.write(name)
        if i in train:
            file_train.write(name)
        else:
            file_val.write(name)
    else:
        file_test.write(name)

file_trainval.close()
file_train.close()
file_val.close()
file_test.close()

然后使用代码

# mian.py   该脚本文件需要修改第10行(classes)即可
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
from tqdm import tqdm
import os
from os import getcwd

sets = ['train', 'test', 'val']
# 这里使用要改成自己的类别
classes = ['red', 'yellow', 'green', 'off']




def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    x = round(x, 6)
    w = round(w, 6)
    y = round(y, 6)
    h = round(h, 6)
    return x, y, w, h


# 后面只用修改各个文件夹的位置
def convert_annotation(image_id):
    # try:
    in_file = open(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1/Annotations/%s.xml' % (image_id), encoding='utf-8')
    out_file = open(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1/labels/%s.txt' % (image_id), 'w', encoding='utf-8')
    tree = ET.parse(in_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').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            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))
        b1, b2, b3, b4 = b
        # 标注越界修正
        if b2 > w:
            b2 = w
        if b4 > h:
            b4 = h
        b = (b1, b2, b3, b4)
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " +
                       " ".join([str(a) for a in bb]) + '\n')


# except Exception as e:
# print(e, image_id)




#  yolov5_to_yolov8 --data_dir D:\DeepLearning\VOC2Yolo\S2TLD\normal_1 --mode_list train,val
# 这一步生成的txt文件写在data.yaml文件里
wd = getcwd()
for image_set in sets:
    if not os.path.exists(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1/labels/'):
        os.makedirs(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1/labels/')

    # image_ids = open(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1/Imagesets/%s.txt' %
    #                  (image_set)).read().strip().split()

    image_ids = open(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1/Imagesets/%s.txt' %(image_set), encoding='utf-8').read().strip().split()
    list_file = open(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1/%s.txt' % (image_set), 'w', encoding='utf-8')
    for image_id in tqdm(image_ids):
        list_file.write('D:/DeepLearning/VOC2Yolo/S2TLD/normal_1/images/%s.jpg\n' % (image_id))#不能使用r符号,否则\n不会被转义为换行符,导致后续找不到路径。
        convert_annotation(image_id)
    list_file.close()

到此生成YOLOV5格式的数据集
YOLOV5数据集格式如下:

yolov5_dataset
├── classes.txt
├── non_labels  # 通常用来放负样本
│   └── bg1.jpeg
├── images
│   ├── images(13).jpg
│   └── images(3).jpg
├── labels
│   ├── images(13).txt
│   └── images(3).txt
├── train.txt
└── val.txt

通过label_convert工具,进行yolov5转yolov8

#网址  https://rapidai.github.io/LabelConvert/docs/supportconversions/yolov5_to_yolov8/
pip install label_convert

安装后,使用

yolov5_to_yolov8 --data_dir dataset/yolov5_dataset --mode_list train,val,test

即可得到yolov8数据格式数据集

--data_dir: 数据集所在目录。示例为dataset/yolov5_dataset
--save_dir: 保存转换后的数据集目录。默认为dataset/yolov5_dataset_yolov8
--mode_list: 指定划分的数据集种类。 (例如:train,val,test / train,val)

yolov8数据集格式如下

yolov8_dataset
├── images
│   ├── train
│   │   ├── 0dcddf72.jpg
│   │   └── images(3).jpg
│   └── val
│       ├── 8ae4af51.jpg
│       └── images(13).jpg
└── labels
    ├── train
    │   ├── 0dcddf72.txt
    │   └── images(3).txt
    └── val
        ├── 8ae4af51.txt
        └── images(13).txt

提示

如果使用label_convert工具时候,出现UTF-8编码错误说明,txt文件编码格式不对。需要指明编码方式。
对于txt文件编码格式可以用如下代码检测。

import chardet

with open(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1\labels\000000.txt', 'rb') as f:
    result = chardet.detect(f.read(100))  # 读取一定量的数据进行编码检测

print(result['encoding'])  # 打印检测到的编码

with open(r'D:\DeepLearning\VOC2Yolo\S2TLD\normal_1\labels\000000.txt', 'r', encoding='utf-8') as file:
    content = file.read()
    print(content)

检测出来的结果是ASCII,则证明是UTF-8 ?

要将VOC数据集换为Yolov5格式,需要进行以下步骤: 1. 下载并安装Yolov5:首先,你需要在你的机器上下载和安装Yolov5。你可以从Yolov5的GitHub存储库获取代码和详细的安装说明。 2. 准备VOC数据集:确保你已经下载和准备好了VOC数据集。这个数据集包含了图像文件和相应的标注文件。 3. 创建Yolov5标注文件格式:Yolov5使用自定义的标注文件格式,而不是VOC数据集中的XML格式。你需要将VOC数据集中的每个图像的标注信息换为Yolov5格式。 Yolov5的标注文件格式如下: ``` class_index x_center y_center width height ``` - class_index:目标类别的索引,从0开始 - x_center, y_center:目标边界框中心的归一化坐标(相对于图像宽度和高度) - width, height:目标边界框的归一化宽度和高度(相对于图像宽度和高度) 例如,如果你有一个类别为"dog"的目标,边界框中心点坐标为(100, 200),宽度为50,高度为100,图像的宽度和高度为500,那么对应的Yolov5标注行为: ``` 0 0.2 0.4 0.1 0.2 ``` 4. 将VOC数据集换为Yolov5格式:使用脚本将VOC数据集换为Yolov5格式。Yolov5的作者提供了一个用于数据集换的脚本,在Yolov5的GitHub存储库中可以找到。你可以使用该脚本将所有图像的标注信息换为Yolov5格式。 运行脚本的命令如下: ``` python path/to/yolov5/scripts/voc2yolo.py --data path/to/data.yaml ``` 其中,`path/to/yolov5`是你安装Yolov5的路径,`path/to/data.yaml`是包含数据集信息的Yaml文件的路径。 5. 获取Yolov5格式的数据集换完成后,你将得到一个包含Yolov5格式标注的数据集。这个数据集可以直接用于训练Yolov5模型。 请注意,以上步骤是基于Yolov5官方提供的脚本和标注文件格式。如果你的需求有所不同,你可能需要进行自定义修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值