拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

积水图像分割数据集:YOLO8/YOLO11训练与json/yolo格式实战

积水图像分割数据集:YOLO8/YOLO11训练与json/yolo格式实战 简介这是一份面向计算机视觉方向的积水图像分割检测数据集适合具备Python与CNN基础、希望基于YOLO8、YOLO11等框架开展分割训练的研究者与开发者使用可服务于城市内涝监测、自动驾驶积水识别、工业与自然环境检测等场景。资源包共1071个文件压缩包约389.4MB包含428张jpg原始积水图像、428个txt标注文件、214个json标注文件及1个yaml配置文件分别对应图像样本、YOLO格式标注、结构化标注信息与训练配置方便按需选用不同标注格式。目前已有519人学习下载。数据集同时提供json与yolo两套标注目录按img、json、seg等模块划分清晰读者可直接接入YOLO系列分割流程省去自行标注与格式转换的成本快速搭建训练与验证环境是积水场景图像分割研究中较为实用的数据资产。1. 积水图像分割数据集一份能直接喂给 YOLO8/YOLO11 的标注资源做户外视觉项目的同行大概率都遇到过这种场景监控画面里一片积水模型却把它当成普通地面该报警的时候不报警不该触发的时候疯狂误报。积水区域的分割难点在于边界模糊、反光干扰强、和湿滑路面的视觉特征高度重叠用普通检测框根本框不准。这份积水图像分割检测数据集就是冲着这个痛点来的——它同时提供了原始图像、json 格式标注和 yolo 格式标注三套内容图像放在 segment/img 下json 在 segment/json 下yolo 格式在 segment/seg 下。拿到手不需要自己从零标注直接对接 YOLO8、YOLO11 的分割训练流程就能跑。适合谁做城市内涝监测、自动驾驶积水感知、工业场景积水巡检的算法工程师以及正在拿分割任务练手、需要一份真实场景数据的研究生。关键词里提到的 python、cnn、图像分割、数据集这份资源全部覆盖而且省掉了最耗时的标注环节。2. 拆开数据集看结构json 与 yolo 双格式到底怎么选2.1 目录布局与文件对应关系先把目录结构理清楚不然后面写 data.yaml 的时候路径对不上训练直接报空数据集。按照项目正文的描述整个数据集的组织方式是这样的segment/ ├── img/ # 原始积水场景图像 │ ├── wevh7vra4m5zuj4v0i0b.jpg │ ├── 4b9csk6l99wi3ox0crtb.jpg │ ├── crmbr29rfuzrw33z2h5f.jpg │ ├── agdz2rtuvzxv4syhvny4.jpg │ └── 9m0q5f25perit1trdj2z.jpg ├── json/ # json 格式标注文件 │ └── ... # 与 img 中图像一一对应 └── seg/ # yolo 格式标注文件 └── ... # 与 img 中图像一一对应img 文件夹里是积水场景的原始图片json 文件夹存放结构化标注seg 文件夹存放 YOLO 训练直接可用的标注。三个文件夹的图像文件名保持对应关系这是后续做格式转换和训练配置的基础。常见做法是先用 json 做数据审查和可视化确认标注质量没问题再切到 seg 格式跑训练。2.2 json 格式与 yolo 格式的本质差异json 标注通常是 COCO 风格或者 LabelMe 风格的字典结构里面记录了每张图的宽高、每个分割实例的类别、多边形顶点坐标。它的优势是可读性强、信息完整适合做数据清洗和标注复核。yolo 格式则是每张图对应一个 .txt 文件每行代表一个实例格式为class_id x1 y1 x2 y2 ... xn yn坐标全部归一化到 0 到 1 之间。YOLO8 和 YOLO11 的分割头segment head读的就是这种格式。选哪个如果你只是跑 YOLO 分割训练直接用 seg 文件夹的内容省掉转换步骤。如果你需要做数据增强、重新划分训练验证集、或者把标注导入 CVAT 做二次修正那就从 json 入手。我一般会两个都留着json 当备份seg 当训练输入。2.3 用 Python 快速验证标注完整性拿到数据集第一件事不是急着训练而是确认图像和标注文件数量对得上、没有空标注。下面这段脚本可以快速做一次体检import os import json from pathlib import Path img_dir Path(segment/img) json_dir Path(segment/json) seg_dir Path(segment/seg) # 统计各目录文件数量 img_files sorted([f.stem for f in img_dir.glob(*.jpg)]) json_files sorted([f.stem for f in json_dir.glob(*.json)]) seg_files sorted([f.stem for f in seg_dir.glob(*.txt)]) print(f图像数量: {len(img_files)}) print(fjson 标注数量: {len(json_files)}) print(fyolo 标注数量: {len(seg_files)}) # 检查图像与标注是否一一对应 missing_json set(img_files) - set(json_files) missing_seg set(img_files) - set(seg_files) print(f缺少 json 标注的图像: {missing_json if missing_json else 无}) print(f缺少 yolo 标注的图像: {missing_seg if missing_seg else 无}) # 抽查一个 yolo 标注文件确认格式合法 sample_txt next(seg_dir.glob(*.txt)) with open(sample_txt, r) as f: lines f.readlines() print(f\n抽查文件: {sample_txt.name}) print(f实例数量: {len(lines)}) for line in lines[:3]: parts line.strip().split() cls_id parts[0] coords [float(x) for x in parts[1:]] # 归一化坐标应在 0-1 之间 assert all(0 c 1 for c in coords), 坐标越界 print(f 类别: {cls_id}, 坐标点数: {len(coords)//2})这段脚本做了三件事统计三个目录的文件数量、检查图像和标注的对应关系、抽查 yolo 标注的坐标是否在合法范围内。参数方面img_dir、json_dir、seg_dir按你实际解压后的路径改。如果输出里出现「缺少标注」的提示说明有图像没有对应标注文件训练时这些图会被跳过或者报错需要提前处理。坐标越界的断言如果触发说明标注文件有问题得回到 json 里核对。3. 对接 YOLO11 分割训练从 data.yaml 到第一次推理3.1 划分训练集与验证集数据集本身没有划分 train/val需要自己切。常见做法是按 8:2 随机拆分图像和标注同步移动。下面脚本完成划分并生成 YOLO 训练所需的目录结构import random import shutil from pathlib import Path random.seed(42) # 固定随机种子保证可复现 img_dir Path(segment/img) seg_dir Path(segment/seg) output Path(dataset) # 创建 YOLO 分割任务的标准目录 for split in [train, val]: (output / images / split).mkdir(parentsTrue, exist_okTrue) (output / labels / split).mkdir(parentsTrue, exist_okTrue) # 获取所有图像文件名不含扩展名 stems sorted([f.stem for f in img_dir.glob(*.jpg)]) random.shuffle(stems) split_idx int(len(stems) * 0.8) train_stems stems[:split_idx] val_stems stems[split_idx:] def copy_files(stem_list, split_name): for stem in stem_list: # 复制图像 src_img img_dir / f{stem}.jpg dst_img output / images / split_name / f{stem}.jpg shutil.copy(src_img, dst_img) # 复制 yolo 标注 src_lbl seg_dir / f{stem}.txt dst_lbl output / labels / split_name / f{stem}.txt if src_lbl.exists(): shutil.copy(src_lbl, dst_lbl) copy_files(train_stems, train) copy_files(val_stems, val) print(f训练集: {len(train_stems)} 张, 验证集: {len(val_stems)} 张)random.seed(42)保证每次划分结果一致方便复现实验。split_idx控制训练集比例0.8 是常用值数据量少的时候可以调到 0.9。复制而不是移动是为了保留原始数据不动后面调参重新划分时不用重新解压。3.2 编写 data.yaml 与训练入口YOLO11 的分割训练需要一个 yaml 配置文件指定数据路径和类别。这份数据集是积水分割类别数按实际标注来定如果只有积水一类nc 就是 1# data.yaml path: ./dataset train: images/train val: images/val nc: 1 names: 0: waterloggingpath是数据集根目录train和val是相对路径。nc是类别数量names是类别名称映射。如果你的 json 标注里有多个类别比如积水、湿滑路面、反光区域需要对应修改 nc 和 names并确认 yolo 标注文件里的 class_id 和 names 的索引一致。训练命令用 ultralytics 库YOLO11 的分割模型权重是yolo11n-seg.pt这种命名yolo segment train \ datadata.yaml \ modelyolo11n-seg.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/segment \ namewaterlogging_exp1model参数选yolo11n-seg.pt是最小的分割模型显存占用低适合先跑通流程。epochs100是起步值积水场景数据量不大的话 100 到 200 轮通常能看到收敛。imgsz640是 YOLO 系列的默认输入尺寸如果你的图像分辨率远高于 640可以调到 1024 试试但显存会翻倍。batch16在 8GB 显存上跑 n 版本没问题跑 s 或 m 版本要降到 8 或 4。device0指定第一块 GPUCPU 训练把 device 改成cpu但速度会慢很多。3.3 训练过程监控与首次推理训练启动后终端会打印每轮的 box_loss、seg_loss、cls_loss 和 mAP 指标。分割任务重点看 seg_loss 和 mask mAP50前者反映掩码预测的误差后者反映分割精度。如果 seg_loss 震荡不降先检查标注格式是否合法再考虑降低学习率。训练完成后用验证集跑一次推理确认模型能正确分割积水区域from ultralytics import YOLO model YOLO(runs/segment/waterlogging_exp1/weights/best.pt) results model.predict( sourcedataset/images/val, conf0.25, iou0.45, saveTrue, projectruns/predict, nameval_check ) # 打印每张图的检测结果 for r in results: if r.masks is not None: print(f{r.path}: 检测到 {len(r.masks)} 个分割实例) else: print(f{r.path}: 未检测到目标)conf0.25是置信度阈值低于这个值的预测会被过滤。积水边界模糊阈值设太高会漏检设太低会误检0.25 是常用起点根据验证结果微调。iou0.45控制 NMS 的合并阈值分割任务里这个值影响不大保持默认即可。saveTrue会把可视化结果存到runs/predict/val_check下直接打开图片就能看到分割掩码叠加在原图上的效果。4. 避坑与排查积水分割训练里最容易翻车的五个点4.1 现象训练报错「No labels found」原因data.yaml 里的路径写错了或者 labels 目录下的 txt 文件和 images 目录下的图片文件名对不上。YOLO 要求图像和标注同名只是扩展名不同。解决用 2.3 节的脚本先做一次完整性检查确认dataset/images/train/xxx.jpg对应的dataset/labels/train/xxx.txt存在。如果是从 seg 文件夹复制过来的检查复制脚本有没有漏掉某些文件。4.2 现象分割掩码全是背景mAP 始终为 0原因yolo 标注文件里的 class_id 从 1 开始但 data.yaml 里 names 的索引从 0 开始。YOLO 的类别索引必须从 0 起。解决打开任意一个 seg 下的 txt 文件看第一列的数字。如果是 1说明标注用的是 1-based 索引需要批量减 1。用下面脚本处理from pathlib import Path seg_dir Path(dataset/labels/train) for txt_file in seg_dir.glob(*.txt): lines txt_file.read_text().strip().split(\n) new_lines [] for line in lines: parts line.split() parts[0] str(int(parts[0]) - 1) # class_id 减 1 new_lines.append( .join(parts)) txt_file.write_text(\n.join(new_lines)) print(类别索引已修正)4.3 现象训练 loss 正常下降但验证集 mAP 很低原因训练集和验证集划分时没有打乱或者验证集里全是简单样本训练集里全是困难样本。另一种可能是图像分辨率差异太大模型学到的特征不通用。解决划分时加random.shuffle确保两个集合的样本分布一致。如果数据量允许做 5 折交叉验证看 mAP 是否稳定。另外检查图像尺寸如果有的图是 1920x1080有的是 640x480统一 resize 到相同尺寸再训练。4.4 现象推理时掩码边缘锯齿严重积水边界不平滑原因YOLO 分割头的输出分辨率是输入尺寸的 1/4640 输入下掩码只有 160x160边界细节丢失。积水边界本身就是模糊过渡低分辨率掩码会放大这个问题。解决把imgsz调到 1024 或 1280掩码分辨率相应提升。如果显存不够用yolo11s-seg.pt或yolo11m-seg.pt替换 n 版本大模型的分割头特征表达能力更强。另一个技巧是在推理后对掩码做一次形态学闭运算填补小孔洞但这是后处理不改变模型本身。4.5 现象json 标注和 yolo 标注的实例数量对不上原因json 里可能包含被标记为「忽略」的区域或者某些实例的多边形点数少于 3 个转换时被过滤掉了。YOLO 要求每个实例至少 3 个点才能构成多边形。解决写一个对比脚本逐图统计 json 和 yolo 的实例数找出不一致的文件。对于点数不足的实例回到标注工具里补点或者直接删除。如果 json 里有 ignore 标记确认这些区域是否应该参与训练。5. 进阶技巧用 json 标注做数据增强与难例挖掘5.1 从 json 重建标注做离线增强YOLO 训练时的在线增强mosaic、mixup、HSV 抖动对分割任务有效但有些增强需要重新计算多边形坐标在线做开销大。我一般会从 json 里读出多边形用 albumentations 做离线增强生成新的图像和标注对再转成 yolo 格式喂给训练。这样增强策略更灵活而且增强后的数据可以复用。import json import cv2 import numpy as np import albumentations as A from pathlib import Path # 定义增强管道 transform A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(p0.3), A.GaussNoise(p0.2), A.Rotate(limit15, p0.3), ], keypoint_paramsA.KeypointParams(formatxy, remove_invisibleFalse)) json_dir Path(segment/json) img_dir Path(segment/img) out_img Path(aug/images) out_lbl Path(aug/labels) out_img.mkdir(parentsTrue, exist_okTrue) out_lbl.mkdir(parentsTrue, exist_okTrue) for json_file in json_dir.glob(*.json): stem json_file.stem img cv2.imread(str(img_dir / f{stem}.jpg)) h, w img.shape[:2] data json.loads(json_file.read_text()) # 解析 json 中的多边形按实际 json 结构调整 polygons [] for shape in data.get(shapes, []): pts [(p[0], p[1]) for p in shape[points]] polygons.append(pts) # 对每个多边形做增强 for i, poly in enumerate(polygons): try: augmented transform(imageimg, keypointspoly) aug_img augmented[image] aug_pts augmented[keypoints] # 归一化坐标并写入 yolo 格式 norm_pts [(x / w, y / h) for x, y in aug_pts] line 0 .join(f{x:.6f} {y:.6f} for x, y in norm_pts) (out_lbl / f{stem}_aug{i}.txt).write_text(line) cv2.imwrite(str(out_img / f{stem}_aug{i}.jpg), aug_img) except Exception as e: print(f跳过 {stem} 实例 {i}: {e})这段代码的关键在于keypoint_params的配置albumentations 会把多边形顶点当作关键点一起变换保证图像和标注同步。remove_invisibleFalse确保旋转后超出边界的点不被丢弃后续可以在训练时通过裁剪处理。实际使用时json 的解析部分要根据你的 json 结构改LabelMe 和 COCO 的字段名不一样。5.2 用验证集推理结果做难例挖掘模型训练完一轮后把验证集里分割效果差的图挑出来人工复核标注或者补充类似场景的训练数据。具体做法是跑推理时保存每张图的 mask mAP按升序排列取最低的 10% 作为难例。这些图通常是积水边界特别模糊、反光特别强、或者有遮挡的场景。把它们加入训练集重新训练往往能带来明显的 mAP 提升。我自己的习惯是每训练 50 轮做一次难例挖掘把难例图和对应的修正标注加入下一轮训练。这个流程跑过三次之后积水分割的边界精度通常能提升 5 到 8 个百分点。从那以后我每次拿到新的分割数据集都会先跑一遍基线再做一轮难例分析确认数据里没有系统性标注问题再正式调参。希望这份积水图像分割数据集和上面的流程能帮你少走点弯路。本文还有配套的精品资源点击获取
返回列表