YOLOV8实例分割——详细记录环境配置、自定义数据处理到模型训练与部署

news2024/11/20 20:26:21

前言

Ultralytics YOLOv8是一种前沿的、最先进的(SOTA)模型,它在前代YOLO版本的成功基础上进行了进一步的创新,引入了全新的特性和改进,以进一步提升性能和灵活性。作为一个高速、精准且易于操作的设计,YOLOv8在广泛的领域中,包括目标检测与跟踪、实例分割、图像分类以及姿势估计等任务中,都表现出色。
实例分割在物体检测的基础上迈出了更进一步的步伐,它不仅可以识别图像中的单个物体,还能够精确地将这些物体从图像的其他部分中分割出来。
目标识别:
在这里插入图片描述
实例分割模型的输出是一组mask(或轮廓),这些遮罩清晰地勾勒出图像中的每个对象,同时还提供了每个对象的类别标签和置信度分数。当需要了解物体的准确形状时,实例分割变得非常有用,因为这不仅仅是关于物体位置的信息。
实例分割:
在这里插入图片描述

一、环境安装

1.直接安装

yolov8有两种安装方式,一种可直接安装U神的库,为了方便管理,还是在conda里面安装:

conda create -n yolov8 python=3.8
pip install ultralytics

2.源码安装

源码安装时,要单独安装torch,要不然训练的时候,有可能用不了GP,我的环境是cuda 11.7。

#新建虚拟环境
conda create -n yolov8 python=3.8
#激活
conda activate yolov8
#安装torch,
conda install pytorch==2.0.0 torchvision==0.15.0 torchaudio==2.0.0 pytorch-cuda=11.7 -c pytorch -c nvidia
#下载源码
git clone https://github.com/ultralytics/ultralytics.git

cd ultralytics
#将requirements.txt中torch torchbision 注释掉,下载其他包
pip install -r requirements.txt

3.验证

安装完成之后,验证是否安装成功。

yolo task=segment mode=predict model=yolov8s-seg.pt source='1.jpg' show=True

在这里插入图片描述

4.安装错误

1.OMP: Error #15: Initializing libomp.dylib, but found libiomp5.dylib already initialize
如果在训练时出现这个错误,要么就降低numpy的版本,要么就是python的版本太高,降到3.9以下就可以了。

二、数据处理

1.数据集标注

标注工具是使用LabelMe进行标注,LabelMe允许用户在图像中绘制边界框、多边形、线条和点等来标注不同类型的对象或特征。也可以标注标注类别,用户可以定义不同的标注类别,使其适应不同的项目需求。每个类别都可以有自己的名称和颜色。
这里标注了湖面的区域,用来做目标入侵检测。
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
标注出来的数据格式是json如下:
在这里插入图片描述

2.数据集转换

标注完数据之后,在工程目录下创建一个dataset目录,dataset目录下包含有images、json_labels、labels三个目录,images存放数据集的所有的图像,json_labels目录下存放labelme标注出来的所有json标签,labels为空目录。
在这里插入图片描述
在当前目录下创建json2txt.py文件

# -*- coding: utf-8 -*-
import json
import os
import argparse
from tqdm import tqdm
import glob
import cv2
import numpy as np


def convert_label_json(json_dir, save_dir, classes):
    json_paths = os.listdir(json_dir)
    classes = classes.split(',')

    for json_path in tqdm(json_paths):
        # for json_path in json_paths:
        path = os.path.join(json_dir, json_path)
        # print(path)
        with open(path, 'r') as load_f:
            print(load_f)
            json_dict = json.load(load_f, )
        h, w = json_dict['imageHeight'], json_dict['imageWidth']

        # save txt path
        txt_path = os.path.join(save_dir, json_path.replace('json', 'txt'))
        txt_file = open(txt_path, 'w')

        for shape_dict in json_dict['shapes']:
            label = shape_dict['label']
            label_index = classes.index(label)
            points = shape_dict['points']

            points_nor_list = []

            for point in points:
                points_nor_list.append(point[0] / w)
                points_nor_list.append(point[1] / h)

            points_nor_list = list(map(lambda x: str(x), points_nor_list))
            points_nor_str = ' '.join(points_nor_list)

            label_str = str(label_index) + ' ' + points_nor_str + '\n'
            txt_file.writelines(label_str)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='json convert to txt params')
    parser.add_argument('--json-dir', type=str, default='dataset/json_labels', help='json path dir')
    parser.add_argument('--save-dir', type=str, default='dataset/labels', help='txt save dir')
    parser.add_argument('--classes', type=str, default='surface', help='classes')
    args = parser.parse_args()
    json_dir = args.json_dir
    save_dir = args.save_dir
    classes = args.classes
    convert_label_json(json_dir, save_dir, classes)

