目录

1、环境配置

2、使用labelimg标注图片

2.1 在 yolov5目录下 新建文件夹 VOCData(可以自定义命名)

2.2在VOCData下新建两个文件夹 Annotations 以及 images

2.3 labelimg的安装

2.4 使用labelimg进行标注

 3 数据集的划分

3.1. 划分训练集、验证集、测试集

 3.2. XML格式转yolo_txt格式

 4修改训练的配置文件

4.1 在 yolov5 目录下的 data 文件夹下 新建一个 myvoc.yaml文件(可以自定义命名)。

4.2生成anchors

4.3修改模型配置文件

4.4训练过程

 4.5训练可视化

 5测试实验

 6参考连接


1、环境配置

使用的环境:

pytorch: 1.10.0

python: 3.9

yolov5 v6.0

其中: 如果使用GPU,cuda版本要 >=10.1

下载yolov5

yolov5 v6.0官方要求 Python>=3.6 and PyTorch>=1.7

yolov5源码下载:https://github.com/ultralytics/yolov5

2、使用labelimg标注图片

2.1 在 yolov5目录下 新建文件夹 VOCData(可以自定义命名)

2.2在VOCData下新建两个文件夹 Annotations 以及 images

 

images:用于存放要标注的图片(jpg格式)

Annotations :用于存放标注图片后产生的内容(这里采用XML格式)

2.3 labelimg的安装

打开anaconda prompt

 输入:pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple

2.4 使用labelimg进行标注

首先新建一个predefined_classed.txt文件,在文件内写入待标注的类别。

 在终端中进入到VOCData文件夹

 输入如下的命令打开labelimg。这个命令的意思是打开labelimg工具;打开JPEGImage文件夹,初始化predefined_classes.txt里面定义的类。

labelimg predefined_classes.txt

 运行如上的命令就会打开这个工具;如下

待标注图片数据的路径文件夹,选择images文件夹

保存类别标签的路径文件夹,选择Annotations 文件夹

这个按键可以说明我们标注的标签为voc格式,点击可以换成yolo或者createML格式。(这里选择voc格式)

        点击View,会出现如图红色框框中的选项。最好和我一样把勾勾勾上。

        Auto Save mode:切换到下一张图的时候,会自动保存标签。

        Display Labels:会显示标注框和标签

        Advanced Mode:标注的十字架会一直悬浮在窗口。

常用快捷键如下:

A:切换到上一张图片

D:切换到下一张图片

W:调出标注十字架

del :删除标注框框

Ctrl+u:选择标注的图片文件夹

Ctrl+r:选择标注好的label标签存在的文件夹

我们设置了标注的十字架一直在标注界面上,这里就不需要我们按快捷键w,然后选择我们需要标注的对象。按住鼠标左键拖出矩形框就可以了。如下图所示,当我们选定目标以后,就会加载出来predefined_classes.txt  定义自己要标注的所有类别(如果类别多,就不需要自己手打每个类别的名字)。打好的标签框框上会有该框框的类别。然后界面最右边会出现打好的类别标签。打好一张照片以后,快捷键D,就会进入下一张,这时候就会自动保存标签文件(voc格式会保存xml,yolo会保存txt格式)。

 在Annotations 文件下可以看到以及标签的文件已经保存在这个目录下。

 3 数据集的划分

3.1. 划分训练集、验证集、测试集

在VOCData目录下创建程序 split_train_val.py 并运行

程序如下:

# 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 = 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()

程序运行完成后 会生成 ImagesSets\Main 文件夹,在这个文件夹中会生成 测试集、训练集、训练验证集、验证集    (由于这里没有分配测试集,所以测试集为空。若要分配测试集,需要更改第 14、15 行的代码,即更改对应的比例)

 3.2. XML格式转yolo_txt格式

在VOCData目录下创建程序 text_to_yolo.py 并运行

程序如下:

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd

