yolov5 训练自己的数据集,怎样组织数据集结构

yolov5 训练自己的数据集,怎样组织数据集结构

​ yolov5官方写了一个教程来说明怎么用yolov5模型来训练自己的数据集,https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data,这里对官方文档的一些关键点进行说明。

1.创建自己的data.yaml

在训练时,需要在yolov5/data/文件夹中为自己的数据集创建一个data.yaml文件,指明数据集图片和标签的存放地址,以及类别的数目和名称,首先来看官方的coco128.yaml文件

# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]

train: ../coco128/images/train2017/    #指定训练集图片存放的地址
val: ../coco128/images/train2017/

# number of classes
nc: 80

# class names
names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
        'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
        'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
        'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
        'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
        'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 
        'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 
        'teddy bear', 'hair drier', 'toothbrush']

图片的存放地址可以用三种方式来表达

  • 给定一个 目录:里面存放着图片的路径加图片名 见coco128.yaml

  • 给定一个 txt文件:里面存放着图片的路径和图片名,见coco.yaml

  • 给定一个 列表

比如对coco128数据集进行训练

python train.py --img 640 --batch 16 --epochs 5 --data coco128.yaml --weights yolov5s.pt

train.pyyolov5文件夹下,此时的工作路径就是yolov5,在coco128.yaml中指定了train(训练集的路径),那么系统就会在yolov5+train这个路径下去寻找训练集的图片,也就是

../coco128/images/train2017/所以如果按照这个路径命名方式,就要将coco128文件夹放在yolov5相邻的地方,而不是作为yolov5的子文件夹。(当然也可以通过修改train的值去指定自己其他任何路径,但是要记住是以yolov5作为当前工作目录)

在data.yaml文件中既然没有定义labels的路径,那么 YOLOV5是怎么定义label路径的呢?

YOLOv5 locates labels automatically for each image by replacing the last instance of /images/ in each image path with /labels/.

也就是如果图片的路径为:

../coco128/images/train2017/img001.jpg

那么labels必须为

../coco128/labels/train2017/img001.txt

一张图片对应一个txt文件,路径除了将最后一个images换成labels,没有任何不同不然就会找不到labels。

具体格式要求

  • One row per object
  • Each row is class x_center y_center width height format.
  • Box coordinates must be in normalized xywh format (from 0 - 1). If your boxes are in pixels, divide x_center and width by image width, and y_center and height by image height.
  • Class numbers are zero-indexed (start from 0).

在这里插入图片描述
在这里插入图片描述

最后根据自己最终预测出的类别的数量和名称,修改 nc 和 names两项,就可以开始训练了。

我的数据集

mydata.yaml

# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: /home/yyz/yolov5/mydataset/ppe_yolov5_dataset/train.txt  # 118287 images
val: /home/yyz/yolov5/mydataset/ppe_yolov5_dataset/valid.txt  # 5000 images
test: /home/yyz/yolov5/mydataset/ppe_yolov5_dataset/test.txt  # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794

# number of classes
nc: 4

# class names
names: [ 'W', 'WH', 'WV', 'WHV' ]

train.txt

/home/yyz/yolov5/mydataset/ppe_yolov5_dataset/images/image_from_china(1).jpg
/home/yyz/yolov5/mydataset/ppe_yolov5_dataset/images/image_from_china(1).jpg
/home/yyz/yolov5/mydataset/ppe_yolov5_dataset/images/image_from_china(10).jpg
....
....

/home/yyz/yolov5/mydataset/ppe_yolov5_dataset/images/labels

在这里插入图片描述

image_from_china\(279\).txt

0 0.400493 0.397366 0.026316 0.122942
1 0.849095 0.496707 0.064967 0.12843
0 0.150082 0.350714 0.028783 0.113063
转换脚本
# coding:utf-8
#将第一列拆分出来
f = open('Labels\\pictor_ppe_crowdsourced_approach-02_test.txt')  # 打开txt文件
line = f.readline()  # 以行的形式进行读取文件
list1 = []
while line:
    a = line.split()
    b = a[0:1]       # 这是选取需要读取的列
    list1.append(b)  # 将其添加在列表之中
    line = f.readline()
f.close()

