网站建设电话销售不被挂断,网站如何能让百度收录,应用公园制作的app归谁,WordPress小说网站源码目录 参考视频#xff1a; 标注 JSON转为TXT 训练 验证 参考视频#xff1a; 使用 Yolov8 自定义数据集进行图像分割_哔哩哔哩_bilibili 标注 数据集#xff1a;
我使用的是一些苹果数据集#xff0c;可以在我的csdn资源中下载#xff1a;
https://download.csdn.net/do… 目录 参考视频 标注 JSON转为TXT 训练 验证 参考视频 使用 Yolov8 自定义数据集进行图像分割_哔哩哔哩_bilibili 标注 数据集
我使用的是一些苹果数据集可以在我的csdn资源中下载
https://download.csdn.net/download/2403_83182682/90405543?spm1001.2014.3001.5503
这里标注使用的 labelme 标注软件下载和使用都很简单下载需要打开 cmd 控制台输入下载代码
pip install labelme
labelme
输入 labelme 打开软件页面
中文版的自己玩玩就会了常用按钮如下 点击【打开目录】输入苹果文件夹点击【创建多边形】绘制多边形点击保存然后继续绘制下一张 标记完成后是这样的 需要将 jpg 文件和 json文件分别放入文件夹中方便后面数据转换。
JSON转为TXT
通过 LabelMe 工具绘制多边形标注后生成的 JSON 文件是一种结构化的数据文件它遵循了一定的格式来存储图像标注信息。但是 yolov8 官方规定需要的是标注文件即 .txt 文件我这里提供一段 json 转 txt 文件的 Python 代码
# -*- coding: utf-8 -*-
from tqdm import tqdm
import shutil
import random
import os
import argparse
from collections import Counter
import yaml
import jsondef mkdir(path):if not os.path.exists(path):os.makedirs(path)def convert_label_json(json_dir, save_dir, classes):json_paths os.listdir(json_dir)classes classes.split(,)mkdir(save_dir)for json_path in tqdm(json_paths):# for json_path in json_paths:path os.path.join(json_dir, json_path)with open(path, r) as load_f:json_dict json.load(load_f)h, w json_dict[imageHeight], json_dict[imageWidth]# save txt pathtxt_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 \ntxt_file.writelines(label_str)def get_classes(json_dir):统计路径下 JSON 文件里的各类别标签数量names []json_files [os.path.join(json_dir, f) for f in os.listdir(json_dir) if f.endswith(.json)]for json_path in json_files:with open(json_path, r) as f:data json.load(f)for shape in data[shapes]:name shape[label]names.append(name)result Counter(names)return resultdef main(image_dir, json_dir, txt_dir, save_dir):# 创建文件夹mkdir(save_dir)images_dir os.path.join(save_dir, images)labels_dir os.path.join(save_dir, labels)img_train_path os.path.join(images_dir, train)img_val_path os.path.join(images_dir, val)label_train_path os.path.join(labels_dir, train)label_val_path os.path.join(labels_dir, val)mkdir(images_dir)mkdir(labels_dir)mkdir(img_train_path)mkdir(img_val_path)mkdir(label_train_path)mkdir(label_val_path)# 数据集划分比例训练集75%验证集15%测试集15%按需修改train_percent 0.90val_percent 0.10total_txt os.listdir(txt_dir)num_txt len(total_txt)list_all_txt range(num_txt) # 范围 range(0, num)num_train int(num_txt * train_percent)num_val int(num_txt * val_percent)train random.sample(list_all_txt, num_train)# 在全部数据集中取出trainval [i for i in list_all_txt if not i in train]# 再从val_test取出num_val个元素val_test剩下的元素就是test# val random.sample(list_all_txt, num_val)print(训练集数目{}, 验证集数目{}.format(len(train), len(val)))for i in list_all_txt:name total_txt[i][:-4]srcImage os.path.join(image_dir, name .jpg)srcLabel os.path.join(txt_dir, name .txt)if i in train:dst_train_Image os.path.join(img_train_path, name .jpg)dst_train_Label os.path.join(label_train_path, name .txt)shutil.copyfile(srcImage, dst_train_Image)shutil.copyfile(srcLabel, dst_train_Label)elif i in val:dst_val_Image os.path.join(img_val_path, name .jpg)dst_val_Label os.path.join(label_val_path, name .txt)shutil.copyfile(srcImage, dst_val_Image)shutil.copyfile(srcLabel, dst_val_Label)obj_classes get_classes(json_dir)classes list(obj_classes.keys())# 编写yaml文件classes_txt {i: classes[i] for i in range(len(classes))} # 标签类别data {path: os.path.join(os.getcwd(), save_dir),train: images/train,val: images/val,names: classes_txt,nc: len(classes)}with open(save_dir /segment.yaml, w, encodingutf-8) as file:yaml.dump(data, file, allow_unicodeTrue)print(标签, dict(obj_classes))if __name__ __main__:python json2txt_nomalize.py --json-dir my_datasets/color_rings/jsons --save-dir my_datasets/color_rings/txts --classes cat,dogsclasses_list apple # 类名parser argparse.ArgumentParser(descriptionjson convert to txt params)parser.add_argument(--image-dir, typestr, defaultD:\OneDrive\桌面\yolov8-segment\datasets\segment\images, help图片地址)parser.add_argument(--json-dir, typestr, defaultD:\OneDrive\桌面\yolov8-segment\datasets\segment\json, helpjson地址)parser.add_argument(--txt-dir, typestr, defaultD:\OneDrive\桌面\yolov8-segment\datasets\segment\\txt, help保存txt文件地址)parser.add_argument(--save-dir, defaultD:\OneDrive\桌面\yolov8-segment\datasets\segment\seg, typestr, help保存最终分割好的数据集地址)parser.add_argument(--classes, typestr, defaultclasses_list, helpclasses)args parser.parse_args()json_dir args.json_dirtxt_dir args.txt_dirimage_dir args.image_dirsave_dir args.save_dirclasses args.classes# json格式转txt格式convert_label_json(json_dir, txt_dir, classes)# 划分数据集生成yaml训练文件main(image_dir, json_dir, txt_dir, save_dir)第 90 行左右可以修改数据集划分比例默认是 90% 训练集10%验证集。 第147到150行依次为图片地址、json文件地址、保存txt文件地址、分割好的数据集地址 我的项目创建目录如下都是可以自己修改的 运行代码
运行成功训练集是19张图片验证集是3张检测到的标签总数量为 53。 运行成功后会帮您创建 Yolov8 训练所需的文件格式并且将 txt文件放入正确的位置 训练
训练环境使用的GPU需要配置的可以看我前文 CV -- 基于GPU版显卡CUDA环境Pycharm YOLOv8 检测-CSDN博客 训练代码如下
from torch.cuda import devicefrom ultralytics import YOLOmodel YOLO(D:\OneDrive\桌面\yolov8-segment\weights\yolov8n-seg.pt)model.train(dataD:\OneDrive\桌面\yolov8-segment\datasets\segment\seg\segment.yaml,epochs300, #训练轮次imgsz640, #输入图片尺寸会转换为该尺寸batch4, #每次训练的批量devicecuda:0, #使用GPU训练workers0 #windows GPU训练需加上该参数否则会报错)
print(训练结束)这里使用的是预训练模型yolov8n-seg.pt大家可以在我的资源中获取到
https://download.csdn.net/download/2403_83182682/90405472?spm1001.2014.3001.5503
训练结束后会生成一些图表 输出文件说明 F1-置信度曲线 (BoxF1_curve.png) 观察方法: F1分数是模型准确度的度量结合了精确度和召回率。在这个图表中您应该寻找F1分数最高的点该点对应的置信度阈值通常是模型最佳的工作点。 精确度-置信度曲线 (BoxP_curve.png) 观察方法: 精确度代表了模型预测为正类的样本中实际为正类的比例。在该曲线中应关注随置信度增加精确度如何提高以及在哪个置信度水平上精确度开始下降这有助于确定阈值设定。 精确度-召回率曲线 (BoxPR_curve.png) 观察方法: 该曲线展示了精确度与召回率之间的权衡。理想的模型应在高精确度和高召回率处达到平衡。通常查看曲线下面积来评估模型整体性能。 召回率-置信度曲线 (BoxR_curve.png) 观察方法: 召回率是指所有正类中模型正确预测的比例。这个图表中召回率通常随着置信度阈值的降低而增加。理想的置信度阈值通常是召回率较高但置信度不过低的点。 混淆矩阵 (confusion_matrix.png) 观察方法: 查看矩阵的对角线对角线上的数值越高表示分类结果越准确。同时观察非对角线元素了解哪些类别容易被误分类。 标准化混淆矩阵 (confusion_matrix_normalized.png) 观察方法: 与非标准化混淆矩阵类似但通过标准化可以更容易地比较不同类别之间的分类准确率特别是在类别样本量不均匀的情况下。 标签分布 (labels.jpg) 观察方法: 柱状图部分显示了每个类别的实例数量有助于了解数据集中各类别的分布情况。散点图部分可以显示样本的位置分布有助于了解样本在输入空间的分布特性。 标签相关图 (labels_correlogram.jpg) 观察方法: 相关图显示了数据标签之间的相关性深色的格子表示较高的正相关浅色表示较低的相关或负相关。这有助于了解不同类别之间的关系。 掩膜F1-置信度曲线 (MaskF1_curve.png) 观察方法: 类似于F1-置信度曲线但特别用于评估模型在像素级分类或分割任务中的性能。寻找曲线中F1得分最高的点来确定最佳的置信度阈值。 精确度-召回率曲线 (Precision-Recall Curve) (MaskPR_curve.png) 如何观察理解: 此图表展示了在不同召回率水平上模型精确度的变化。蓝色的线表示所有类别的平均精确度。曲线下的面积AUC越大模型性能越好。理想状态是曲线靠近右上角即高召回率和高精确度。 召回率-置信度曲线 (Recall-Confidence Curve) (MaskR_curve.png) 如何观察理解: 该图标展示了模型在不同置信度阈值下召回率的变化。您应关注在召回率保持高的同时置信度阈值的选择。最佳操作点通常是召回率开始显著下降之前的置信度值。 训练和验证指标图 (results.png) 如何观察理解: 这张图显示了多个指标的训练和验证过程其中包括损失函数的变化和性能指标如精确度和mAP。下降的损失和上升的性能指标通常表明模型在学习过程中正在改进。平滑的曲线有助于识别趋势。 损失和性能指标图 如何观察理解: 类似于上一个图表这个可能包含了不同的损失和性能指标。每个小图标展示了训练过程中的具体方面如框体损失、分割损失、分类损失等。这有助于诊断模型在哪些方面表现良好在哪些方面可能需要进一步优化。 Weights文件这是一个模型权重文件通常以.ptPyTorch模型格式保存。它包含了经过训练的神经网络的所有参数和权重。这个文件是模型训练过程的直接产物用于后续的图像识别和分析任务。
Args.yaml文件这个文件通常包含了模型训练时使用的配置参数。它详细记录了训练过程中使用的所有设置如学习率、批大小、训练轮数等。这个文件的目的是为了提供一个清晰的训练配置概览使得训练过程可以被复现或调整。 左半部分是损失函数图损失函数下降可能并不能说明训练结果很好但如果损失函数上升那训练结果一定不好说明你的数据可能出现了很大的错误或者一些其他不好的事情正在发生。 通过对测试数据的详细分析我们可以观察到原始标注与模型预测的掩膜之间存在差异很小这实际上体现了模型具备出色的语义分割能力。具体而言尽管在某些局部细节上可能存在细微偏差但模型整体能够准确捕捉并区分不同对象的边界和区域展示了其在复杂场景下对图像内容的强大理解能力。这种高水平的分割精度不仅验证了模型训练的有效性还为其在实际应用中的性能提供了有力保障。
验证
可以使用我们训练好的模型对苹果图片进行图像分割训练好的模型的权重文件中有两个模型文件第一个是最好的模型第二个是最后一次训练的模型一般使用第一个模型。 训练代码
from ultralytics import YOLO
import cv2
import numpy as np# 模型路径和图像路径
model_path D:/OneDrive/桌面/yolov8-segment/runs/segment/train8/weights/best.pt
image_path D:/OneDrive/桌面/apple2.jpg# 加载模型并进行预测
model YOLO(model_path,tasksegment)
results model.predict(sourceimage_path,saveTrue,showTrue)
成功运行后就能得到分割图片 可以看见分割效果是有的但也有点瑕疵把杯子也识别成 apple 了可能是因为数据集太少或者标注问题。
当然也可使用代码将各个 apple 的掩膜提取出来
from ultralytics import YOLO
import cv2
import numpy as np# 模型路径和图像路径
model_path D:/OneDrive/桌面/yolov8-segment/runs/segment/train8/weights/best.pt
image_path D:/OneDrive/桌面/apple2.jpg# 加载模型并进行预测
model YOLO(model_path,tasksegment)
results model.predict(sourceimage_path,saveTrue,showTrue)# 读取图像
img cv2.imread(image_path)
H, W, _ img.shape
print(img.shape)# # 遍历每个结果中的掩码
for i, result in enumerate(results):for j, mask in enumerate(result.masks.data):# 将mask从GPU移动到CPU并转换为numpy数组mask mask.cpu().numpy()# 如果mask是多维的选择第一个通道假设单通道if len(mask.shape) 2:mask mask[0]# 归一化到0-255范围并转换为uint8类型mask (mask * 255).astype(np.uint8)# 调整大小以匹配原图尺寸mask_resized cv2.resize(mask, (W, H))# 保存掩码图像output_path f./mask_{i}_{j}.pngcv2.imwrite(output_path, mask_resized)print(fSaved {output_path})
得到各个掩膜的 png 文件 这些掩膜文件在某些时候非常有用。 感谢您的三连