运行json2txt.py之后,在labels里面生成txt标签文件,格式如下:

0 0.0019379844961240355 0.411190053285968 0.034496124031007755 0.41222272708496843 0.06705426356589148 0.411190053285968 0.08565891472868217 0.4163534222809699 0.1290697674418605 0.4235821388739725 0.17790697674418607 0.42771283406997396 0.23527131782945737 0.42771283406997396 0.34147286821705425 0.42771283406997396 0.3724806201550388 0.42151679127597175 0.37868217054263564 0.44113759345697884 0.42054263565891475 0.44630096245198064 0.9972868217054264 0.5227188235780081 0.9972868217054264 0.9946507497211781 0.0019379844961240355 0.9946507497211781

转换之后,一定要使用代码验证所转的数据是否正确:

def check_labels(txt_labels, images_dir):
    txt_files = glob.glob(txt_labels + "/*.txt")
    for txt_file in txt_files:
        filename = os.path.splitext(os.path.basename(txt_file))[0]

        pic_path = images_dir + filename + ".jpg"

        img = cv2.imread(pic_path)
        height, width, _ = img.shape

        file_handle = open(txt_file)
        cnt_info = file_handle.readlines()
        new_cnt_info = [line_str.replace("\n", "").split(" ") for line_str in cnt_info]

        color_map = {"0": (0, 255, 255)}
        for new_info in new_cnt_info:
            print(new_info)
            s = []
            for i in range(1, len(new_info), 2):
                b = [float(tmp) for tmp in new_info[i:i + 2]]
                s.append([int(b[0] * width), int(b[1] * height)])
            cv2.polylines(img, [np.array(s, np.int32)], True, color_map.get(new_info[0]))
        cv2.namedWindow('img2', 0)
        cv2.imshow('img2', img)
        cv2.waitKey()

调用函数,显示转换后的效果:
在这里插入图片描述

3.数据集分割

一般数据集划分为训练集和验证集是在开发深度学习模型时的常见做法。这种划分有助于评估模型的性能并进行超参数调整,以便提高模型的泛化能力。通常,常见的训练集和验证集的划分比例是9:1或者8:2,其中训练集占大部分,验证集占较小部分。
关训练集和验证集划分的指导原则:
数据量考虑: 数据集的大小是选择划分比例的一个关键因素。如果数据集较小,可能希望将更大的比例分配给训练集,以确保模型有足够的数据来学习。
数据的随机性: 确保在划分数据集时要随机混洗数据,以防止数据集中的任何特定模式或顺序影响模型的性能评估。
代表性: 确保训练集和验证集都代表了整个数据集的不同方面,以避免在验证模型性能时出现偏差。
交叉验证: 对于较小的数据集,您可以考虑使用交叉验证,将数据划分为多个折(folds),并在每次训练中使用不同的折作为验证集,从而更全面地评估模型性能。
超参数调整: 验证集通常用于调整模型的超参数,例如学习率、正则化强度等,以获得更好的性能。
不要在验证集上过拟合: 避免在验证集上进行过多的超参数调整或模型选择,以免模型在验证集上产生过拟合。
划分数据集的目的是确保模型在未见过的数据上具有良好的泛化能力。选择适当的训练集和验证集比例以及遵循上述指导原则将有助于提高深度学习项目的成功率。
数据集分割spilit_dataset.py代码:

# -*- coding:utf-8 -*
import os
import random
import os
import shutil
def data_split(full_list, ratio):

    n_total = len(full_list)
    offset = int(n_total * ratio)
    if n_total == 0 or offset < 1:
        return [], full_list
    random.shuffle(full_list)
    sublist_1 = full_list[:offset]
    sublist_2 = full_list[offset:]
    return sublist_1, sublist_2


train_p="dataset/train"
val_p="dataset/val"
imgs_p="images"
labels_p="labels"

#创建训练集
if not os.path.exists(train_p):#指定要创建的目录
    os.mkdir(train_p)
tp1=os.path.join(train_p,imgs_p)
tp2=os.path.join(train_p,labels_p)
print(tp1,tp2)
if not os.path.exists(tp1):#指定要创建的目录
    os.mkdir(tp1)
if not os.path.exists(tp2):  # 指定要创建的目录
    os.mkdir(tp2)

#创建测试集文件夹
if not os.path.exists(val_p):#指定要创建的目录
    os.mkdir(val_p)
vp1=os.path.join(val_p,imgs_p)
vp2=os.path.join(val_p,labels_p)
print(vp1,vp2)
if not os.path.exists(vp1):#指定要创建的目录
    os.mkdir(vp1)
if not os.path.exists(vp2):  # 指定要创建的目录
    os.mkdir(vp2)

#数据集路径
images_dir="D:/DL/ultralytics/dataset/images"
labels_dir="D:/DL/ultralytics/dataset/labels"
#划分数据集,设置数据集数量占比
proportion_ = 0.9 #训练集占比

total_file = os.listdir(images_dir)

num = len(total_file)  # 统计所有的标注文件
list_=[]
for i in range(0,num):
    list_.append(i)

list1,list2=data_split(list_,proportion_)

for i in range(0,num):
    file=total_file[i]
    print(i,' - ',total_file[i])
    name=file.split('.')[0]
    if i in list1:
        jpg_1 = os.path.join(images_dir, file)
        jpg_2 = os.path.join(train_p, imgs_p, file)
        txt_1 = os.path.join(labels_dir, name + '.txt')
        txt_2 = os.path.join(train_p, labels_p, name + '.txt')
        if os.path.exists(txt_1) and os.path.exists(jpg_1):
            shutil.copyfile(jpg_1, jpg_2)
            shutil.copyfile(txt_1, txt_2)
        elif os.path.exists(txt_1):
            print(txt_1)
        else:
            print(jpg_1)

    elif i in list2:
        jpg_1 = os.path.join(images_dir, file)
        jpg_2 = os.path.join(val_p, imgs_p, file)
        txt_1 = os.path.join(labels_dir, name + '.txt')
        txt_2 = os.path.join(val_p, labels_p, name + '.txt')
        shutil.copyfile(jpg_1, jpg_2)
        shutil.copyfile(txt_1, txt_2)

print("数据集划分完成: 总数量:",num," 训练集数量:",len(list1)," 验证集数量:",len(list2))

运行之后,在dataset下面多出train和val两个目录:
在这里插入图片描述
在这里插入图片描述

三、模型训练

1.数据文件

在ultralytics/cfg/datasets目录下复制一份coc128-seg.yaml复制ultralytics目录,重新命名成water-seg.yaml。
在这里插入图片描述
然后抒文件内容改成自己的数据路径:

# Ultralytics YOLO 🚀, AGPL-3.0 license
# COCO128-seg dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics
# Example usage: yolo train data=coco128.yaml
# parent
# ├── ultralytics
# └── datasets
#     └── coco128-seg  ← downloads here (7 MB)


# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: D:/DL/ultralytics  # dataset root dir
train: dataset/train  # train images (relative to 'path') 128 images
val: dataset/val  # val images (relative to 'path') 128 images
test:  # test images (optional)

# Classes
names:
  0: surface

# Download script/URL (optional)
download: https://ultralytics.com/assets/coco128-seg.zip

2.模型训练

模型训练有两种方式,直接pip安装ultralytics库的和源码安装的训练方法有差异。

2.1 直接安装ultralytics库

单卡

yolo detect train data=water-seg.yaml model=./weights/yolov8s-seg.pt epochs=150 imgsz=640 batch=4 workers=0

