
简介工业液滴气泡多目标检测数据集面向化工、能源、环保及流体力学研究人群专用于YOLO等深度学习模型的训练与验证。数据覆盖管道运输、流体实验、工业反应器等场景将目标细分为单液滴、单气泡、液泡混合体与高密度液滴群四类并包含密集小目标、不同光照与拍摄角度的样本适合开展气液两相流实时监测、雾化过程追踪及多尺度检测算法研究。资源共2000个文件以txt标注文件为主1971个配合jpg图像、yaml配置文件与docx说明文档压缩包仅26.32MB原生YOLO格式便于快速投入训练。目前已有335人学习浏览。借助该数据集可构建工业数字孪生视觉模块、校验流体力学数值模拟结果也可为气泡破裂、液滴聚合等动态过程提供标注基准是工业场景目标检测与流体状态分析的高价值基础数据。1. 工业液滴气泡检测一个比通用目标更刁钻的数据集化工管道的监测画面里液滴和气泡在视觉上高度相似——都是近圆形、半透明、边缘带高光。用通用目标检测模型去跑这类场景最常见的错误不是漏检而是把气泡当成液滴、把液泡混合体拆成两个独立目标。这个数据集就是冲着这个问题来的训练集 1,219 张、验证集 752 张全部来自管道运输、流体实验、工业反应器等真实场景标注了单液滴0droplet、单气泡1bubble、液泡混合体2dropletbubble和高密度液滴群droplet四类目标图像规格统一为 1536×1536标注是原生 YOLO 格式拿来就能直接训练。适合做工业视觉、两相流监测和数字孪生视觉模块的工程师也适合正在用 YOLOv8 或 YOLOv12 折腾密集小目标检测的人。2. 数据集结构与YOLO标注体系四类目标为什么这样分拿到的压缩包解开之后内容很干净图片和同名 txt 标签分目录存放文件名保留着采集时的信息比如Slice237_JPG_jpg.rf.xxx.jpg.rf.说明图片走过了 Roboflow 的导出流程后面的哈希串是导出任务的唯一标识。数据集本体没有套额外目录壳解压后按 YOLO 项目惯例把images和labels归位就能用。2.1 四类标注的划分逻辑与类名陷阱四类目标不是简单按“是液滴还是气泡”切的而是按流体形态和检测难度双重维度划分类别编号类名物理含义检测难点00droplet离散液态微粒与气泡视觉特征接近边缘高光相似11bubble气体在液体中的独立形态半透明内部纹理弱易漏检22dropletbubble气液两相复合体边界不规则单检测框内特征混杂3droplet高密度液滴群密集排列相互遮挡小目标尺度单液滴和液滴群拆成两个类是这套标注最专业的地方。密度不同检测器的处理策略就该不同——稀疏液滴可以依赖全局特征密集液滴群必须靠局部对比度和边缘分离能力。训练时如果合并成一类网络很容易学会“见圆就算液滴”结果在气泡边缘产生大量误检。这里有个配置文件层面的坑类名0droplet以数字开头3号类名直接叫droplet和0号类名是不同字符串。写 data.yaml 时names 列表必须严格对应编号0号位置是字符串0droplet不是droplet。不少人在这里手滑把两个类名写重训练时 loss 直接异常。2.2 YOLO归一化标注的解析方法与统计脚本标注文件是标准 YOLO 格式每行五个数值class_id x_center y_center width height坐标都是相对图片宽高的归一化比例。打开一个标注文本内容长这样0 0.4312 0.5521 0.0214 0.0198 1 0.7302 0.4123 0.0179 0.0231 2 0.5055 0.6389 0.0482 0.0366 3 0.2734 0.7301 0.0152 0.0147第一列是类别编号第三、四、五、六列分别是中心点 x、中心点 y、框宽、框高。由于是归一化坐标取值必须在0~1之间。解析整个数据集时不建议用肉眼检查直接写个 bash 统计各类别的标注框数量for split in train val; do echo $split cat labels/$split/*.txt \ | awk {print $1} \ | sort | uniq -c \ | sort -k2 -n done这段命令把所有 txt 的第一列类别编号取出来按编号统计数量。编号集中分布在 0~3 属于正常如果出现 4 以上的编号说明标注导出时类别映射出了问题。统计结果还可以用来判断类别均衡性——密集液滴群3 号类的框数量通常会远多于其他类因为一张图里可能有几十个密集液滴框。2.3 用Python校验标注的完整性类别统计通过后还要检查标注框本身是否有效。常见问题有三个中心点越界、宽高为负或为 0、txt 文件空内容。写个小脚本批量扫描import os from collections import Counter label_dir labels/train cat_counter Counter() for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue path os.path.join(label_dir, fname) lines [l.strip() for l in open(path) if l.strip()] if len(lines) 0: print(f空标注: {fname}) for line in lines: parts line.split() if len(parts) ! 5: print(f格式异常: {fname} - {line}) continue cls, cx, cy, w, h int(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) if not (0 cx 1 and 0 cy 1): print(f中心点越界: {fname}) if w 0 or h 0 or w 1 or h 1: print(f宽高异常: {fname}) cat_counter[cls] 1 print(类别分布:, dict(cat_counter))脚本逻辑分三段先查空标注文件再查每行的列数是否为 5最后校验坐标范围。归一化坐标下中心点越界意味着标注框中心跑到画面外训练时这类样本的 loss 会被放大干扰收敛。宽高为 0 的框需要直接剔除。跑完后如果输出为空说明标注文件整体健康可以直接进入训练环节。3. 从1536×1536原图到YOLOv8/YOLOv12训练管道数据标注是 YOLO 格式的最大好处就是省掉了格式转换这一步。Ultralytics YOLO 的detect流程原生吃这套目录结构昨天解压完今天就能开训。但 1536×1536 的输入分辨率不是默认值YOLO 默认imgsz640直接训会把大量小液滴缩小到十几个像素检测性能会明显打折。这一章把从目录整理到训练启动的关键步骤过一遍。3.1 标准YOLO目录结构与data.yaml配置推荐目录组织方式industrial-droplet-bubble/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── dataset.yaml图片和标注txt一一对应文件名去掉扩展名后必须完全一致。dataset.yaml是 YOLO 训练入口最重要的配置文件指向数据集根目录并声明类别path: /data/industrial-droplet-bubble train: images/train val: images/val names: 0: 0droplet 1: 1bubble 2: 2dropletbubble 3: dropletpath建议写绝对路径避免相对路径在不同工作目录下解析失败。names的键是标注文件里的整数编号值是显示名。注意0droplet必须用引号包裹否则 YAML 解析器可能把它当作数字 0 处理导致类别映射错误。droplet3 号类和0droplet0 号类名字相近但语义完全不同一个代表密集液滴群一个代表单液滴别在阅读日志时混淆。3.2 训练命令与关键参数对照YOLOv8 直接训练yolo \ detect train \ datadataset.yaml \ modelyolov8m.pt \ imgsz1536 \ batch8 \ epochs120 \ optimizerAdamW \ lr01e-3 \ mosaic0.5 \ close_mosaic10用 YOLOv12 训练时只换 model 参数yolo \ detect train \ datadataset.yaml \ modelyolov12m.pt \ imgsz1536 \ batch8 \ epochs120关键参数按这个思路调参数推荐值说明imgsz1536与数据集原生分辨率一致避免小目标缩没batch4~16由显存决定优先保证 imgsz 不降epochs100~150密集小目标收敛慢120 轮起步optimizerAdamW比 SGD 对学习率更不敏感省调参mosaic0.5~1.0密集场景建议 0.5过高会让目标更小close_mosaic10最后 10 轮关闭 mosaic让模型适应真实分布imgsz1536是这份数据的核心参数。YOLO 会把输入图 resize 到这个尺寸再喂进网络1536 意味着保留原始分辨率的信息液滴群里的单个目标还能维持 20×20 像素以上的面积。显存不够时优先降 batch不要轻易降 imgsz——密集小目标场景下分辨率比 batch size 更影响最终精度。3.3 预训练权重与训练资源评估modelyolov8m.pt会先下载 COCO 预训练权重再开始训练这是迁移学习的标准做法。四类目标里液滴和气泡相对接近 COCO 里的球类、圆形物体底层特征可以复用。如果你打算跑 YOLOv12它的预训练库同样支持直接加载yolov12m.pt会自动拉取对应权重。显存估算给个参考1536×1536 输入、batch8、yolov8m 参数量约 2600 万在 24GB 显存的 4090 上能跑动。8GB 显存就降到 batch2配合梯度累积accumulate4等效到 batch8。再低就上第 4 章的切片方案别硬撑。4. 密集小目标的检测难点NMS、图块切片与增强参数密集液滴群这类目标难不在类别区分而在同一片区域里几十个相似目标挤在一起。训练好之后部署时的表现往往和训练时判若两人——问题多半出在后处理 NMS 和输入尺度适配。4.1 液滴群场景下NMS为什么会误杀NMS 的工作逻辑是所有检测框按置信度排序得分高的框保留和它 IoU 超过阈值的邻近框全部抑制。单液滴场景下这没问题但密集液滴群里两个真实液滴的框 IoU 可能高达 0.6——因为液滴本身就挨着。默认iou0.5的 NMS 会把其中一只当作重复检测直接丢掉。应对办法有两种。第一种是调低 NMS 阈值到iou0.3只抑制真正重叠的框。代价是可能多出一些碎框。第二种是提高max_det默认 300 的上限在密集场景可能不够用单张图上千个液滴时检测器输出会被截断。训练时可以直接在 data.yaml 里加上max_det: 1000让模型适应大候选量推理时再用更严格的 NMS 收一遍。4.2 显存不够时的切片推理方案1536 分辨率对显存是考验。部署机往往比训练机配置低如果跑不动整图推理切片tiling是成熟解法。SAHI 库就是干这个的把大图切成若干小块分别推理再合并结果pip install sahi推理脚本from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction model AutoDetectionModel.from_pretrained( model_typeyolov8, model_pathruns/detect/train/weights/best.pt, confidence_threshold0.25, devicecuda:0, ) result get_sliced_prediction( industrial_pipe_001.jpg, detection_modelmodel, slice_height512, slice_width512, overlap_height_ratio0.2, overlap_width_ratio0.2, )slice_height/width512将 1536×1536 图片切为 3×3 网格overlap设为 0.2 是为了避免目标正好骑在切片边界上被截断。合并时 SAHI 会做跨切片的去重。这个方案有两个优点单块推理显存占用大幅下降且每个目标在 512×512 小图上的像素占比变大小目标检测率反而比整图推理高。4.3 mosaic、close_mosaic与尺度增强的取舍增强参数的设置对密集目标影响很大。mosaic1.0时每张训练图由 4 张图拼接而成相当于把 4 个不同场景塞进一张图目标数量翻倍单个目标相对变小。液滴群本身已经够密集够小mosaic 再叠加会让目标退化成几个像素网络学到的是“密集噪声”而不是“密集液滴”。所以这里推荐mosaic0.5让模型在真实分布和增强分布之间交替学习。close_mosaic10的含义是训练最后 10 轮强制关闭 mosaic 增强。这个参数是 Ultralytics 的默认行为但很多人忽略它的意义训练后期模型已经接近收敛继续喂拼接图会让它适应“假分布”关闭后模型重新拟合真实数据分布AP 通常能涨 1~2 个点。尺度增强scale0.5建议保留但别拉太狠。小目标检测对尺度敏感过强的缩放会让液滴变小到不可分辨。旋转增强在这份数据上不建议开工业相机安装角度固定目标不会旋转 90 度旋转增强反而让模型学会识别倒置的液滴属于无效特征。5. 类别混淆排查与置信度阈值筛选技巧训练完一轮先别急着看 mAP。对这类近圆形目标更该关注的是混淆矩阵——两张类别易混AP 再高部署时也难受。5.1 从val混淆矩阵定位易混类验证结束后runs/detect/val目录下会生成confusion_matrix.png。重点看三类位置的数值液滴被误判为气泡的比例、气泡被误判为液滴的比例、液泡混合体被拆成单液滴或单气泡的比例。如果 2 号类液泡混合体大量落入 0 号和 1 号说明训练数据里混合体的边缘特征不够——混合体是复合形态单个框里同时存在液体和气体特征分布介于两者之间。解法是检查 2 号类标注框里是否混入了纯液滴或纯气泡的样本而不是急着调模型。5.2 低置信度可视化看漏检比看误检更有用要判断检测器对密集液滴群的“能力边界”用低阈值跑一遍可视化from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) model.predict( sourcedatasets/val/images, conf0.1, iou0.5, imgsz1536, saveTrue, projectdebug_vis, nameconf01, )savaTrue会把推理结果画框后存到debug_vis/conf01。把阈值放到 0.1 的目的不是用这个分数部署而是看模型“隐约觉得有但不敢确认”的目标长什么样。你会看到两类情况边界模糊的微小气泡被忽略或者两个相邻液滴只出一个框。前者说明输入分辨率还不够后者说明 NMS 或增强策略需要调整。这一步比刷 mAP 更直观能定位到具体物理场景。5.3 按类别设置差异化置信度阈值默认conf0.25对四类目标一刀切但实际场景里各类别的置信度分布差异很大。单液滴边界清晰模型给分普遍高气泡半透明、内部纹理弱给分偏低混合体特征混杂给分居中。统一阈值要么放过大量气泡误检要么丢掉真气泡。按类别拆分阈值是更好用的做法from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) preds model.predict( sourcedatasets/val/images, conf0.05, iou0.5, imgsz1536, verboseFalse, ) cls_threshold {0: 0.20, 1: 0.30, 2: 0.35, 3: 0.25} for p in preds: boxes p.boxes confs boxes.conf.cpu().numpy() cls_ids boxes.cls.cpu().numpy().astype(int) keep [] for i, cls_id in enumerate(cls_ids): if confs[i] cls_threshold.get(cls_id, 0.25): keep.append(i)先以conf0.05跑出尽可能多的候选框再用类别字典过滤。0号液滴阈值放低到 0.20是因为液滴形体清晰、误检概率低宁可多框不能漏2号混合体阈值拉高到 0.35是因为它和液滴气泡的边界本来就不清低分数框大概率是错分。3号密集液滴群阈值设在 0.25保证群内弱目标能被留住。阈值配好后在漏检严重的局部区域把conf0.05的可视化图和conf过滤后的结果对比直到误检和漏检的平衡点符合你的业务要求。本文还有配套的精品资源点击获取