path_out = 'test.txt'   # 新的txt文件
t = ''
with open(path_out, 'w+') as f_out:
    for i in list1:
        for j in range(len(list1[0])):
            t = t + str(i[j])
        f_out.write(t)
        f_out.write('\n')
        t = ''

f=open('test.txt')
lines=f.readlines() #整行读取
f.close()
for line in lines:
    rs = line.rstrip('\n')  # 去除原来每行后面的换行符,但有可能是\r或\r\n
    #newname = rs.replace(rs)
    newfile = open('test.txt', 'a')
    newfile.write(rs + '\n')
    newfile.close()
"""
将 filename <object-class> <x> <y> <width> <height>
image_from_china(1015).jpg	137,556,186,703,1	246,544,323,685,1	0,614,23,725,0	477,131,512,179,1	906,76,938,146,1	926,41,953,109,1
image_from_china(1023).jpg	764,0,1215,688,0
.....
格式的labels文件转换为
  filename.txt中有class id, x, y, w, h
  并进行标准化
"""

import os,sys
from PIL import Image

if not os.path.exists("labels"):
    os.makedirs("labels")

f = open('Labels\\pictor_ppe_crowdsourced_approach-02_valid.txt')  # 打开txt文件
line = f.readline()  # 以行的形式进行读取文件
files_name = []    #定义一个空字符串来装第一列
files_value = []

while line:
    a = line.split()
    list1 = a[0]       # 假设第N次运行,第N行的第一列
    im = Image.open('ppe_yolov5_dataset\\Images\\' + list1)
    im_w = im.size[0]
    im_h = im.size[1]
    v5label = ''

    for i in range( len(a)-1 ):
        #obj = a[i]   #将文件名去掉了,一个单独的框
        #'left(x1),top(y1),right(x2),bottom(y2),class'
        leftx1 = a[i+1].split(',')[0]
        topy1 = a[i + 1].split(',')[1]
        rightx2 = a[i + 1].split(',')[2]
        bottomy2 = a[i + 1].split(',')[3]
        objclass = a[i + 1].split(',')[4]
        x_truth = (int(rightx2) + int(leftx1)) / 2
        y_truth = (int(bottomy2) + int(topy1)) / 2
        w_truth = (int(rightx2) - int(leftx1))
        h_truth = (int(bottomy2) - int(topy1))

        x = round((x_truth / im_w),6)
        y = round((y_truth / im_h),6)
        w = round((w_truth / im_w),6)
        h = round((h_truth / im_h),6)

        # <object-class> <x> <y> <width> <height>,且归一化,空格隔开,直接加逗号是元祖
        v5label = v5label + objclass+' '+str(x)+' '+str(y)+' '+str(w)+' '+str(h)+'\n'

    files_name = list1[:-4]  # 去掉字符串最后四个 .jpg后缀
    fs = open("ppe_yolov5_dataset\\labels\\valid\\" + files_name + ".txt", "w")
    fs.write(v5label)
    fs.close()
    # files_name = list1[:-4]   #去掉字符串最后四个 .jpg后缀
    # with open("test\\"+files_name+".txt", "w") as fs:
    #     fs.write(files_value)
    #     fs.close()   #不要跟f重复,记得关闭文件
    line = f.readline()   #这样就会读取下一行
f.close()
#将图片转换为train.txt文件中包括了所有的训练集图片的路径
f = open('Labels\\pictor_ppe_crowdsourced_approach-02_valid.txt')  # 打开txt文件
line = f.readline()  # 以行的形式进行读取文件
list1 = []
img_dir = ''
while line:
    qianzhui = ['/home/yyz/yolov5/mydataset/ppe_yolov5_dataset/images/']
    a = line.split()
    b = a[0:1]       # 这是选取需要读取的列
    qianzhui.extend(b)
    img_dir = img_dir + ''.join(qianzhui) + '\n'
    fs = open('valid.txt','a')
    fs.write(img_dir)
    fs.close()
    line = f.readline()
f.close()

path_out = 'test.txt'   # 新的txt文件
t = ''
with open(path_out, 'w+') as f_out:
    for i in list1:
        for j in range(len(list1[0])):
            t = t + str(i[j])
        f_out.write(t)
        f_out.write('\n')
        t = ''
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值