是时候制作自己的数据集啦!(强烈建议先看完文章)
结尾提供傻瓜式使用文件
参考文章:YOLOv5训练自己的数据集(超详细)_yolo数据集_AI追随者的博客-CSDN博客
对于YOLO 的数据集主要涉及到两个东西: 图片 以及 图片的标注
- 图片的收集不在本文章的内容范围内
- 图片的标注可以通过 Labelimg 进行标注
通过使用Labelimg 可以获得 XML 格式的标签,可以选择 YOLO 格式的标签
下面以获得 XML 格式的标签后为例子
# 处理文件名:
有时候通过各种方式获得的图片中会有空格,而空格会导致接下来划分数据集的时候出现问题,因此我们需要将空格替换成其他的符号,比如 "_"
更改的文件夹为 ./data/Picture/
处理完成后将 ./data/Picture/ 中的图片移动到 ./data/Convert/images/ 中
import os def filerename(path_): filelist = os.listdir(path_) # 文件夹中的文件列表 for file in filelist: # 逐次遍历文件夹下的文件 path2 = file.replace(' ', '_') # 将文件名中的空格替换成下划线,或者替换成其他的也行 Olddir = os.path.join(path_, file) # 完整的的文件路径 Newdir = os.path.join(path_, path2) # 得到新的路径 os.rename(Olddir, Newdir) # 重命名 if __name__ == "__main__": filerename("data/Picture")
# 划分数据集:
将图片按照比例划分为不同的数据集:
train.txt val.txt trainval.txt test.txt
需要注意图片文件的格式 如果是png格式的图片需将下面代码第33行的.png修改为jpg
输出文件夹为 ./data/Convert/
# coding:utf-8 import os import random import argparse parser = argparse.ArgumentParser() parser.add_argument('--xml_path', default='./data/Picture_XML/', type=str, help='input xml label path') parser.add_argument('--txt_path', default='./data/Convert/', type=str, help='output txt label path') opt = parser.parse_args() trainval_percent = 1.0 train_percent = 0.9 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') file_test = open(txtsavepath + '/test.txt', 'w') file_train = open(txtsavepath + '/train.txt', 'w') file_val = open(txtsavepath + '/val.txt', 'w') for i in list_index: name = './images/' + total_xml[i][:-4] + '.jpg\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()
# XML格式 标签转换为 YOLO 格式标签:
存放 XML 格式的文件夹为 ./data/Picture_XML/
输出文件夹为 data/Convert/labels/
# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd
sets = ['train', 'val', 'test']
classes = ["A", "B", "C"] # 改成自己的类别
abs_path = os.getcwd()
print(abs_path)
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
return x, y, w, h
def convert_annotation(image_id):
in_file = open('data/Picture_XML/%s.xml' % (image_id), encoding='UTF-8')
out_file = open('data/Convert/labels/%s.txt' % (image_id), 'w')
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')
wd = getcwd()
for image_set in sets:
if not os.path.exists('data/Convert/labels/'):
os.makedirs('data/Convert/labels/')
image_ids = open('data/Convert/%s.txt' % (image_set)).read().split(".")[1::2]
image_names = []
for image_id in image_ids:
image_names.append(image_id[8:])
list_file = open('data/Convert/labels/%s.txt' % (image_set), 'w')
for image_id in image_names:
list_file.write(abs_path + 'data/Convert/labels/%s.txt\n' % (image_id))
convert_annotation(image_id)
list_file.close()
# 配置数据
执行完以上几步后,数据的目录应当是这样的
labelimg └── data ├── Convert # 此目录下有两个文件夹 和四个txt 文件 | ├──images * 放入移除空格后的图片 | └──labels * 这里生成了 XML 转换出来的 TXT 格式的数据标注 ├──Picture # 这里放用来训练的图片 └──Picture_XML # 这里放标注获得的XML 格式文件
接下来配置yaml文件:
1. yolov5 默认使用的是 coco128.yaml 默认是在 'YOLO根目录'/data/ 下面, 复制一份
2. 更改这份复制的coco128.yaml 中的2个参数(已加粗):
path: D:/0_AI_Learning/ApexDataset # 更改为 ./data/Convert/ 文件夹的绝对路径
比如 'D:/AI_Learning/labelImg/'
train: train.txt # train images (relative to 'path') 128 images 不用更改
val: val.txt # val images (relative to 'path') 128 images 不用更改
test: # test images (optional) 不用更改 #
Classes # 更改成训练时的类别, 注意保持顺序
names:
0: A
1: B
2: C
## 将获得的 *.yaml 文件放入 YOLOV5/data/ 目录内
# 更改train.py 中的参数: parser.add_argument('--data', type=str, default=ROOT / 'data/***.yaml', help='dataset.yaml path') 将'***.yaml'改为 #数据集配置 中获得的 yaml 文件的名称## 记得将获得的 *.yaml 文件放入 YOLOV5/data/ 目录内
接下来介绍傻瓜式操作:
YOLO/labelImg at main · RedWhiteLuo/YOLO (github.com)
进入上面的网页 -> 打包下载 -> 在pycharm 中打开项目 -> 将图片放入 ./data/Picture/ 中
-> 将标注文件放入 ./data/Picture_XML/ 文件夹中 -> 执行del_space.py
-> 将./data/Picture/ 中的所有图片移动到 ./data/Convert/images 中
-> 执行 into_different_data.py -> 执行xml2txt.py -># 更改train.py 中的参数(上面不远处有)