news 2026/9/28 2:07:54

芒果实例分割数据集YOLOv8实战:544张图从训练到部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
芒果实例分割数据集YOLOv8实战:544张图从训练到部署

简介:这是一份面向深度学习与计算机视觉方向的芒果实例分割数据集,采用YOLOv8标注格式,可直接用于YOLOv8的实例分割训练与验证。资源包含453条训练数据与91条验证数据,覆盖精准农业、自动化采摘、质量分级、病虫害检测及储运监控等典型场景,适合从事目标检测与实例分割研究的学生、算法工程师及农业智能化开发者使用。压缩包共1088个文件,以542个png图像与542个txt标注文件为主,另含2个json与2个cache缓存文件,整体约187.03MB,图像与标注一一对应,便于直接投入训练流程。目前已有761人学习下载,具备一定参考热度。借助该数据集,读者可快速搭建芒果实例分割实验环境,完成模型训练、验证与效果评估,并在此基础上探索果园管理、自动采摘与品质追溯等落地应用,节省数据采集与标注成本。

1. 芒果实例分割数据集与 YOLOv8:544 张图能跑出什么结果

手上只有几百张标注图,却要做实例分割,这事到底靠不靠谱?我拿到「芒果实例分割数据集 yolov8 格式,453 条训练、91 条验证」这个标题时,第一反应不是兴奋,而是先算账:544 张图,按 8:2 切分,训练集 453、验证集 91,这个比例是标准的。真正决定成败的不是图片数量,而是标注质量、类别一致性和格式转换有没有出错。芒果这种目标有个特点——果实之间互相遮挡严重,成熟度不同导致颜色差异大,树冠背景杂乱,这些都会让实例分割比普通目标检测难上一截。如果你正在做农业视觉、果园采摘机器人或者果实计数系统,这套数据值得认真跑一遍。下面我按「数据长什么样 → 环境怎么搭 → 训练怎么配 → 坑在哪 → 怎么验证」的顺序,把整个流程拆开讲。

2. 芒果实例分割数据集的结构与 YOLOv8 格式要求

2.1 实例分割标注和检测标注的本质区别

很多人第一次接触实例分割,会以为就是把检测框画得更细。不是的。目标检测输出的是(x, y, w, h, class),而实例分割输出的是每个目标的一圈多边形顶点坐标,加上类别。YOLOv8 的分割任务用的是task=segment,标注文件里每一行格式是:

<class-index> <x1> <y1> <x2> <y2> ... <xn> <yn>

所有坐标都是归一化到 0~1 之间的浮点数,多边形至少 3 个点。这里有个容易翻车的地方:如果你的原始标注是 LabelMe 生成的 JSON,里面存的是绝对像素坐标,直接转成 YOLO 格式必须除以图片宽高。我见过有人忘了归一化,训练时 loss 直接飙到 nan,排查半天才发现是坐标没除。

芒果数据集的目录结构,标准做法是这样:

mango_seg/ ├── images/ │ ├── train/ # 453 张 │ └── val/ # 91 张 ├── labels/ │ ├── train/ # 453 个 .txt │ └── val/ # 91 个 .txt └── data.yaml

data.yaml是整个训练的入口配置文件,内容必须包含path、train、val、names四个字段。names里类别的顺序必须和标注文件里的class-index严格对应,错一个位置,模型学到的就是错的类别映射。

2.2 从 LabelMe 到 YOLOv8 分割格式的转换脚本

假设你拿到的原始数据是 LabelMe 标注的 JSON,下面这个脚本可以直接用:

