YOLOv5训练自己的数据集

版本:YOLOv5-5.0 权重文件:yolov5s.pt

将YOLOv5自带的images删去;

1.在data文件夹下新建Annotations、images、ImageSets、JPEGImages、labels五个目录;

YOLOv5训练自己的数据集

Annotations存放标签xml文件(自己放进去);

images和JPEGImages存在图片jpg(自己放进去);

ImageSets存放如下四个txt文件(暂无);

YOLOv5训练自己的数据集

labels存放xml文件转换的txt文件(暂无)。

2.在YOLOv5目录下粘贴voc_label.py和makeTxt.py

(1)voc_label.py内容如下:

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=["phone"]

进行归一化操作
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('data/Annotations/%s.xml' % (image_id), encoding='utf-8')
    # 准备在对应的image_id 中写入对应的label,分别为
    # <object-class> <x> <y> <width> <height>
    out_file = open('data/labels/%s.txt' % (image_id), 'w', encoding='utf-8')
    # &#x89E3;&#x6790;xml&#x6587;&#x4EF6;
    tree = ET.parse(in_file)
    # &#x83B7;&#x5F97;&#x5BF9;&#x5E94;&#x7684;&#x952E;&#x503C;&#x5BF9;
    root = tree.getroot()
    # &#x83B7;&#x5F97;&#x56FE;&#x7247;&#x7684;&#x5C3A;&#x5BF8;&#x5927;&#x5C0F;
    size = root.find('size')
    # &#x5982;&#x679C;xml&#x5185;&#x7684;&#x6807;&#x8BB0;&#x4E3A;&#x7A7A;&#xFF0C;&#x589E;&#x52A0;&#x5224;&#x65AD;&#x6761;&#x4EF6;
    if size != None:
        # &#x83B7;&#x5F97;&#x5BBD;
        w = int(size.find('width').text)
        # &#x83B7;&#x5F97;&#x9AD8;
        h = int(size.find('height').text)
        # &#x904D;&#x5386;&#x76EE;&#x6807;obj
        for obj in root.iter('object'):
            # &#x83B7;&#x5F97;difficult &#xFF1F;&#xFF1F;
            difficult = obj.find('difficult').text
            # &#x83B7;&#x5F97;&#x7C7B;&#x522B; =string &#x7C7B;&#x578B;
            cls = obj.find('name').text
            # &#x5982;&#x679C;&#x7C7B;&#x522B;&#x4E0D;&#x662F;&#x5BF9;&#x5E94;&#x5728;&#x6211;&#x4EEC;&#x9884;&#x5B9A;&#x597D;&#x7684;class&#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x6216;difficult==1&#x5219;&#x8DF3;&#x8FC7;
            if cls not in classes or int(difficult) == 1:
                continue
            # &#x901A;&#x8FC7;&#x7C7B;&#x522B;&#x540D;&#x79F0;&#x627E;&#x5230;id
            cls_id = classes.index(cls)
            # &#x627E;&#x5230;bndbox &#x5BF9;&#x8C61;
            xmlbox = obj.find('bndbox')
            # &#x83B7;&#x53D6;&#x5BF9;&#x5E94;&#x7684;bndbox&#x7684;&#x6570;&#x7EC4; = ['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)
            # &#x5E26;&#x5165;&#x8FDB;&#x884C;&#x5F52;&#x4E00;&#x5316;&#x64CD;&#x4F5C;
            # w = &#x5BBD;, h = &#x9AD8;&#xFF0C; b= bndbox&#x7684;&#x6570;&#x7EC4; = ['xmin','xmax','ymin','ymax']
            bb = convert((w, h), b)
            # bb &#x5BF9;&#x5E94;&#x7684;&#x662F;&#x5F52;&#x4E00;&#x5316;&#x540E;&#x7684;(x,y,w,h)
            # &#x751F;&#x6210; calss x y w h &#x5728;label&#x6587;&#x4EF6;&#x4E2D;
            out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')

&#x8FD4;&#x56DE;&#x5F53;&#x524D;&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;
wd = getcwd()
print(wd)