sets = ['train', 'val', 'test']
classes = ["bottle"]  # 改为自己的类别
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('D:/Yolov5/yolov5/VOCData/Annotations/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('D:/Yolov5/yolov5/VOCData/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
        # 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('D:/Yolov5/yolov5/VOCData/labels/'):
        os.makedirs('D:/Yolov5/yolov5/VOCData/labels/')
    image_ids = open('D:/Yolov5/yolov5/VOCData/ImageSets/Main/%s.txt' % (image_set)).read().strip().split()

    if not os.path.exists('D:/Yolov5/yolov5/VOCData/dataSet_path/'):
        os.makedirs('D:/Yolov5/yolov5/VOCData/dataSet_path/')

    list_file = open('D:/Yolov5/yolov5/VOCData/dataSet_path/%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        list_file.write('D:/Yolov5/yolov5/VOCData/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

程序运行完成后,会生成 labels 文件夹和 dataSet_path 文件夹。

其中 labels 中为不同图像的标注文件。每个图像对应一个txt文件,文件每一行为一个目标的信息,分别为class, x_center, y_center, width, height,这种为 yolo_txt格式

 dataSet_path文件夹包含三个数据集的txt文件,train.txt等txt文件为划分后图像所在位置的路径,如train.txt就含有所有训练集图像的路径。

 4修改训练的配置文件

4.1 在 yolov5 目录下的 data 文件夹下 新建一个 myvoc.yaml文件(可以自定义命名)。

内容是:

训练集(train.txt)的路径

验证集(val.txt)的路径

目标的类别数目

类别名称。

模板如下:

train: D:/Yolov5/yolov5/VOCData/dataSet_path/train.txt
val: D:/Yolov5/yolov5/VOCData/dataSet_path/val.txt

# number of classes
nc: 2

# class names
names: ["bottle", "apple"]

4.2生成anchors

如果目录 yolov5/utils下有 autoanchor.py文件,那么就可以采用自动获取anchors。(yolov5版本偏低是没有的)

 确保 yolov5/data/hyps/hyp.cratch.yaml中的anchors这行是注释掉的

 采用自动法的话,不用运行,训练时自动调用

4.3修改模型配置文件

在yolov5目录下的model文件夹下是模型的配置文件,有n、s、m、l、x版本,逐渐增大(随着架构的增大,训练时间也是逐渐增大)。

 这里选择 yolov5s.yaml

 打开 yolov5s.yaml,最好将yolov5s.yaml文件复制一份,然后将其重命名,我将其重命名为yolov5_bottle.yaml。所有冒号后面需要加一个空格。

 找到train.py这个py文件。找到主函数,这里面有模型的主要参数,训练自己的模型需要修改如下几个参数就可以训练了。首先将weights权重的路径填写到对应的参数里面,然后将修好好的models模型的yolov5s.yaml文件路径填写到相应的参数里面,最后将data数据的hat.yaml文件路径填写到相对于的参数里面。这几个参数就必须要修改的参数。 

 还有几个需要根据自己的需求来更改的参数:首先是模型的训练轮次,这里是训练的100轮。

其次是输入图片的数量和工作的核心数,这里每个人的电脑都不一样,所以这里每个人和自己的电脑的性能来。这里可以根据我的电脑的配置做参考,我的电脑是拯救者2060版本的显卡,cpu的核心数是16核。我的电脑按默认的参数输入图片数量为16,工作核心为8的话就会出现GPU显存溢出的报错。每个人的电脑配置不一样,所以可以根据自己的电脑配置来修改参数。
 

或者在终端运行

python train.py --weights weights/yolov5s.pt  --cfg models/yolov5s.yaml  --data data/myvoc.yaml --epoch 200 --batch-size 8 --img 640   --device cpu

4.4训练过程

训练好的模型会被保存在 yolov5 目录下的 runs/train/weights/ 下

 4.5训练可视化

训练时或者训练后可以利用 tensorboard 查看训练可视化

在终端中进入到yolov5的文件夹,输入tensorboard --logdir=runs/train/exp4,我的为exp4(即为第四次训练),需要根据自己的情况来定。

tensorboard --logdir=runs/train/exp4

就会出现一个网址地址,将那行网址复制下来到浏览器打开就可以看到训练的过程了

 如果模型已经训练好了,但是我们还想用tensorbord查看此模型的训练过程,就需要输入如下的命令。就可以看到模型的训练结果了。

 5测试实验

    等数据训练好后,就会在主目录下产生一个run文件夹,在run/train/exp/weights目录下会产生两个权重文件,一个是最后一轮的权重文件,一个是最好的权重文件。找到主目录下的detect.py文件,打开该文件。然后找到主函数的入口,这里面有模型的主要参数。

第一行:需要将刚刚训练好的最好的权重传入到推理函数中去。然后就可以对图像视频进行推理。

第二行:对图片进行测试推理,将如下参数修改成图片的路径

运行detect.py就可以进行测试了。

 测试结束以后,在run下面会生成一个detect目录,推理结果会保存在exp目录下。

对视频进行测试,和如上的图片的测试是一样的,只不过是将图片的路径改为视频的路径而已

 利用摄像头进行测试只需将路径改写为0就好了。但是11报错如下。

解决方法:首先找到datasets.py这个py文件。  打开文件,找到第279行代码,给两个url参数加上str就可以了,如图所示,就可以完美运行电脑的摄像头了。 

 6参考连接

1.从0开始学视觉(5)——利用yolov5训练自己的目标检测模型_从0开始深度学习的博客-CSDN博客_yolov5训练自己的模型

2.Yolov5训练自己的数据集(详细完整版)_缔宇diyu的博客-CSDN博客_yolov5训练自己的数据集

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