import json import os import numpy as np from PIL import Image # 类别映射,必须和 data.yaml 里的 names 顺序一致 class_map = {"mango": 0} def labelme_to_yolo_seg(json_dir, output_dir, img_dir): os.makedirs(output_dir, exist_ok=True) for fname in os.listdir(json_dir): if not fname.endswith(".json"): continue with open(os.path.join(json_dir, fname), "r", encoding="utf-8") as f: data = json.load(f) img_w = data["imageWidth"] img_h = data["imageHeight"] lines = [] for shape in data["shapes"]: label = shape["label"] if label not in class_map: continue points = shape["points"] # 至少 3 个点才能构成多边形 if len(points) < 3: continue cls_id = class_map[label] coords = [] for x, y in points: # 归一化并裁剪到 [0,1],防止越界 nx = min(max(x / img_w, 0.0), 1.0) ny = min(max(y / img_h, 0.0), 1.0) coords.append(f"{nx:.6f} {ny:.6f}") lines.append(f"{cls_id} " + " ".join(coords)) out_name = os.path.splitext(fname)[0] + ".txt" with open(os.path.join(output_dir, out_name), "w") as f: f.write("\n".join(lines)) labelme_to_yolo_seg("./raw_json", "./labels/train", "./images/train")

这段代码的逻辑很直白:读 JSON、取图片宽高、遍历每个 shape、归一化坐标、写 txt。几个关键参数说明一下。class_map决定了类别索引,如果你的数据集有多个类别(比如「成熟芒果」「未成熟芒果」),这里要全部列出来,顺序和data.yaml的names一一对应。min(max(x / img_w, 0.0), 1.0)这个裁剪操作看起来多余,但实际标注中经常出现点稍微超出图片边界的情况,不裁剪的话 YOLOv8 训练时会报坐标越界警告。:.6f保留六位小数是 YOLO 官方推荐的精度,太少会导致小目标多边形变形。

转换完成后,务必抽查几个 txt 文件,用下面的脚本把标注画回图片上肉眼确认:

import cv2 import numpy as np def visualize_seg(img_path, label_path): img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path) as f: for line in f: parts = line.strip().split() cls_id = int(parts[0]) coords = np.array(list(map(float, parts[1:]))).reshape(-1, 2) coords[:, 0] *= w coords[:, 1] *= h pts = coords.astype(np.int32) cv2.polylines(img, [pts], True, (0, 255, 0), 2) cv2.imwrite("check.jpg", img) visualize_seg("./images/train/001.jpg", "./labels/train/001.txt")

提示:可视化检查这一步千万别省。我踩过的坑是标注工具导出的多边形点序是逆时针,YOLOv8 虽然不强制方向,但某些后处理会受影响,画出来一看就能发现异常。

3. YOLOv8 实例分割训练环境搭建与参数配置

3.1 在 Ubuntu 20.04 上搭 CPU 版和 GPU 版环境

热词里有人搜「ubuntu20.04 搭建 yolov8 环境 cpu 版本」,说明不是所有人都有显卡。我的建议是:训练阶段尽量用 GPU,哪怕是一张 GTX 1660 Ti 也比 CPU 快几十倍。但如果你只是先跑通流程验证数据格式,CPU 版也能用。

GPU 版环境搭建,我一般这样操作:

conda create -n yolov8 python=3.10 -y conda activate yolov8 pip install ultralytics # 确认 CUDA 可用 python -c "import torch; print(torch.cuda.is_available())"

如果输出True,说明 GPU 环境正常。如果输出False但你确实有 NVIDIA 显卡,大概率是 CUDA 版本和 PyTorch 版本不匹配。这时候不要急着重装系统,先跑nvidia-smi看驱动支持的 CUDA 版本,再去 PyTorch 官网找对应版本的安装命令。

CPU 版就简单了,pip install ultralytics之后直接跑,但训练时要把device参数设成cpu,并且做好心理准备:544 张图跑 100 轮,CPU 可能要一整天。

3.2 训练参数怎么设:从 epochs 到 imgsz 的实操建议

YOLOv8 分割训练的核心命令就一行:

yolo segment train \ data=./mango_seg/data.yaml \ model=yolov8n-seg.pt \ epochs=100 \ imgsz=640 \ batch=8 \ device=0 \ workers=4 \ patience=20 \ save=True \ project=./runs/segment \ name=mango_exp1