for image_set in sets:
    '''
    &#x5BF9;&#x6240;&#x6709;&#x7684;&#x6587;&#x4EF6;&#x6570;&#x636E;&#x96C6;&#x8FDB;&#x884C;&#x904D;&#x5386;
    &#x505A;&#x4E86;&#x4E24;&#x4E2A;&#x5DE5;&#x4F5C;&#xFF1A;
&#x3000;&#x3000;&#x3000;&#x3000;&#xFF11;&#xFF0E;&#x5C06;&#x6240;&#x6709;&#x56FE;&#x7247;&#x6587;&#x4EF6;&#x90FD;&#x904D;&#x5386;&#x4E00;&#x904D;&#xFF0C;&#x5E76;&#x4E14;&#x5C06;&#x5176;&#x6240;&#x6709;&#x7684;&#x5168;&#x8DEF;&#x5F84;&#x90FD;&#x5199;&#x5728;&#x5BF9;&#x5E94;&#x7684;txt&#x6587;&#x4EF6;&#x4E2D;&#x53BB;&#xFF0C;&#x65B9;&#x4FBF;&#x5B9A;&#x4F4D;
&#x3000;&#x3000;&#x3000;&#x3000;&#xFF12;&#xFF0E;&#x540C;&#x65F6;&#x5BF9;&#x6240;&#x6709;&#x7684;&#x56FE;&#x7247;&#x6587;&#x4EF6;&#x8FDB;&#x884C;&#x89E3;&#x6790;&#x548C;&#x8F6C;&#x5316;&#xFF0C;&#x5C06;&#x5176;&#x5BF9;&#x5E94;&#x7684;bundingbox &#x4EE5;&#x53CA;&#x7C7B;&#x522B;&#x7684;&#x4FE1;&#x606F;&#x5168;&#x90E8;&#x89E3;&#x6790;&#x5199;&#x5230;label &#x6587;&#x4EF6;&#x4E2D;&#x53BB;
    &#x3000;&#x3000;&#x3000;&#x3000;&#x3000;&#x6700;&#x540E;&#x518D;&#x901A;&#x8FC7;&#x76F4;&#x63A5;&#x8BFB;&#x53D6;&#x6587;&#x4EF6;&#xFF0C;&#x5C31;&#x80FD;&#x627E;&#x5230;&#x5BF9;&#x5E94;&#x7684;label &#x4FE1;&#x606F;
    '''
    # &#x5148;&#x627E;labels&#x6587;&#x4EF6;&#x5939;&#x5982;&#x679C;&#x4E0D;&#x5B58;&#x5728;&#x5219;&#x521B;&#x5EFA;
    if not os.path.exists('data/labels/'):
        os.makedirs('data/labels/')
    # &#x8BFB;&#x53D6;&#x5728;ImageSets/Main &#x4E2D;&#x7684;train&#x3001;test..&#x7B49;&#x6587;&#x4EF6;&#x7684;&#x5185;&#x5BB9;
    # &#x5305;&#x542B;&#x5BF9;&#x5E94;&#x7684;&#x6587;&#x4EF6;&#x540D;&#x79F0;
    image_ids = open('data/ImageSets/%s.txt' % (image_set)).read().strip().split()
    # &#x6253;&#x5F00;&#x5BF9;&#x5E94;&#x7684;2012_train.txt &#x6587;&#x4EF6;&#x5BF9;&#x5176;&#x8FDB;&#x884C;&#x5199;&#x5165;&#x51C6;&#x5907;
    list_file = open('data/%s.txt' % (image_set), 'w')
    # &#x5C06;&#x5BF9;&#x5E94;&#x7684;&#x6587;&#x4EF6;_id&#x4EE5;&#x53CA;&#x5168;&#x8DEF;&#x5F84;&#x5199;&#x8FDB;&#x53BB;&#x5E76;&#x6362;&#x884C;
    for image_id in image_ids:
        list_file.write('data/images/%s.jpg\n' % (image_id))
        # &#x8C03;&#x7528;  year = &#x5E74;&#x4EFD;  image_id = &#x5BF9;&#x5E94;&#x7684;&#x6587;&#x4EF6;&#x540D;_id
        try:
            convert_annotation(image_id)
        except:
            continue
    # &#x5173;&#x95ED;&#x6587;&#x4EF6;
    list_file.close()</height></width></y></x></object-class>

(2)makeTxt.py内容如下:

import os
import random

trainval_percent = 0.9
train_percent = 0.9
xmlfilepath = 'data/Annotations'
txtsavepath = 'data/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('data/ImageSets/trainval.txt', 'w')
ftest = open('data/ImageSets/test.txt', 'w')
ftrain = open('data/ImageSets/train.txt', 'w')
fval = open('data/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:
            ftrain.write(name)
        else:
            fval.write(name)
    else:
        ftest.write(name)

ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

先运行makeTxt.py创建ImageSets下的四个txt文件;

然后运行voc_label.py将Annotations存放的标签xml文件转换为labels存放的txt文件。

3.将权重文件yolov5s.pt粘结在YOLOv5目录下

YOLOv5训练自己的数据集
  1. 将data下的coco128.yaml文件复制,粘结在data目录下,改成自己的名字(如phone.yaml)

YOLOv5训练自己的数据集

内容改成如图所示

YOLOv5训练自己的数据集

YOLOv5训练自己的数据集

6.将train.py文件下的如图所示三项改成自己对应的文件

YOLOv5训练自己的数据集

如我采用yolov5s.pt、cfg采用yolov5s.yaml、data采用自己的phone.yaml

然后即可开始训练。

训练完成得到last.py和best.py

YOLOv5训练自己的数据集

7.打开detect.py更改前两行

YOLOv5训练自己的数据集

第一行更改为训练生成的best.py

第二行更改为你想要测试的图片数据。

然后运行detect.py,得到推测结果。

YOLOv5训练自己的数据集

然后点开runs\detect\exp11,即可查看训练的效果。

YOLOv5训练自己的数据集

Original: https://blog.csdn.net/weixin_52950958/article/details/125508751
Author: xukobe97
Title: YOLOv5训练自己的数据集

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/518860/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球