Yolov5训练自己的数据集

news2024/11/20 2:36:43

一、从官网下载最新的yolov5代码

二、新建VOCData文件夹

三、VOCData文件夹结构

  1. 新建Annotations文件夹,存放标签

简单的xml文件,应该长这样

复杂的xml文件,应该长这个样子

  1. 新建images文件夹,存放图片数据

注意:需要观察自己的图片文件的后缀名,后面需要用到,不然可能出现程序找不到图片的情况

3、新建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 = 0.7  # 训练集和验证集所占比例。 这里没有划分测试集
train_percent = 0.5     # 训练集所占比例,可自己进行调整
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()

运行之后,会发现VOCData文件夹里面多了ImageSets文件夹

里面包括四个txt文件

txt文件存储了图片的序号

4、新建xml_to_yolo.py,用于将xml格式的标签转化为yolo格式的标签

对于简单的xml文件,用下列代码

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

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

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

    list_file = open('dataSet_path/%s.txt' % (image_set), 'w')
    # 这行路径不需更改,这是相对路径
    for image_id in image_ids:
        list_file.write('D:/Project/yolov5Project/yolov5/VOCData/images/%s.jpg\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

对于复杂的xml文件,用下列代码。

该程序的功能:将Class_ID属于aircraft_carrier列表的物体标记为类别0,将Class_ID属于warcraft列表的物体标记为类别1,将Class_ID属于aircraft_carrier列表的物体标记为类别2,将Class_ID属于merchant_ship列表的物体标记为类别3。然后转化为yolo格式标签。

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

Class_1_num = 0
Class_2_num = 0
Class_3_num = 0
Class_4_num = 0

sets = ['train','test','val']
classes = ["ship"]  # 改成自己的类别
abs_path = os.getcwd()
print(abs_path)

aircraft_carrier = [100000005,100000006,100000012,100000013,100000031,100000032,100000033]
warcraft = [100000007,100000008,100000009,100000010,100000011,100000014,100000015,100000016,100000017,100000019,100000003,100000029]
merchant_ship = [100000018,100000022,100000024,100000018,100000025,100000026,100000030]
Submarine = [100000027]

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):
    global Class_1_num,Class_2_num,Class_3_num,Class_4_num
    in_file = open('./Annotations/%s.xml' % (image_id), encoding='UTF-8')
    out_file = open('./labels/%s.txt' % (image_id), 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    HRSC_Objects = root.find('HRSC_Objects')
    HRSC_Object = HRSC_Objects.find('HRSC_Object')

    if HRSC_Object!=None:
        for HRSC_Object in HRSC_Objects.iter('HRSC_Object'):
            Class_ID = int(HRSC_Object.find('Class_ID').text)

            if Class_ID in aircraft_carrier or Class_ID in warcraft or Class_ID in merchant_ship or Class_ID in Submarine:
                w = int(root.find('Img_SizeWidth').text)
                h = int(root.find('Img_SizeHeight').text)
                b = (float(HRSC_Object.find('box_xmin').text),float(HRSC_Object.find('box_xmax').text),float(HRSC_Object.find('box_ymin').text),float(HRSC_Object.find('box_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)
                if Class_ID in aircraft_carrier:
                    Class_1_num = Class_1_num+1
                    Class = 0
                if Class_ID in warcraft:
                    Class_2_num = Class_2_num+1
                    Class = 1
                if Class_ID in merchant_ship:
                    Class_3_num = Class_3_num+1
                    Class = 2
                if Class_ID in Submarine:
                    Class_4_num = Class_4_num+1
                    Class = 3
                out_file.write(str(Class) + " " + " ".join([str(a) for a in bb]) + '\n')


            else:
                print('do not caculate'+str(Class_ID))
                continue

wd = getcwd()


for image_set in sets:
    if not os.path.exists('./labels/'):
        os.makedirs('./labels/')
    image_ids = open('./ImageSets/Main/%s.txt' % (image_set)).read().strip().split()

    if not os.path.exists('./dataSet_path/'):
        os.makedirs('./dataSet_path/')

    list_file = open('./dataSet_path/%s.txt' % (image_set), 'w')
    # 这行路径不需更改,这是相对路径
    for image_id in image_ids:
        print('目前的图片id为:'+image_id)
        list_file.write('D:/Project/yolov5Project/yolov5_three_classifications/VOCData/images/%s.bmp\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()
print(Class_1_num)
print(Class_2_num)
print(Class_3_num)
print(Class_4_num)

运行后,会发现多了两个文件

dataSet_path文件中存储了训练集、测试集、验证集的绝对路径

labels存储了yolo格式的标签

5、进入data文件夹,新建mycov.yaml

myvoc.yaml的内容,其中,train与val为训练集与验证集列表的绝对路径

  1. 修改权重文件yolov5s.yaml

把类别改为我们设置的类别数量

7、开始训练

(1)训练

python train.py --weights weights/yolov5s.pt --cfg models/yolov5s.yaml --data data/myvoc.yaml --epoch 100 --batch-size 16 --img 640 --device 0

2)训练过程可视化

tensorboard --logdir=./runs

(3)测试训练出的网络模型

python detect.py --source data/images/000026.jpg --weights runs/train/exp10/weights/best.pt

1

一些常用命令:

(1)指定下载镜像源

pip install onnx -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

1

(2)制作数据集教程

(3)mAP说明

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156906.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.1.2半导体二极管的结构、工作原理、参数、伏安特性;

1.结构 内部实际上是一个PN结,将电极引线和其封装在一起就构成了二极管 拓展:点接触型二极管,面接触型二极管 2.工作原理 3.参数(以肖特基二极管SS56为例) MAX Forward Voltage(最大导通电压) ,因为SS5…

Jvm-hotspot 总结系列-完整版(1)类加载器

一、类加载器子系统的作用(1)类加载器子系统负责从文件系统或网络中加载class文件,class文件在文件开头有特定的文件标识(cafebabe)咖啡宝贝。(2)ClassLoader只负责class文件的加载,…

广告业务系统 之 核心通道 —— “日志中心-s2s监测上报”

文章目录广告业务系统 之 核心通道 —— “日志中心-s2s监测上报”s2s 监测上报s2s 、c2s曝光/互动/Win数据上报监测上报AB 实验平台广告业务系统 之 核心通道 —— “日志中心-s2s监测上报” s2s 监测上报 s2s 监测上报,是 ADX 将广告的曝光、互动[点击/播放/下载…

赛事推荐 | 建筑物细粒度实例分割——2023 IEEE GRSS 数据融合赛道1

1. 赛题名称 建筑物检测和屋顶类型分类 2. 赛题背景 该轨道侧重于从高分辨率卫星光学图像和 SAR 图像中检测和分类建筑物屋顶类型。SAR 和光学模态有望提供补充信息。给定的数据集涵盖了全球六大洲的十七个城市。分类任务由 12 种细粒度的预定义屋顶类型组成。图 1 显示了一…

缺乏长线思考是扼杀工程师前途的屠刀.

缺乏长线思考是扼杀工程师前途的屠刀。 死局 工作几年后,最容易陷入一个隐形的死局,开发只关注实现需求,运维只关注部署、故障。待到七八年,一定会出现后继无力。被替代,早晚而已。 我相信很多领导都讲过沉淀方法论&am…

RK3399平台开发系列讲解(内核调试篇)如何使用perf进行性能优化

🚀返回专栏总目录 文章目录 一、perf list命令二、perf record/report命令三、perf stat命令四、perf top命令五、火焰图沉淀、分享、成长,让自己和他人都能有所收获!😄 📢perf 可以在 CPU Usage 增高的节点上找到具体的引起 CPU 增高的函数,然后我们就可以有针对性地…

开源PPP软件PRIDE-PPPAR使用记录(一)GFZRNX预处理

我们使用PRIDE-PPPAR软件对GNSS观测数据进行解算时,会遇到观测文件不能识别的问题。观测文件不能识别的主要原因是格式不对,可通过GNSS预处理软件进行修复。本文介绍一款由德国波兹坦地学研究中心(GFZ)开发的GNSS预处理软件GFZRNX…

Mathorcup数学建模竞赛第六届-【妈妈杯】B题:车位分布的优化设计与评价(附一等奖获奖论文、lingo和matlab代码)

赛题描述 随着现代社会经济的快速发展,房地产成为国家经济发展中重要的经济增长点之一。而小区内汽车停车位的分布对于小区居民的上下班出行影响很大。请建立数学模型,解决下列问题: 问题1:分析评判小区汽车停车位分布是否合理的几个关键指标,建立评判车位分布合理的数学…

Qt之单选按钮和复选按钮(QRadioButton、QCheckBox)

文章目录QRadioButton属性示例代码:QCheckBox属性示例代码QRadioButton QRadioButton片这个按钮类应对多选一的场景。打开windows的画图软件,我们就可以看到下面的: 如果我们刚开始的是线,然后我们又想画矩形,则线这…

作用域、生命期和程序的组织结构

一、局部变量和全局变量 在函数内部或复合语句中定义的变量,称为局部变量(local variable)。 (1)在一个函数内部定义的变量; (2)函数的形式参数; (3&…

微信小程序基础篇-模板与配置

本篇学习目标使用WXML渲染模板语法渲染页面结构使用WXSS样式美化结构使用app.json对项目进行全局配置使用page.json对页面进行个性化配置如何发起网络请求1.WXML模板语法1.1 数据绑定在data中定义数据:在页面的js文件在data对象中定义在wxml中使用数据:使…

记一次Windows Terminal的安装和配置

换的原因 之前一直用的cmder,结果突然一次更新之后,delete文本后显示文本错误,于是就换成Window Terminal了 安装 进微软商店搜或者官网跳转到微软商店 下载完后在winr里用wt可以进入 配置外观 配置(因为我是已经配好再写博客…

【微服务笔记05】微服务组件之Ribbon负载均衡器组件介绍及其使用

这篇文章,主要介绍微服务组件之Ribbon负载均衡器及其使用。 目录 一、Ribbon负载均衡器 1.1、负载均衡介绍 (1)负载均衡概念 (2)负载均衡分类 (3)Ribbon负载均衡思想 1.2、Ribbon的使用 …

Mybatis一发入魂

文章目录Mybatis官方中文文档一、Mybatis简介二、简单入门使用2.1、在pom.xml中添加依赖2.2、使用xml配置文件2.3、创建接口2.4、创建映射文件2.6、获取sqlsession实例并执行方法三、Mybatis的Xml配置文件3.1、properties属性3.2、settings设置3.3、typeAliases类型别名3.4、en…

试题 基础练习 高精度加法(java)

试题 基础练习 高精度加法提交此题 评测记录 资源限制内存限制:512.0MB C/C时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s问题描述输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。算法描述由于a和b…

《架构300讲》学习笔记(151-200)

前言 内容来自B站IT老齐架构300讲内容。 151 Redis发布订阅机制是如何实现的? 152 阿里Seata分布式事务AT、TCC、SAGA、XA模式到底该怎么选? 153 超级实用!十分钟掌握Prometheus与Grafana监控SpringBoot应用 154 如何利用Docker快速构建…

Java面试题每日10问(7)

Core Java - OOPs Concepts: final keyword Interview Questions 1. What is the final variable? the final variable is used to restrict the user from updating it.If we initialize the final variable, we can’t change its value.The final variable - which is not…

论文阅读笔记《Multilevel Graph Matching Networks for Deep Graph Similarity Learning》

核心思想 本文提出一种多级图匹配网络(MGMN)用于图相似性的度量。常见的图相似性网络都是利用图神经网络或其他图嵌入技术将整幅图转化为特征向量,然后计算两个特征向量之间的相似程度。这种做法的缺点在于只关注了图一级的信息交互&#xff…

【随风丶逆风】2022年终总结

前言 又到了一年一度的年终总结了,回顾一年可谓一波三折,感慨良多,最有感触的大概就是疫情带来各种影响吧,经济下行、市场不景气、互联网寒冬。 回顾去年年终规划《【随风丶逆风】2021年终总结》,整体低于预期&#x…

ArcGIS基础实验操作100例--实验83查找点集中最近最远点

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台:ArcGIS 10.6 实验数据:请访问实验1(传送门) 高级编辑篇--实验83 查找点集中最近最远点 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff0…