制作自己的数据集并训练的YOLOv8模型

news/2024/7/10 22:59:17 标签: YOLO, yolov8, 深度学习

文章目录

    • 1.制作数据集
      • 1.1 下载安装labelImg
      • 1.2 开始制作数据集
    • 准备训练
    • 分配数据集
    • 训练
    • 测试

1.制作数据集

1.1 下载安装labelImg

LabelImg源码

下载好源码并 cd到源码路径下
安装需要的环境

# 安装lxml
pip install lxml
 
# 安装pyqt5
pip install pyqt5

# 将"resources.qrc" 文件编译成 Python 代码,并将输出到 "libs/resources.py" 文件中
pyrcc5 -o libs/resources.py resources.qrc
# 启动labelImg
python labelimg.py

1.2 开始制作数据集

在这里插入图片描述
打开data/predefined_classes.txt,修改默认类别,也可以直接清空,后面打标签的时候会自动生成,我这里将这个文件清空。

在这里插入图片描述
点击“创建区块” 开始打标签
在这里插入图片描述

准备训练

可以参考ultralytics官方安装教程

# 创建一个用于训练的虚拟环境
conda create --name YOLOv8_ultralytics python=3.8
#启动训练环境
conda activate YOLOv8_ultralytics

PyTorch 要求因操作系统和 CUDA 要求而异,因此建议先按照 https://pytorch.org/get-started/locally 中的说明安装 PyTorch。

#我这里cuda是11.6
conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 pytorch-cuda=11.6 -c pytorch -c nvidia
#安装ultralytics
pip install ultralytics

分配数据集

  1. 新建文件夹 datasets/data/images
    然后将图片和标签全部放到这个文件夹下。

  2. 在datasets下新建一个分配数据集数据的脚本文件Process.py

import os
import random
import shutil

def split_dataset(data_dir,train_val_test_dir, train_ratio, val_ratio, test_ratio):
    # 创建目标文件夹
    train_dir = os.path.join(train_val_test_dir, 'train')
    val_dir = os.path.join(train_val_test_dir, 'val')
    test_dir = os.path.join(train_val_test_dir, 'test')
    os.makedirs(train_dir, exist_ok=True)
    os.makedirs(val_dir, exist_ok=True)
    os.makedirs(test_dir, exist_ok=True)

    # 获取数据集中的所有文件
    files = os.listdir(data_dir)

    # 过滤掉非图片文件
    image_files = [f for f in files if f.endswith('.jpg') or f.endswith('.png')]
    # 随机打乱文件列表
    random.shuffle(image_files)

    # 计算切分数据集的索引
    num_files = len(image_files)
    num_train = int(num_files * train_ratio)
    num_val = int(num_files * val_ratio)
    num_test = num_files - num_train - num_val

    # 分离训练集
    train_files = image_files[:num_train]
    for file in train_files:
        src_image_path = os.path.join(data_dir, file)
        src_label_path = os.path.join(data_dir, file.replace('.jpg', '.txt').replace('.png', '.txt'))
        dst_image_path = os.path.join(train_dir, file)
        dst_label_path = os.path.join(train_dir, file.replace('.jpg', '.txt').replace('.png', '.txt'))
        shutil.copy(src_image_path, dst_image_path)
        shutil.copy(src_label_path, dst_label_path)

    # 分离验证集
    val_files = image_files[num_train:num_train+num_val]
    for file in val_files:
        src_image_path = os.path.join(data_dir, file)
        src_label_path = os.path.join(data_dir, file.replace('.jpg', '.txt').replace('.png', '.txt'))
        dst_image_path = os.path.join(val_dir, file)
        dst_label_path = os.path.join(val_dir, file.replace('.jpg', '.txt').replace('.png', '.txt'))
        shutil.copy(src_image_path, dst_image_path)
        shutil.copy(src_label_path, dst_label_path)

    # 分离测试集
    test_files = image_files[num_train+num_val:]
    for file in test_files:
        src_image_path = os.path.join(data_dir, file)
        src_label_path = os.path.join(data_dir, file.replace('.jpg', '.txt').replace('.png', '.txt'))
        dst_image_path = os.path.join(test_dir, file)
        dst_label_path = os.path.join(test_dir, file.replace('.jpg', '.txt').replace('.png', '.txt'))
        shutil.copy(src_image_path, dst_image_path)
        shutil.copy(src_label_path, dst_label_path)

    print("数据集分离完成!")
    print(f"训练集数量:{len(train_files)}")
    print(f"验证集数量:{len(val_files)}")
    print(f"测试集数量:{len(test_files)}")

def move_files(data_dir):
    # 创建目标文件夹
    images_dir = os.path.join(data_dir, 'images')
    labels_dir = os.path.join(data_dir, 'labels')
    os.makedirs(images_dir, exist_ok=True)
    os.makedirs(labels_dir, exist_ok=True)

    # 获取数据集中的所有文件
    files = os.listdir(data_dir)

    # 移动PNG文件到images文件夹
    png_files = [f for f in files if f.endswith('.png')]
    for file in png_files:
        src_path = os.path.join(data_dir, file)
        dst_path = os.path.join(images_dir, file)
        shutil.move(src_path, dst_path)

    # 移动TXT文件到labels文件夹
    txt_files = [f for f in files if f.endswith('.txt')]
    for file in txt_files:
        src_path = os.path.join(data_dir, file)
        dst_path = os.path.join(labels_dir, file)
        shutil.move(src_path, dst_path)

    print(f"{data_dir}文件移动完成!")
    print(f"总共移动了 {len(png_files)} 个PNG文件到images文件夹")
    print(f"总共移动了 {len(txt_files)} 个TXT文件到labels文件夹")


