
简介面向计算机视觉目标检测任务的厨房积水检测数据集整合了Pascal VOC与YOLO两种标注格式适合需要训练积水、泡沫识别模型的算法工程师与研究者直接使用。全部图像聚焦厨房场景共标注foam泡沫与water水两个类别合计562个真实矩形标注框类别分布相对均衡每张图片均对应同名xml与txt标注文件可有效支撑目标检测模型的训练与验证。7z压缩包内共有268个文件包括90个txt文件、88个xml VOC标注、88张jpg原图以及2个ini系统配置文件整包仅18.23MB目录清晰便于快速下载、解压与数据划分。所有标注均使用labelImg工具人工绘制矩形框完成数据准确且标注规范同时明确不承诺任何训练模型精度可作为算法研究或教学实验的干净数据集来源。目前已有161人学习下载适合厨房场景异常积水检测项目的开发者作为起步数据使用时无需自行采集和标注图像可直接用于模型训练、验证与对比实验也适配课程设计或科研快速测试。1. 厨房积水检测数据集88张图够不够撑起一次真实落地后厨地面的一摊积水可能是食安检查扣分项也可能是员工滑倒事故的隐患。“厨房积水检测数据集VOCYOLO格式88张2类别.7z”这个数据集就是冲着这类场景来的两个类别把积水区和正常地面分开同时提供VOC和YOLO两套标注压缩成7z分包存放。88张图确实不多但配合预训练权重做迁移学习足够把一版能跑的积水检测模型拉起来验证“摄像头能不能自动识别后厨积水”这件事。它适合刚接到食安监管或后厨安全需求、需要快速出demo验证算法路线的团队也适合想用手头小数据集把YOLO训练流程完整走一遍的从业者。下面按格式拆解、数据准备、训练、避坑、进阶的顺序讲透。2. 拆开VOC和YOLO两套标注XML坐标和txt归一化坐标怎么对齐拿到这个数据集第一眼会看到两套标注目录一套VOC风格的XML一套YOLO风格的txt。同一批图片为什么给两种格式因为不同训练框架读取标注的方式不一样VOC是人可读的、方便质检YOLO是训练直接吃进去的、效率高。这一章把两套格式的字段含义、坐标体系和换算关系讲清后面训练时才不会在标注上翻车。2.1 VOC的XML结构左上右下坐标与object标签VOC格式按目录组织JPEGImages放原始图片Annotations放同名XML标注ImageSets/Main里放训练验证划分的txt列表。打开一个XML标注结构是这样的示意真实字段以压缩包内文件为准annotation folderJPEGImages/folder filenamekitchen_01_001.jpg/filename size width1280/width height720/height depth3/depth /size object namewater/name bndbox xmin412/xmin ymin265/ymin xmax890/xmax ymax610/ymax /bndbox /object object namenormal/name bndbox xmin50/xmin ymin600/ymin xmax500/xmax ymax710/ymax /bndbox /object /annotation这里最关键的是bndbox里的四个值xmin/ymin是框的左上角像素坐标xmax/ymax是右下角。它是绝对值依赖图片原始分辨率。object可以出现多个表示一张图里标了多个区域。2类别对应的是两个不同的name字符串——比如water代表积水、normal代表正常地面区域。注意VOC格式没有独立的类别清单文件类别全靠XML里的name字符串体现所以不同标注员手一抖拼错一个字母训练时就会多出一个莫名其妙的类别这是VOC格式“自由但松散”的固有坑。2.2 YOLO的txt格式归一化中心点才是训练真正吃的YOLO训练读取的标注是一张图对应一个同名txt每行一个目标格式是五个数字类别ID、归一化的中心点x、中心点y、宽w、高h。对应关系如下0 0.5086 0.5903 0.3734 0.4792 1 0.2148 0.9097 0.3516 0.1528第一列的0和1是类别ID由data.yaml里names列表的顺序决定。不像VOC里写的是可读的字符串这里就是数字。后面的四个数全部除以图片宽高做了归一化所以取值范围在0到1之间。如果看到某个值大于1基本可以确定标注越界或图片被resize过但标注没跟着更新。YOLO格式训练时读取效率高但人眼几乎没法直接检查所以它的质量全靠转换脚本和抽检兜底。VOC和YOLO两套坐标的核心差异在于VOC是绝对像素的左上右下YOLO是相对图片宽高的中心点加宽高。两者换算不是难点难的是在转换的时候保持类别映射一致。VOC里是字符串waterYOLO里是数字0如果转换时类别表的顺序变一下整个模型学到的东西就全错位了而且这种错位不会报错只会让预测结果变得莫名其妙。2.3 手工换算坐标一份脚本看懂从VOC到YOLO的映射不少工具号称一键转换但手工算一遍能彻底理解映射关系以后排查问题也更快。下面这个脚本按标准公式把VOC的XML转成YOLO的txtimport xml.etree.ElementTree as ET def voc_to_yolo(xml_path, img_w, img_h, class_map): 把单个VOC xml转成YOLO txt内容列表 tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_map: # 遇到没登记的类别直接跳过避免污染训练 continue box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # 中心点坐标 宽高再除以图片宽高归一化 cx (xmin xmax) / 2.0 / img_w cy (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{class_map[name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) return lines调用时需要传入图片的真实宽高而不是直接信任XML里size字段。图片后期如果被压缩过而XML没同步改这里就会算错。class_map是类别名到数字ID的固定映射比如{water: 0, normal: 1}这个映射一旦定下来就不能再变后续data.yaml、训练、推理全都要沿用同一份。脚本里保留6位小数就够用YOLO读取时按float解析更多位数没有任何实际意义。转换完成后txt文件必须和图片完全同名kitchen_01_001.jpg对应kitchen_01_001.txt大小写、空格、中文路径都尽量别碰否则训练时静默跳过。转换完不算完抽检才是关键一步。用OpenCV把txt里的框画回原图肉眼对比几个样本确认框的位置和类别都对得上。这一步是性价比最高的质控手段任何统计数字都替代不了。3. 从7z解压到yaml配置训练前的数据准备步步查格式看懂了接下来要把压缩包变成能训练的数据集目录。这一章覆盖四件事7z解压的通用命令、图片与标注的一致性校验、训练验证集划分的策略、以及data.yaml的编写。每一步都卡在后续训练的前置条件上漏一步后面就会反复返工。3.1 用7z命令解压Windows和Linux的常见做法拿到的是.7z压缩包第一步自然是解压。Windows上装7-Zip后右键解压即可但训练通常发生在Linux服务器上服务器默认没有7z命令需要先装。# Ubuntu / Debian sudo apt update sudo apt install -y p7zip-full # CentOS / RHEL sudo yum install -y p7zip p7zip-plugins # 解压到指定目录-o后面不要加空格 7z x kitchen_water_dataset.7z -o./kitchen_water解压参数里最常见的一个坑是-o写法-o与输出路径之间不能有空格写成-o ./kitchen_water会被当成文件名处理。另外解压命令用x而不是ex保留压缩包内的目录结构e会把所有文件摊平到一层目录结构被压平后后续按目录批量处理就乱了。解压如果遇到提示输入密码说明压缩包设了密码保护密码记错只能逐个试没有后悔药。解压完先看一眼目录结构是不是被包了两层比如kitchen_water/kitchen_water/xxx.jpg这种嵌套目录等下写路径的时候会把人绕晕提前调整好。3.2 图片与标注文件的一致性校验一个脚本统计完所有隐患训练前必须确认每张图片都有对应的标注文件。YOLO训练遇到缺标注的图只会打一条警告然后跳过不会报错这种静默最坑——你以为训练用了88张实际只用了75张指标还虚高。下面脚本一次做完配对检查和类别统计from pathlib import Path from collections import Counter img_dir Path(kitchen_water/images) # 根据实际解压路径改 lab_dir Path(kitchen_water/labels) # 用stem不带后缀的文件名做配对兼容jpg/png/jpeg imgs {p.stem for p in img_dir.glob(*.jpg)} imgs | {p.stem for p in img_dir.glob(*.png)} labs {p.stem for p in lab_dir.glob(*.txt)} print(缺标注的图片:, imgs - labs) print(缺图片的标注:, labs - imgs) # 统计每个txt的类别分布顺便发现空文件 class_cnt Counter() empty_files [] for p in lab_dir.glob(*.txt): lines [l.strip() for l in p.read_text().splitlines() if l.strip()] if not lines: empty_files.append(p.name) for line in lines: class_cnt[int(line.split()[0])] 1 print(类别分布:, dict(class_cnt)) print(空标注文件:, empty_files)脚本逻辑分三段第一段用文件主名做集合差找出缺配对的文件第二段读每个txt统计类别分布第三段单独揪出空文件。空txt比缺标注更隐蔽因为它对应的图片不会报警告只是这一张图没有任何目标参与训练。如果发现某张图是jpg后缀而Linux上实际是JPGglob匹配不上也得靠这个脚本暴露。统计完类别分布后如果两个类别数量悬殊后面训练时要考虑类别权重或扩增补偿。3.3 按积水场景划分训练集和验证集避免同类照片串组88张图怎么划分直接决定验证指标可不可信。常见做法是85/15或80/20但划分方式比比例更重要。这个数据集的图片大概率来自几个不同厨房环境或几段视频抽帧同一场景的相邻帧高度相似。如果直接随机shuffle相似帧会被同时分进训练集和验证集验证时模型其实见过同款mAP虚高得离谱一到现场立刻露馅。正确做法是按来源分组划分同一个场景的所有图片只能进训练集或验证集一侧。压缩包里不一定带场景分组信息一个变通办法是按文件名前缀分组from pathlib import Path import random random.seed(42) imgs sorted(Path(kitchen_water/images).glob(*.jpg)) # 按文件名首段分组让同一采集来源的图片统一进训练或验证 groups {} for p in imgs: key p.stem.split(_)[0] # kitchen_01_003.jpg - kitchen groups.setdefault(key, []).append(p) train_imgs, val_imgs [], [] for key, group in groups.items(): random.shuffle(group) split int(len(group) * 0.85) train_imgs group[:split] val_imgs group[split:] print(f训练 {len(train_imgs)} 张, 验证 {len(val_imgs)} 张)分组键选取是这段代码的灵活点如果发现同一场景的文件名前缀长度不同就把split(_)的前两段拼起来做key。比例上如果场景数很少比如只有两个厨房85/15会让验证集漏掉整个场景的样本这时调到70/30更合理或者直接用第6章的k-fold交叉验证做评估。划分结果要写进train.txt和val.txt每个路径一行供后续data.yaml引用。提示划分后随手统计一下验证集里两个类别的框数量。如果验证集某个类别只有一两个框评估结果几乎等于抽彩票调大验证集比例或改用k-fold。3.4 编写data.yaml路径、类别名和类别ID的顺序YOLOv8训练前需要一份data.yaml描述数据集位置和类别写错是新手报错重灾区。最小可用的配置如下# 数据集根目录建议写绝对路径 path: /home/yourname/kitchen_water train: train.txt # 训练集文件列表 val: val.txt # 验证集文件列表 # 类别ID - 类别名顺序必须和txt标注的第一列一致 names: 0: water 1: normalpath推荐写成绝对路径。相对路径在不同机器上解析规则不一致解压目录一变就可能出现训练时找不到图片的玄学问题。train和val既可以指向txt也可以指向目录指向txt的写法兼容性最好因为txt里每行一个图片路径路径怎么组织完全可控。names的顺序就是类别ID的定义和txt第一列的数字严格对应。写完之后做一个最小检查确认txt里出现的最大类别ID小于names的键数量再随便打开验证集的一张图和它的标注确认类别名和框的位置都正常。这三处统一了训练才敢开始。4. 用YOLOv8把这88张图训成能用的小模型命令与关键参数数据准备好了进入训练环节。这一章用的是YOLOv8配合ultralytics包命令简洁参数直给。重点讲清楚每个关键参数在小数据集下的取舍以及训练完怎么验证、怎么导出部署文件。4.1 环境安装与版本选择ultralytics包和PyTorch的匹配训练环境建议用独立的环境别直接往系统Python里塞依赖。常见做法是conda create -n yolo python3.10 -y conda activate yolo pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics8.0,9 yolo --help先装PyTorch再装ultralytics因为ultralytics会检测已有的torch版本决定是否重新安装。装完后先跑一下yolo --help确认命令行入口可用。有些服务器上yolo命令可能被其他包占用这时用python -m ultralytics代替即可。版本上把ultralytics锁在8.x不追最新的9.x避免命令参数变动造成的脚本失效。CPU机器也可以训练88张图、yolov8s、imgsz640单CPU训练一轮大概十几秒不是不能接受但GPU还是快得多。4.2 训练命令与关键参数epochs、batch、imgsz和预训练权重训练命令如下一行跑通yolo detect train \ datakitchen_water.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch8 \ patience20 \ projectruns/kitchen \ namewater_run1关键参数取舍如下参数建议值说明modelyolov8s.pt预训练权重迁移学习起点不要用yolov8xepochs100配合patience早停小数据集通常50轮内收敛batch888张图一轮才11个stepbatch太大会让BN统计不稳imgsz640YOLOv8默认积水区域小可提到800显存占用近翻倍patience20连续20轮验证集无提升就停防过拟合ampTrue默认开loss震荡时改成ampFalse再试为什么必须用预训练权重88张图从头训练卷积网络特征根本学不出来大概率loss降不下去或严重过拟合。yolov8s.pt在COCO上已经学好了通用的目标表征积水框的迁移成本低模型只需要适应“积水”和“正常地面”这两个新类别。不用yolov8m或yolov8x的原因很实际数据量撑不起大模型的参数量s对这个小数据集已经绰绰有余训练更快部署也更轻。batch8是折中方案太小则BN统计噪声大太大则一个epoch的梯度更新次数太少。如果训练时loss曲线剧烈震荡先关amp再考虑调小batch不要一上来就动学习率。4.3 从权重到推理验证指标和导出onnx的最小流程训练结束后验证和导出是连续动作# 验证输出mAP50、mAP50-95和混淆矩阵 yolo detect val \ modelruns/kitchen/water_run1/weights/best.pt \ datakitchen_water.yaml # 单图推理 yolo detect predict \ modelruns/kitchen/water_run1/weights/best.pt \ sourcetest_imgs/ \ conf0.25 \ saveTrue # 导出onnx给部署端 yolo export modelruns/kitchen/water_run1/weights/best.pt formatonnx验证结果里重点看两个数mAP50和mAP50-95。对积水这类面积占比不小的目标mAP50在0.8以上算合格mAP50-95受小框影响大0.4到0.6是常见区间不要拿它否定模型。混淆矩阵要瞄一眼如果normal那一类把大量框都吸收进去了说明模型在拿大框赌地面而不是真的区分积水回头去检查normal的标注是不是都把整块地面框进去了。推理时的conf阈值默认0.25现场误报多就往上调到0.4到0.5优先保准确率还是召回率看具体场景。导出onnx时注意imgsz要和部署端保持一致否则推理端还要额外做resize平白引入精度损耗。5. 厨房积水数据集训练避坑五个真实翻车现场与对应解法小数据集训练翻车点不多但每一个都挺隐蔽。这一章五条踩坑记录都按现象、原因、解决展开基本覆盖了这个数据集从解压到训练完最常见的意外。5.1 现象训练日志里出现大量no labels found警告训练集实际没满员现象是训练日志不断刷WARNING skipping ... no labels found背后的图全部被跳过但训练不报错一切照常继续。原因是图片和标注文件不同名或后缀大小写不一致。Windows上JPG和jpg不区分Linux上严格区分解压后换平台训练最容易触发。解决方式是训练前先跑3.2节的一致性脚本把缺配对的找出来统一改名或重新生成标注空txt直接删掉避免对应的图被静默跳过而没人发现。5.2 现象训练完预测时两个类别完全错乱地面反光被当成积水现象是预测结果里normal和water的预测框张冠李戴错得整整齐齐。原因几乎可以锁定类别映射错位VOC里是字符串water和normal转YOLO时如果class_map的排序变了一下ID就变了。比如有人按字典序排normal排到了0water排到了1而data.yaml里还写着0: water整个模型学到的就是反的。解决方式是从一开始就固定class_map并写进yaml不做第二次修改训练前拿已经标注过的图做一次predict验证框和类别名对上了再继续调参。类别映射错位不会报错只能靠人工抽检验证。5.3 现象验证集mAP50高达0.95一到现场就漏检现象是验证指标漂亮得不像话实测拍一段现场视频积水漏掉一半。原因是划分时随机shuffle同一段视频的相似帧同时进了训练和验证模型相当于提前见过“考题”。解决方式是按场景分组划分同源图片只进一侧条件允许的话从现场单独录一段完全不参与训练的“hold-out”视频做最终验收。验证集的作用是模拟没见过的数据如果验证集和训练集长得太像整个验证环节就失去了意义。5.4 现象训练loss降得很低mAP却剧烈波动甚至BN崩溃现象是loss曲线一路向下看起来收敛了但验证mAP忽高忽低有时直接掉到0.2。常见原因有两个一是batch太小导致BN统计量不稳定尤其是88张图配batch4时一个epoch只有22个stepBN的均值方差根本估计不准二是模型过拟合把训练集的积水纹理背了下来验证集稍微不同就崩。解决方式是把batch调到8到16关掉amp试试观察训练loss和验证loss的差距——验证loss先升训练loss继续降就是典型过拟合。这时候回调patience或减少epochs不要急着加数据增强先把优化稳定性稳住。5.5 现象7z解压报CRC错误或文件解不全现象是解压到一半报CRC校验失败或者解压完目录里缺文件。原因是压缩包下载不完整或传输过程中损坏也可能是用的老版本7z解压器不支持新压缩算法。解决方式是重新下载一次传输工具用支持断点续传的下载完先对比压缩包大小Linux上更新p7zip-full到最新版再解压Windows上7-Zip有修复功能可以尝试打开压缩包后执行File - Open - 修复但修复成功率看损坏程度不如重新下载靠谱。解压完立刻跑目录完整性检查数一下图片数量和标注数量别等到训练时才暴露。6. 小数据集的上限迁移学习起点、扩增策略与现场验证88张图的上限不在数据量在策略。最后一章讲三个让这个小数据集发挥更大价值的做法选对预训练起点、做对数据扩增、用现场视频做最终验收。6.1 从预训练权重起步而不是随机初始化常见做法是直接用yolov8s.pt做迁移学习。如果推理设备是低功耗边缘盒子可以把s换成n参数量更小、速度更快代价是精度略降。两个都训练一遍对比验证集mAP再决定部署用哪个时间成本很低。不要从零训练88张图从零训练出来的模型在真实场景下基本不可用。6.2 扩增策略里哪些适合积水检测积水检测的核心难点在反光和地面材质差异扩增要围绕这两点做。亮度对比度增强、mosaic、随机平移和缩放是主力hsv_h色相扰动要调小积水反光的颜色偏移太大反而让模型学到错误模式。可以参考这组参数yolo detect train \ datakitchen_water.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch8 \ patience20 \ hsv_h0.02 hsv_s0.6 hsv_v0.5 \ translate0.1 scale0.4 fliplr0.5 \ flipud0.3 mosaic1.0flipud能模拟摄像头安装高度变化带来的视角差异mosaic让小模型在有限数据下看到更多上下文。90度旋转不建议全开会让“地面积水”的语义变形。扩增不是越多越好小数据集叠加过多变换验证集指标会失真。6.3 用一段现场视频做最终验收所有验证集指标都是中间产物最终验收应该是一段现场视频。录5分钟不同光线、不同地面材质的视频按时间戳均匀抽帧用训练好的模型跑一遍统计漏报率和误报率按分钟画曲线看波动。这个方法比任何验证集指标都直观能暴露“某个时段反光强就集体漏检”这类真实问题。我自己做积水这类反光目标项目时最大的教训就是不要相信测试图片的视觉效果一定要用现场视频按分钟验收否则就是在拿验证集自我感动。这个习惯帮我避开了很多次部署现场返工希望帮到你。本文还有配套的精品资源点击获取