1.创建虚拟环境
conda create -n yolov5a python=3.8
2.安装labelimg
pip install labelimg
or
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple labelimg
3.终端输入labelimg
把你的数据集(你的图片放在一个文件夹例如:images),另外创建一个生成后的数据保存文件夹(例如:Annotations),点击file-open dir(这是你的数据集路径),点击file-chenge save dir(这是你的输出路径)
voc标注方式,最后生成的是.xml格式的文件,
而再次点击它(PascalVoc)会出现yolo格式的标注,最会生成的txt格式的文件
最后我们需要的是.txt文件格式的标注,但是如果你要是忘了后面还是有代码将xml转换为txt格式的代码,快捷键:W是启动标注,A是上一张,D是下一张图片,(就像我们以前打CF前后左右键)在view里面点击自动保存。
数据集就标注完成了,现在你手里有两个文件夹一个存放原始图片的,一个是存放标注文件的,
4.然后再yolov5的源码里要修改哪些地方呢
(1)首先你应该把你刚刚的两个文件放到data文件夹里面去:把原图片放到JPEGimages文件夹,把标签文件还是放在原来的文件里面,images里面是源码自带的文件夹所以不管他,
现在我们训练是需要两个文件train.txt、val.txt、原图片、.txt格式的标注文件。所以我们这里要运行一个代码将数据集分为训练集、测试集、验证集等几个txt文件(先不用管几个反正需要的只有train、val),就在data目录下创建一个python代码:
# coding:utf-8
import os
import random
import argparse
parser = argparse.ArgumentParser()
#xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下
parser.add_argument('--xml_path', default='Annotations', type=str, help='input xml label path')
#数据集的划分,地址选择自己数据下的ImageSets/Main
parser.add_argument('--txt_path', default='ImageSets/Main', 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 = 'D:/FOD/yolov5/yolov5_4/data/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()
运行完这个代码会出现以下文件夹:
imagesets-mian里面就存放着我们一会需要的train.txt, val.txt等四个文件,
最重要的问题也是经常训练出错的问题:没有找到图片啊,图片加载失败啊什么的
就是刚刚我们生成数据集的代码里面,生成的四个文件主要是存放的数据集的路径:
这四个文件里面存放的是我们的图片路径,所以我们就要改一下上面name的代码,改成你自己的文件路径:比如D:/张三/李四/yolov5/data/JPEGimages/img.jpg, 记住一定要是英文路径,斜杠一定要这个斜杠,必须要有后缀。我们这里JPEGimages存放的原图片所以就写成JPEGimages;
————————————————
我们的标注文件默认为.xml,如果你已经是.txt格式的你就直接在data文件夹下面创建一个labels文件夹把他们放到里面去,为了以防万一再把所有的txt文件放到JPEGimages存放原图的文件夹如下:你这里应该是JPEGimages下面
labels文件
如果是.xml的话我们运行下面的代码:将xml格式转换为txt格式的就完事了;这个代码创建在项目的文件下也就是和你的train.py在一起创建,
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
# 数据标签
classes = ['person'] #需要修改
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
if w>=1:
w=0.99
if h>=1:
h=0.99
return (x,y,w,h)
def convert_annotation(rootpath,xmlname):
xmlpath = rootpath + '/Annotations'
xmlfile = os.path.join(xmlpath,xmlname)
with open(xmlfile, "r", encoding='UTF-8') as in_file:
txtname = xmlname[:-4]+'.txt'
print(txtname)
txtpath = rootpath + '/labels' #生成的.txt文件会被保存在labels目录下
if not os.path.exists(txtpath):
os.makedirs(txtpath)
txtfile = os.path.join(txtpath,txtname)
with open(txtfile, "w+" ,encoding='UTF-8') as out_file:
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
out_file.truncate()
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))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
if __name__ == "__main__":
rootpath='F:\\QQ\yolov5\yolov5\\yolov5_4\\data' ##需要修改的地方改成你的路径
xmlpath=rootpath+'\\Annotations'这就是xml的路径
list=os.listdir(xmlpath)
for i in range(0,len(list)) :
path = os.path.join(xmlpath,list[i])
if ('.xml' in path)or('.XML' in path):
convert_annotation(rootpath,list[i])
print('done', i)
else:
print('not xml file',i)
运行完之后
数据集分配问题解决了之后我们要修改coco.yaml, 与 models文件夹下面yolov5s.yaml文件的东西,
coco.yaml里面存放的是train.txt,和val.txt的存放路径,以及类别数量,和类别名字:也就是我们刚刚代码生成的文件路径,
yolov5s.yaml改一下类别就可以了,改成你自己的类别数量 如我的类别是1,所以nc=1
基本上没有需要改的了,我们直接打开train.py看看:直接划到最下面参数部分
代码里面的data,从data里面的coco.yaml读取train.txt(训练集的地址),train.txt就是存放的图片路径这样就可以读取到图片,标签的话自动定位到对应到labels文件的标签,weights就是预训练模型,epoch训练的轮数,我一般设置的是200,300,batch_size是多少张图片打包,如果电脑不好就是1,2,8,16,32,64,越大就是电脑需要的性能越好,device:设置为0,workers:代表启动的线程数,如果电脑不好就设置为0,表示主线程。
这样我们就可以直接运行这个代码了,运行完之后在根目录下面runs--train里面找到自己的权重,有一个best.pt用来去检测。
如出现报错 AssertionError: train: No labels in E:\yolov5\yolov5\data_area\lables\train.cache. Can
首先找到utils文件,再utils文件中找到dataloaders.py文件,ctrl+F搜define label
将第二行改为自己存放自己图片的文件夹名称即 如我的图片文件夹是JPEGimages,就把这里的images改成JPEGimages
原文链接:https://blog.csdn.net/qq_52859223/article/details/123701798
本文是在博主小吴的文章上基础上转载简化的,如想了解详细版本点以上链接