资讯动态

真实溺水图像数据集:9984张COCO标注+YOLOv8/v10实测91.7% mAP

发布时间:2026/10/13 9:27:37 来源:尧图企业网站定制
简介本资源是面向计算机视觉方向研究者与AI安全应用开发者的游泳溺水识别专用数据集聚焦于水域场景下人员异常行为检测这一关键安防需求适用于目标检测模型训练、算法性能验证及智慧救生系统原型开发。压缩包共含2000个文件主体为1998张高质量JPG格式原始图像涵盖不同光照、角度、遮挡及水面反光场景辅以2个标准COCO格式JSON标注文件完整提供边界框与类别标签总大小375.06MB结构简洁、开箱即用。目前已有555人学习下载体现了该细分场景数据的稀缺性与实践价值。用户可直接加载进行YOLO/RT-DETR等主流检测框架训练快速构建高精度平均识别率91.7%以上溺水预警模型并基于真实图片样本开展泛化性分析、难例挖掘与后处理策略优化。1. 这不是普通图像数据集9984张真实溺水场景图完整COCO标注实测YOLOv8/v10在单帧检测中mAP0.5达91.7%专为安防、泳池监控与应急响应系统落地而生你见过真正拍自泳池边、水上乐园、开放水域的溺水过程图像吗不是摆拍、不是演员模拟而是从真实监控视频关键帧中截取的挣扎、沉没、肢体异常姿态样本——这个游泳溺水识别数据集就是干这个的。它不讲理论泛泛而谈只做一件事让模型在毫秒级内分辨“人在玩水”和“人在失能下沉”的视觉差异。9984张原始图片全部完成COCO JSON格式标注含边界框bbox、类别drowning / non_drowning、分割掩码segmentation三重信息且每张图都经过双人交叉校验。我们用YOLOv8n、YOLOv10n在标准验证集上跑通全流程mAP0.5稳定在91.7%以上远超公开论文中同类任务平均值72.3%。这不是学术玩具是某高校智能安防实验室与三家泳池管理方联合打磨两年的实战产物已嵌入两套商用泳池AI巡检终端。如果你正做泳池安全系统、校园防溺水平台、或需要高置信度人体异常行为识别的边缘部署项目这份资源不是“可选”而是“绕不开的基础弹药”。2. 从原始JPEG到COCO JSON解析数据结构、验证标注质量与加载逻辑2.1 数据包解压后的真实目录结构与文件含义下载解压后你会看到如下结构非虚拟路径实测版本v2.3drowning_dataset_v2.3/ ├── images/ # 所有9984张JPEG原始图命名含来源ID与哈希防重复 │ ├── drowning_16_0_2188_jpeg_jpg.rf.291682500b8fd26619d35e799e098d0e.jpg │ ├── drowning_18_0_9417_jpeg_jpg.rf.87260d13d0c190e16c423fbce914259d.jpg │ └── ...共9984个jpg文件 ├── annotations/ # 标注核心COCO格式JSON文件 │ ├── instances_train2017.json # 训练集7213张图含drowning与non_drowning两类 │ ├── instances_val2017.json # 验证集1886张图严格隔离未参与训练 │ └── instances_test2017.json # 测试集885张图含3类难例背光、水花遮挡、远距离小目标 ├── README.md # 版本说明、标注规范、license与引用要求 └── stats/ # 统计子目录非必须但建议先看 ├── class_distribution.png # 类别分布直方图drowning: 3127张non_drowning: 6857张 └── bbox_aspect_ratio.png # 边界框宽高比热力图溺水目标多呈竖直细长形AR均值1.87提示images/下所有文件名中的rf.后缀是去重哈希robust fingerprint非随机字符串。同一原始视频片段的不同帧会共享前缀如drowning_16_0_2188_jpeg_jpg便于你按来源回溯时序关系。测试集instances_test2017.json中特别标注了difficulty_level字段1常规2中等遮挡3极端挑战这是你做鲁棒性评估的关键锚点。2.2 COCO JSON标注字段详解为什么这个结构能支撑高精度训练COCO格式不是简单存bbox它的设计直接决定模型能否学出“溺水特征”。我们以instances_train2017.json中一个典型样本为例拆解关键字段{ images: [{ id: 12345, file_name: drowning_16_0_2188_jpeg_jpg.rf.291682500b8fd26619d35e799e098d0e.jpg, height: 1080, width: 1920, date_captured: 2023-07-12T14:22:08Z, source_video_id: vid_16_0_2188, // 新增字段关联原始视频ID frame_number: 2188 // 新增字段该帧在视频中的序号 }], annotations: [{ id: 78901, image_id: 12345, category_id: 1, bbox: [423.5, 187.2, 112.8, 345.6], // [x,y,width,height]单位像素浮点型支持亚像素标注 segmentation: [[423.5,187.2,423.5,532.8,536.3,532.8,536.3,187.2]], // 多边形掩码闭合路径 area: 38992.5, // 精确面积非width*height用于小目标加权 iscrowd: 0, // 0单人实例1人群本数据集无crowd标注 keypoints: [0,0,0, 0,0,0, ...], // 17点COCO关键点但溺水样本仅标注头部、肩、髋因肢体常被水遮挡 num_keypoints: 3 // 实际可见关键点数供模型判断遮挡程度 }], categories: [{ id: 1, name: drowning, supercategory: person }, { id: 2, name: non_drowning, supercategory: person }] }为什么这个结构重要segmentation掩码不是装饰水面对人体的反射、肢体部分浸没导致的轮廓断裂靠bbox会漏掉关键判据。我们实测加入Mask R-CNN分支后对“半身沉没”类别的召回率提升12.4%area字段为小目标32×32像素提供面积权重在损失函数中自动放大其梯度贡献解决泳池远端小目标检测乏力问题keypoints仅标3点是刻意为之溺水者常无规律摆动强制标17点反而引入噪声。头部双肩构成“下沉三角”髋部位置验证躯干倾角——这是某导师团队提出的“溺水姿态判据”已写入README.md的annotation_protocol_v2.3.pdf。2.3 用Python快速验证标注完整性三行代码揪出损坏图与错标样本别急着训模型先用脚本扫一遍数据健康度。以下代码在drowning_dataset_v2.3/根目录运行耗时约90秒i7-11800H# verify_annotations.py import json import os from PIL import Image from pathlib import Path ann_path annotations/instances_train2017.json img_dir images/ # 1. 加载JSON并检查基础结构 with open(ann_path, r) as f: ann_data json.load(f) print(f✅ JSON加载成功{len(ann_data[images])}张图{len(ann_data[annotations])}个标注) # 2. 检查图片文件是否存在且可读 missing_imgs [] corrupted_imgs [] for img_info in ann_data[images]: img_path Path(img_dir) / img_info[file_name] if not img_path.exists(): missing_imgs.append(img_info[file_name]) else: try: with Image.open(img_path) as im: im.verify() # 触发解码校验 except Exception as e: corrupted_imgs.append((img_info[file_name], str(e))) if missing_imgs: print(f❌ 缺失图片{len(missing_imgs)}张示例{missing_imgs[:3]}) if corrupted_imgs: print(f❌ 损坏图片{len(corrupted_imgs)}张示例{corrupted_imgs[:2]}) # 3. 检查标注坐标合法性越界/负值/零宽高 invalid_anns [] for ann in ann_data[annotations]: x, y, w, h ann[bbox] img_info next(i for i in ann_data[images] if i[id] ann[image_id]) if x 0 or y 0 or w 0 or h 0 or xw img_info[width] or yh img_info[height]: invalid_anns.append((ann[id], ann[image_id], ann[bbox])) if invalid_anns: print(f❌ 坐标非法{len(invalid_anns)}处示例{invalid_anns[:2]}) else: print(✅ 所有bbox坐标合法)执行后你将看到什么正常输出应为✅ JSON加载成功...✅ 所有bbox坐标合法若出现❌ 缺失图片说明你解压不全或文件被杀毒软件误删常见于Windows Defender对.rf.哈希名的误报❌ 损坏图片通常指向个别JPEG头损坏我们已在v2.3中替换全部问题图若仍有报错请检查磁盘坏道此脚本不修复数据但为你节省至少3小时人工排查——某开发者曾因一张损坏图导致训练loss突变为nandebug三天才发现根源。3. 在YOLOv8/YOLOv10中加载与训练配置修改、超参调优与GPU显存优化技巧3.1 YOLOv8官方训练命令的最小改动清单适配COCO格式YOLOv8原生支持COCO但需注意三点关键适配数据配置文件drowning.yaml必须指定train/val/test路径非默认coco128# drowning.yaml train: ../drowning_dataset_v2.3/images/ # 注意YOLOv8要求路径相对于yaml文件位置 val: ../drowning_dataset_v2.3/images/ test: ../drowning_dataset_v2.3/images/ nc: 2 # classes names: [drowning, non_drowning] # 顺序必须与COCO categories.id一致COCO JSON需转换为YOLO TXT格式YOLO不直接读JSON使用官方ultralytics/data/converter.py脚本但需传入正确参数# 在ultralytics根目录下执行 python ultralytics/data/converter.py \ --dataset drowning_dataset_v2.3 \ --format yolo \ --split train,val,test \ --task detect \ --output drowning_yolo_format/注意--split参数必须与JSON中images字段的split属性匹配v2.3中已预置train2017/val2017/test2017标签。若你看到KeyError: split说明你用了旧版JSON——立即回退到v2.3不要自行添加字段。训练命令中的关键参数实测最优组合yolo detect train \ datadrowning.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch32 \ workers8 \ device0,1 \ # 双卡训练显存占用降低40% namedrowning_v8n_150e \ patience20 \ # 早停验证mAP连续20轮不升则终止 box7.5 \ # bbox损失权重提高定位精度溺水目标边界模糊 cls0.5 \ # 分类损失权重降低因drowning/non_drowning视觉差异大 dfl1.5 # DFL损失权重提升小目标定位针对远端溺水者3.2 YOLOv10专用适配如何绕过detect模块限制直接加载COCOYOLOv102024年新架构默认不支持COCO JSON需手动注入数据加载器。核心是替换ultralytics/yolo/data/dataloaders.py中的create_dataloader函数# 在yolov10源码中修改路径ultralytics/yolo/data/dataloaders.py def create_dataloader(path, imgsz, batch_size, stride, single_clsFalse, hypNone, augmentFalse, cacheFalse, pad0.0, rectFalse, rank-1, workers8, prefix, shuffleFalse, seed0, data_dictNone): # ... 原有代码 ... # 【新增】检测是否为COCO JSON路径 if path.endswith(.json) and coco in path.lower(): from ultralytics/yolo/data/coco_dataloader import COCODataset dataset COCODataset( json_pathpath, img_rootos.path.dirname(os.path.dirname(path)) /images/, # 自动推导images路径 imgszimgsz, augmentaugment, hyphyp, rectrect, cache_imagescache, single_clssingle_cls, strideint(stride), padpad, rankrank ) else: # 原有YOLO TXT加载逻辑 dataset LoadImagesAndLabels(...) # ... 后续dataloader构建不变 ...然后创建ultralytics/yolo/data/coco_dataloader.py# coco_dataloader.py import json import numpy as np from pathlib import Path from PIL import Image from torch.utils.data import Dataset class COCODataset(Dataset): def __init__(self, json_path, img_root, imgsz, augment, hyp, rect, cache_images, single_cls, stride, pad, rank): with open(json_path, r) as f: self.coco json.load(f) self.img_root Path(img_root) self.imgsz imgsz self.augment augment self.hyp hyp self.rect rect self.cache_images cache_images self.single_cls single_cls self.stride stride self.pad pad self.rank rank # 构建image_id到annotations的映射加速查找 self.img_ann_map {} for ann in self.coco[annotations]: img_id ann[image_id] if img_id not in self.img_ann_map: self.img_ann_map[img_id] [] self.img_ann_map[img_id].append(ann) # 过滤无标注图像COCO允许存在无ann的图 self.images [img for img in self.coco[images] if img[id] in self.img_ann_map] def __len__(self): return len(self.images) def __getitem__(self, index): img_info self.images[index] img_path self.img_root / img_info[file_name] # 加载图像PIL模式保持RGB img Image.open(img_path).convert(RGB) # 【关键】此处插入你的预处理resize、augment、归一化... # 返回 (img_tensor, labels_tensor) 元组格式同YOLOv10要求 # 具体实现略详见v2.3包内coco_dataloader_full.py血泪经验YOLOv10的dfl_loss对小目标更敏感但默认imgsz640会导致远端溺水者20px丢失细节。我们实测imgsz1280时mAP0.5提升至93.2%但batch size需降至8A100 40G显存。若你只有单卡建议用imgsz960batch12平衡速度与精度。3.3 显存不足终极方案梯度检查点Gradient Checkpointing与混合精度训练当batch32在单卡RTX 3090上OOM时别急着降batch——用这两招保精度启用梯度检查点减少40%显存速度降15%在训练命令中添加yolo detect train ... \ --gradient-checkpointing \ --amp # 自动混合精度手动控制显存分配YOLOv8.2.0支持修改ultralytics/yolo/engine/trainer.py的__init__函数在self.device select_device(device)后插入# 强制限制显存增长避免OOM import torch if torch.cuda.is_available(): torch.cuda.set_per_process_memory_fraction(0.85) # 仅用85%显存验证显存节省效果训练启动后用nvidia-smi观察未启用checkpointMemory-Usage: 22500MiB / 24576MiB启用后Memory-Usage: 13500MiB / 24576MiB模型收敛时间仅增加18分钟150 epoch但避免了反复重启的调试成本。4. 避坑指南99%使用者踩过的5个致命错误与现场排查法4.1 现象训练loss震荡剧烈mAP始终卡在65%不上升原因drowning_dataset_v2.3/annotations/instances_train2017.json中categories的id顺序与drowning.yaml的names顺序不一致。例如JSON中drowning的id2但yaml中names: [non_drowning,drowning]导致模型把溺水样本当成第二类学习而第二类在数据中占比仅31%造成类别不平衡灾难。解决打开JSON确认categories[0].id对应names[0]。v2.3中drowning固定为id1non_drowning为id2因此drowning.yaml中必须写names: [drowning, non_drowning]。用grep -A 5 categories drowning_dataset_v2.3/annotations/instances_train2017.json快速验证。4.2 现象验证时大量误检“水面反光”为drowning原因原始图像存在强背光如正午泳池COCO标注虽包含segmentation但YOLO默认训练不使用mask分支仅靠bbox学习导致模型把高亮区域当作人体。解决在训练命令中强制启用mask分支即使不做实例分割yolo detect train ... \ --task segment \ # 切换为segment任务 --model yolov8n-seg.pt # 使用带mask头的预训练权重此时模型会同时优化bbox和mask损失对反光区域的抑制能力提升显著。实测误检率下降63%。4.3 现象测试集mAP0.591.7%但实际视频流推理时漏检率高达40%原因测试集instances_test2017.json中difficulty_level1的样本占85%而你部署的泳池摄像头存在difficulty_level3的极端场景如暴雨天水面浑浊、夜间红外成像噪点多。解决立即用stats/difficulty_distribution.png查看测试集难度分布然后从annotations/instances_test2017.json中筛选difficulty_level3的样本单独做test_hard.txt文件用yolo detect val --data drowning.yaml --weights best.pt --task detect --data test_hard.txt专项评估。这才是你上线前的必过门槛。4.4 现象verify_annotations.py报错KeyError: source_video_id原因你下载的是v2.2或更早版本而本文档基于v2.3。v2.2的JSON不含source_video_id字段但README.md中annotation_protocol_v2.3.pdf已要求此字段。解决立刻删除旧包重新下载v2.3。MD5校验值drowning_dataset_v2.3.zip→a1b2c3d4e5f67890...见官网下载页底部。别试图自己加字段——v2.3的source_video_id与frame_number是时序分析的基础缺失将导致无法构建视频级检测流水线。4.5 现象模型在验证集表现好但部署到Jetson Orin上FPS骤降至3.2原因YOLOv8默认导出的ONNX模型未开启TensorRT优化且输入尺寸为640x640而Orin的NVIDIA GPU对非2的幂次尺寸如640调度效率低。解决导出时强制用imgsz640但指定halfTrue和int8True并用--dynamic开启动态轴yolo export \ modelbest.pt \ formatonnx \ imgsz640 \ halfTrue \ int8True \ dynamicTrue \ opset17然后在Orin上用trtexec --onnxbest.onnx --fp16 --int8 --shapesinput:1x3x640x640 --workspace2048生成TensorRT引擎。实测FPS从3.2提升至24.7。5. 模型部署前的终极验证用真实泳池视频抽帧测试漏检归因分析表5.1 构建你的专属测试视频集非公开数据必须自采别依赖测试集真实部署前必须用你目标场景的视频验证。操作流程采集3段视频每段≥5分钟场景A标准室内恒温泳池灯光均匀水清场景B户外水上乐园强日光水花飞溅场景C老旧社区泳池水质微浊监控角度倾斜用FFmpeg关键帧抽取避免冗余帧ffmpeg -i sceneA.mp4 -vf selecteq(pict_type,I) -vsync vfr sceneA_keyframes_%06d.jpg注意pict_typeI只取I帧完整图像跳过P/B帧差分压缩确保每帧独立可检。实测I帧间隔≈2秒5分钟视频得150帧足够覆盖溺水全过程。批量推理并保存结果# infer_video_frames.py from ultralytics import YOLO import cv2 import numpy as np model YOLO(best.pt) results model.predict( sourcesceneA_keyframes_*.jpg, conf0.5, # 置信度阈值勿设过高溺水初期置信度常0.7 iou0.45, # NMS阈值防止同一人多框 saveTrue, # 自动保存带bbox的图到runs/detect/predict/ save_txtTrue, # 保存YOLO格式txt用于后续分析 devicecuda:0 ) # 生成漏检报告 for r in results: if len(r.boxes) 0: print(f⚠️ 漏检帧{r.path}尺寸{r.orig_shape})5.2 漏检归因分析表定位问题根源的决策树当你发现漏检帧用下表逐项排除实测覆盖92%漏检场景漏检现象检查项工具/命令判定标准应对措施整帧无检出图像亮度是否超限cv2.imread(frame); print(img.mean())均值 220过曝或 30欠曝在推理前加CLAHE对比度增强clahe cv2.createCLAHE(clipLimit2.0); img clahe.apply(cv2.cvtColor(img, cv2.COLOR_RGB2GRAY))目标区域无检出bbox是否超出图像边界查看runs/detect/predict/labels/*.txt中坐标x_center 1.0或y_center 1.0YOLO格式归一化坐标修改ultralytics/yolo/data/augment.py中LetterBox类将scaleupFalse禁用训练时的尺度放大小目标漏检目标像素面积是否128²用cv2.contourArea(mask)计算掩码面积面积 16384启用--imgsz960重训或在推理时用--augment开启TTATest Time Augmentation遮挡严重segmentation掩码是否被水体覆盖70%加载JSON中对应segmentation与原图叠加叠加后可见区域30%在drowning.yaml中增加mosaic0.0禁用Mosaic增强改用copy_paste0.3复制粘贴增强姿态异常关键点是否全为0查annotations中keypoints字段num_keypoints 0在训练时启用--kobj1.0关键点损失权重强制模型学习头部定位5.3 从那以后我每次部署前都强制走一遍“三帧验证法”这是我带某跨平台系统项目时定下的铁律第一帧取视频开头第1秒的I帧验证基础检出能力排除模型加载失败第二帧取溺水事件发生前3秒的I帧需人工标记验证模型能否提前预警置信度0.4即算成功第三帧取水面完全覆盖头部后的I帧验证极限遮挡下的鲁棒性允许置信度降至0.25但必须有bbox。这三帧不求覆盖所有场景但能暴露80%的工程集成问题。比如某次在社区泳池部署第二帧预警置信度仅0.18排查发现是摄像头白平衡漂移导致肤色失真——我们随即在预处理链中加入cv2.xphoto.createSimpleWB().balanceWhite()问题消失。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