逐个参数说清楚。model=yolov8n-seg.pt选的是 nano 版本的分割模型,参数量最小,适合小数据集快速验证。如果你数据量上千或者对精度要求高,可以换yolov8s-seg.pt或yolov8m-seg.pt,但要注意显存占用会成倍增加。epochs=100对 453 张图来说是个合理起点,配合patience=20早停机制,如果 20 轮验证指标没提升就自动停,省时间。imgsz=640是默认值,芒果图片如果分辨率很高,可以试 1024,但显存不够就老老实实 640。batch=8在 8GB 显存上比较稳,12GB 以上可以拉到 16。

训练过程中,损失曲线和 mAP 曲线是判断有没有跑偏的关键。YOLOv8 默认会在runs/segment/mango_exp1/下生成results.csv,用下面这段代码画出来:

import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv("runs/segment/mango_exp1/results.csv") df.columns = df.columns.str.strip() fig, axes = plt.subplots(1, 2, figsize=(12, 4)) axes[0].plot(df["epoch"], df["train/seg_loss"], label="train seg loss") axes[0].plot(df["epoch"], df["val/seg_loss"], label="val seg loss") axes[0].set_xlabel("epoch") axes[0].set_ylabel("loss") axes[0].legend() axes[1].plot(df["epoch"], df["metrics/mAP50(B)"], label="mAP50") axes[1].plot(df["epoch"], df["metrics/mAP50-95(B)"], label="mAP50-95") axes[1].set_xlabel("epoch") axes[1].set_ylabel("mAP") axes[1].legend() plt.tight_layout() plt.savefig("training_curve.png", dpi=150)

如果训练 loss 持续下降但验证 loss 从某个 epoch 开始往上走,说明过拟合了。小数据集过拟合是常态,解决办法有三个:加数据增强(YOLOv8 默认开了 mosaic、flip、scale)、降低模型复杂度(从 s 换回 n)、或者加 dropout。我一般先看验证 mAP 有没有在涨,如果 mAP 还在涨,验证 loss 稍微抬头可以再观察几轮。

4. 小数据集训练实例分割的避坑与排查

4.1 类别不均衡导致某些芒果「消失」

现象:训练完发现模型对遮挡严重的芒果分割效果极差,几乎不输出掩码。原因:453 张图里,被遮挡的芒果样本占比可能不到 10%,模型在训练中逐渐偏向「只学容易的」。解决:在data.yaml同级目录建一个hyp.yaml,调低mosaic概率、开启copy_paste增强,让遮挡样本被复制粘贴到其他图上,人为增加难度样本的权重。

4.2 验证集 mAP 虚高但实际推理一塌糊涂

现象:验证集 mAP50 跑到 0.85,但拿新拍的芒果照片推理,掩码乱七八糟。原因:训练集和验证集如果来自同一批拍摄场景,验证集不能反映真实泛化能力。解决:重新划分数据,确保验证集包含不同光照、不同角度、不同树冠背景的图片。如果原始数据全是同一棵树的照片,那 91 张验证集的意义有限,需要补拍。

4.3 多边形标注自相交导致训练报错

现象:训练启动时报Polygon self-intersection或 loss 突然变 nan。原因:LabelMe 标注时手抖,多边形边线交叉了。解决:用 shapely 库批量检测并修复:

from shapely.geometry import Polygon def check_self_intersection(label_path): with open(label_path) as f: for i, line in enumerate(f): parts = line.strip().split() coords = list(map(float, parts[1:])) points = [(coords[j], coords[j+1]) for j in range(0, len(coords), 2)] poly = Polygon(points) if not poly.is_valid: print(f"{label_path} line {i} invalid polygon")

检测到之后,要么手动重新标注,要么用poly.buffer(0)修复后重新导出。

4.4 图片和标签文件名不匹配