# 设置数据集路径和切分比例
data_dir = './data/images'      # 图片和标签路径
train_val_test_dir= './data'    # 目标文件夹
train_ratio = 0.7               # 训练集比例
val_ratio = 0.2                 # 验证集比例
test_ratio = 0.1                # 测试集比例

# 调用函数分离数据集
split_dataset(data_dir, train_val_test_dir,train_ratio, val_ratio, test_ratio)
# 调用函数移动文件
move_files(os.path.join(train_val_test_dir, 'train'))
move_files(os.path.join(train_val_test_dir, 'val'))
move_files(os.path.join(train_val_test_dir, 'test'))

  1. 在datasets下运行这个脚本,然后生成这样的文件结构
    在这里插入图片描述
  2. 在datasets同级目录下新建一个mydata.yaml文件
train: ./data/train/images
val: ./data/val/images
test: ./data/test/images

# 类别数
nc: 4

# 类别名称
names: ['CCTV2','fivestar','CCTV3',"CCTV1"]

训练

在datasets同级路径下新建train.py 训练脚本

from ultralytics import YOLO

# Load a model
#model = YOLO('yolov8n.yaml')  # build a new model from YAML
model = YOLO('yolov8n.pt')  # load a pretrained model (recommended for training)
#model = YOLO('yolov8n.yaml').load('yolov8n.pt')  # build from YAML and transfer weights


# Train the model
model.train(data='./mydata.yaml', epochs=100, imgsz=640)

测试

在datasets同级路径下新建test.py测试脚本

from PIL import Image
from ultralytics import YOLO

# Load a pretrained YOLOv8n model
model = YOLO('./runs/detect/train/weights/last.pt')

# Run inference on 'bus.jpg'
results = model('./test1.png')  # results list

# Show the results
for r in results:
    im_array = r.plot()  # plot a BGR numpy array of predictions
    im = Image.fromarray(im_array[..., ::-1])  # RGB PIL image
    im.save('results.jpg')  # save image


http://www.niftyadmin.cn/n/4947950.html

相关文章

管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——选言——相容/不相容选言+联言

第四节 不相容选言+相容选言-要么,要么-包含相容-“要么A要么B”为真→“A或B”为真 题—不相容选言-要么A要么B-恰有一真才真,全真全假才假- 1.某山区发生了较大面积的森林病虫害。在讨论农药的使用时,老许提出:“要么使用甲胺磷等化学农药,要么使用生物农药。前者过去…

统计XML标注文件中各标注类别的标签数量

目标检测任务重,担心数据集中各标签类别不均衡,想统计XML标注文件中各标注类别的标签数量,可以使用以下脚本: import os import glob import xml.etree.ElementTree as etdef count_labels(source_dir):file_list glob.glob(os.…

elementui 修改日期选择器el-date-picker样式

1. 案例: 2. css /* 最外层颜色 */ .el-popper.is-pure {background: url("/assets/imgList/memuBG.png") no-repeat;border: none;background-size:100% 100%}/* 日期 1.背景透明 */ .el-date-picker{background: transparent; }/* 日期 2.标题、左右图…

【nodejs】用Node.js实现简单的壁纸网站爬虫

1. 简介 在这个博客中,我们将学习如何使用Node.js编写一个简单的爬虫来从壁纸网站获取图片并将其下载到本地。我们将使用Axios和Cheerio库来处理HTTP请求和HTML解析。 2. 设置项目 首先,确保你已经安装了Node.js环境。然后,我们将创建一个…

关于Java:使用prepare语句的动态Sql查询

Dynamic Sql qyery using prepare statement 我想创建一个动态查询来过滤产品。我要从"产品"表中过滤产品 根据某些参数,例如 牌味道价钱尺寸类型 我正在创建一个函数,在其中我正在执行MySQL查询,我想检查用户使用了哪个参数&…

WebSocket服务端数据推送及心跳机制(Spring Boot + VUE)

一、WebSocket简介 HTML5规范在传统的web交互基础上为我们带来了众多的新特性,随着web技术被广泛用于web APP的开发,这些新特性得以推广和使用,而websocket作为一种新的web通信技术具有巨大意义。WebSocket是HTML5新增的协议,它的…

Flink学习笔记(一)

流处理 批处理应用于有界数据流的处理,流处理则应用于无界数据流的处理。 有界数据流:输入数据有明确的开始和结束。 无界数据流:输入数据没有明确的开始和结束,或者说数据是无限的,数据通常会随着时间变化而更新。 在…

neovim为工作区添加本地clangd配置

1 背景 尝试使用neovim开发stm32,使用clangd作为LSP提供代码补全等功能。 2 思路 使用stm32cubeMX生成一个基于makefile的stm32工程。 使用bear或compiledb基于makefile生成compile_commands.json文件。 为clangd配置--query-driver选项,使其使用arm…