多卡训练

yolo detect train data=water-seg.yaml model=./weights/yolov8s-seg.pt epochs=150 imgsz=640 batch=4 workers= \'0,1,2,3\'

2.2 源码安装训练方法

在根目录下新建一个train.py的文件

'''
实例分割训练
'''
from ultralytics import YOLO

#train
model = YOLO('water-seg.yaml').load('yolov8s-seg.pt')  # build from YAML and transfer weights

# Train the model
model.train(data='./ultralytics/datasets/coco128-seg.yaml', epochs=150, imgsz=640,batch=2, workers=0)

3.参数说明

在这里插入图片描述

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

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

相关文章

合宙Air724UG LuatOS-Air LVGL API控件-标签 (Label)

标签 (Label) 标签是 LVGL 用来显示文字的控件。 示例代码 label lvgl.label_create(lvgl.scr_act(), nil) lvgl.label_set_recolor(label, true) lvgl.label_set_text(label, "#0000ff Re-color# #ff00ff words# #ff0000 of\n# align the lines …

Vision Transformer(VIT 网络架构)

论文下载链接&#xff1a;https://arxiv.org/abs/2010.11929 文章目录 引言1. VIT与传统CNN的比较2. 为什么需要Transformer在图像任务中&#xff1f; 1. 深入Transformer1.1 Transformer的起源&#xff1a;NLP领域的突破1.2 Transformer的基本组成1.2.1 自注意机制 (Self-Atte…

C++将派生类赋值给基类

在 C/C++ 中经常会发生数据类型的转换,例如将 int 类型的数据赋值给 float 类型的变量时,编译器会先把 int 类型的数据转换为 float 类型再赋值;反过来,float 类型的数据在经过类型转换后也可以赋值给 int 类型的变量。 数据类型转换的前提是,编译器知道如何对数据进行取舍…

星际争霸之小霸王之小蜜蜂(十)--鼠道

系列文章目录 星际争霸之小霸王之小蜜蜂&#xff08;九&#xff09;--狂鼠之灾 星际争霸之小霸王之小蜜蜂&#xff08;八&#xff09;--蓝皮鼠和大脸猫 星际争霸之小霸王之小蜜蜂&#xff08;七&#xff09;--消失的子弹 星际争霸之小霸王之小蜜蜂&#xff08;六&#xff09;-…

大数据课程K20——Spark的SparkSql概述

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Spark的SparkSQL由来; ⚪ 了解Spark的SparkSQL特点; ⚪ 了解Spark的SparkSQL优势; ⚪ 掌握Spark的SparkSQL入门; 一、SparkSQL概述 1. 概述 Spark为结构化数据处理引入了一个称…

SQLI-labs-第四关

知识点&#xff1a;get双引号(")和括号注入 思路&#xff1a; 1、判断注入点 首先&#xff0c;输入?id1 --&#xff0c;看看正常的回显状态 接着输入?id1 --&#xff0c;结果还是正常回显&#xff0c;说明这里不存在单引号问题 试试双引号&#xff0c;这里爆出了sql语…

深入了解GCC编译过程

关于Linux的编译过程&#xff0c;其实只需要使用gcc这个功能&#xff0c;gcc并非一个编译器&#xff0c;是一个驱动程序。其编译过程也很熟悉&#xff1a;预处理–编译–汇编–链接。在接触底层开发甚至操作系统开发时&#xff0c;我们都需要了解这么一个知识点&#xff0c;如何…

C# 如何读取dxf档案

需求来源&#xff1a; 工作中&#xff0c;客户提供一张CAD导出的dxf 档案&#xff0c;然后需要机器人将其转成点位&#xff0c;走到对应的位置。 下面介绍一下dxf档案到底是什么&#xff1f;以及语法规则。 dxf 格式介绍&#xff1a;DXF 格式 dxf LINE 格式。 其实上述文档…

软考:中级软件设计师:多媒体基础,音频,图像,颜色,多媒体技术的种类,图像音频视频的容量计算,常见的多媒体标准

软考&#xff1a;中级软件设计师:多媒体基础 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &am…

在公网上使用SSH远程连接安卓手机Termux:将Android手机变身为远程服务器

文章目录 前言1.安装ssh2.安装cpolar内网穿透3.远程ssh连接配置4.公网远程连接5.固定远程连接地址 前言 使用安卓机跑东西的时候&#xff0c;屏幕太小&#xff0c;有时候操作不习惯。不过我们可以开启ssh&#xff0c;使用电脑PC端SSH远程连接手机termux。 本次教程主要实现在…

介绍OpenCV

OpenCV是一个开源计算机视觉库&#xff0c;可用于各种任务&#xff0c;如物体识别、人脸识别、运动跟踪、图像处理和视频处理等。它最初由英特尔公司开发&#xff0c;目前由跨学科开发人员社区维护和支持。OpenCV可以在多个平台上运行&#xff0c;包括Windows、Linux、Android和…

高等数学刷题

分段函数主要看在临界点处的左右极限是否相等&#xff0c;若相等则整段函数即为连续 &#xff08;反之若是连续函数&#xff0c;在某一点为间断点&#xff0c;则可推导出一定为可去间断点&#xff09; 无定义的点一定为间断点 如果该点有极限则为可去间断点 由于x的不确定导…

RK3568-spi-适配1.8寸TFT彩屏驱动芯片st7735s

RK3568-spi-适配1.8寸TFT彩屏 驱动芯片st7735s 显示分辨率128x160硬件连接 VCC -- 3.3V GND -- GND BL -- 背光控制 CS -- 片选引脚 DC -- 数据/命令控制 RES -- 屏幕复位 SCL -- i2c时钟引脚 SDA -- i2c数据引脚设备树编写 &spi0 {pinctrl-names = "default"…

docker安装Apache NIFI

说明 系统&#xff1a;CentOS7.9 nifi版本&#xff1a;1.23.2 下载镜像 nifi的镜像比较大&#xff0c;大概有2G左右&#xff0c;下载时间根据个人网速而定 docker pull apache/nifi:1.23.2 查看下载好的镜像 docker images 复制容器数据 创建挂载目录 创建挂载目录的目…

【Yolov5+Deepsort】训练自己的数据集(3)| 目标检测追踪 | 轨迹绘制 | 报错分析解决

&#x1f4e2;前言&#xff1a;本篇是关于如何使用YoloV5Deepsort训练自己的数据集&#xff0c;从而实现目标检测与目标追踪&#xff0c;并绘制出物体的运动轨迹。本章讲解的为第三部分内容&#xff1a;数据集的制作、Deepsort模型的训练以及动物运动轨迹的绘制。本文中用到的数…

qt day 6

登录界面 #include "window.h" #include<QDebug> #include<QIcon> Window::Window(QWidget *parent) //构造函数的定义: QWidget(parent) //显性调用父类的构造函数 {//判断数据库对象是否包含了自己使用的数据库Student.dbif(!db.contains(&…

20230904 QT客户端服务器搭建聊天室

Ser cpp#include "app.h" #include "ui_app.h"APP::APP(QWidget *parent):QWidget(parent),ui(new Ui::APP) {ui->setupUi(this);this->resize(550,400);ui->Line->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->Line->se…

爬虫源码---爬取自己想要看的小说

前言&#xff1a; 小说作为在自己空闲时间下的消遣工具&#xff0c;对我们打发空闲时间很有帮助&#xff0c;而我们在网站上面浏览小说时会被广告和其他一些东西影响我们的观看体验&#xff0c;而这时我们就可以利用爬虫将我们想要观看的小说下载下来&#xff0c;这样就不会担…

突破瓶颈:如何应对高级职位的面试

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

K8S自动化运维容器Docker集群

K8S&#xff1a;K8S自动化运维容器化(Docker)集群 一.k8s概述 1.k8s是什么 &#xff08;1&#xff09;K8S全程为Kubernetes&#xff0c;由于K到S直接有8个字母简称为K8S。 &#xff08;2&#xff09;版本&#xff1a;目前一般是1.18~1.2.0&#xff0c;后续可能会到1.24-1.2…