现象:训练时提示No labels found,但明明 labels 目录里有文件。原因:图片是.jpg,标签是.txt,但文件名前缀不一致,比如图片叫mango_001.jpg,标签叫001.txt。YOLOv8 是按文件名(不含扩展名)去匹配的。解决:写个脚本批量重命名,确保images/train/xxx.jpg对应labels/train/xxx.txt。

4.5 显存溢出(OOM)的三种降级方案

现象:训练到一半报CUDA out of memory。原因:batch或imgsz设太大,或者workers太多导致数据加载占用显存。解决:按优先级依次尝试——先把batch减半,再把imgsz从 640 降到 512,最后把workers从 8 降到 2。如果还不行,换yolov8n-seg.pt并开启amp=True(自动混合精度)。

5. 用验证集和推理脚本确认模型真的能用

训练完之后,别只看 mAP 数字。我习惯做两件事:一是用yolo segment val跑一遍验证集,看混淆矩阵和各类别的 P/R 曲线;二是写一个推理脚本,拿几张验证集里的图跑预测,把掩码叠回原图肉眼检查。

yolo segment val \ model=runs/segment/mango_exp1/weights/best.pt \ data=./mango_seg/data.yaml \ imgsz=640 \ batch=8

推理脚本这样写:

from ultralytics import YOLO import cv2 model = YOLO("runs/segment/mango_exp1/weights/best.pt") results = model.predict( source="./mango_seg/images/val", imgsz=640, conf=0.25, iou=0.45, save=True, project="./inference", name="val_check" )

conf=0.25是置信度阈值,低于这个值的检测框会被过滤。iou=0.45是 NMS 的 IoU 阈值,控制重叠框的合并程度。这两个参数对最终效果影响很大:conf调高会减少误检但可能漏检,iou调低会抑制重叠目标。芒果互相遮挡的场景,我一般把iou设到 0.5~0.6,让模型保留更多相邻目标的掩码。

验证集只有 91 张,跑完推理后重点看三类图:单果无遮挡的、多果重叠的、背景杂乱的。如果单果图掩码边缘毛糙,说明多边形标注本身不够精细;如果多果图漏检,说明 NMS 阈值需要调;如果背景杂乱图误检,说明负样本不够,需要补一些没有芒果的树冠图作为背景类。

最后一件事:把best.pt导出成 ONNX,方便后续部署到边缘设备。命令是yolo export model=best.pt format=onnx imgsz=640。导出后拿 Netron 打开看一眼输入输出节点,确认输出里有output0和output1两个分支——分割任务比检测多一个掩码分支,如果只有一个输出,说明导出时任务类型选错了。

这套流程我跑过不止一次,544 张图做芒果实例分割,mAP50 跑到 0.8 以上是可行的,但前提是标注质量过关、验证集划分合理、训练参数不激进。小数据集训练最忌讳的就是一上来就堆 epochs 和加大模型,先用 nano 版本跑通全流程,看到曲线正常了再逐步升级。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 2:07:53

台达E3伺服脉冲控制5大参数陷阱与实战避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 2:07:52

基于YOLOv8的芒果实例分割实战:453张训练图从数据到部署

简介&#xff1a;这是一份面向深度学习与计算机视觉方向的芒果实例分割数据集&#xff0c;采用YOLOv8标注格式&#xff0c;可直接用于YOLOv8的实例分割训练与验证&#xff0c;适合从事目标检测、实例分割研究的学生、算法工程师及农业智能化应用开发者。资源包共1088个文件&…

作者头像 李华
网站建设 2026/9/28 2:07:39

高精度ADC选型与硬件设计避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 2:06:57

AD8544差分信号转单端电路设计:从选型到MATLAB仿真验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 2:06:23

电商评论情感分析实战:从噪声清洗到BERT微调的完整闭环

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 2:05:35

从改一个I2C地址到重构整个框架:PyCircuit 6架构复盘

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华