简介:面向瓶装白酒质量检测的计算机视觉数据集,压缩包约213MB,文件总数2000,主要包含4516张JPG图片与1个JSON标注文件。图片采集了瓶身划痕、标签破损、密封不良等多种常见疵品特征,同时也包含正常瓶装样本,覆盖正面、侧面等多角度视图,可用于疵品识别、图像分类、目标检测与异常检测等任务,为工业质检自动化模型提供基础训练素材。标注文件提供对应类别或位置信息,便于进行监督学习时的训练集、验证集与测试集划分,也方便使用准确率、精确率、召回率等指标评估模型。目录结构对应某一轮训练赛数据,可作为竞赛复现、算法研究或课程设计的直接输入。数据集在采集时考虑了光照、背景和焦点等因素,有助于减少无关变量干扰,适合训练卷积神经网络等模型,逐步提升产线上瓶装白酒质量的自动检测能力。已有292人学习下载,适合计算机视觉、工业自动化方向的研究人员、学生及质检系统开发者参考。
1. 瓶装白酒疵品检测数据集:先看清这张图里有什么
一个几千张图片的 zip 包摆到桌面上,真正决定模型上限的往往不是之后传入训练脚本的那行命令,而是包里图像与标注有没有和产线工况对齐。瓶装白酒疵品检测数据集,核心要解决的是灌装流水线上那几类高频缺陷:瓶盖歪斜与缺失、标签褶皱或破损、喷码模糊、液位异常、瓶身异物与裂纹。看起来是通用的目标检测任务,实际上它是一个强约束的固定工位场景——相机位姿基本不变、光照可控、被检物体是同一批瓶型。这种场景里背景差异小,缺陷与正常形态的差异反而更细微,比如标签褶皱和正常反光在视觉上只差几个像素的纹理梯度。需要这套数据的人,通常是拿它快速验证 YOLOv8 训练闭环、标注质量和模型在固定工位检测上的可用性,而不是把它当成通用 benchmark 来刷分。数据集的真实工作量也集中在解压校验、目录解析、标注审查和按缺陷类别做评估这几步。
2. 数据集的目录结构与标注格式:YOLO 标签怎么和图像对上
2.1 目录组织别急着猜,用 find 看一遍再写解析脚本
拿到 zip 包后,先把文件解压到干净的目录,再全量看目录结构。很多人在这一步直接打开 annotations 目录,发现里面有 JSON 或 XML,就默认按 COCO2017 数据集结构去写解析脚本,但瓶装白酒产线数据更常按「train / val 分离 + images / labels 平行目录」组织,标注格式以 YOLO txt 为主,偶尔带一个 data.yaml 或 classes.txt。先跑一段命令把目录看全,比什么都稳:
unzip -q bottle_quality_dataset.zip -d ./baijiu_data && cd ./baijiu_data find . -maxdepth 3 -type d | sort find . -name "*.txt" | wc -l find . -name "*.jpg" -o -name "*.png" | wc -l第一条命令把压缩包解压到 baijiu_data 目录,-q是安静模式,避免大文件解压时刷屏;第二条列出前 3 层目录,重点看 images、labels、train、val 这几个目录是否存在且同级;后面两条分别统计标注文件和图片数量。如果标注 txt 数量和图片数量差得很大,说明存在大量空标注图片,这类图片对缺陷检测模型是「负样本」,后面类别分布统计时要单独看。这里不建议用 Windows 解压工具自带的重命名功能,很多中文文件名在跨平台传输后会变成乱码,Linux 环境里直接用 unzip 最稳。
2.2 YOLO 坐标归一化:每个标签都藏在 0 到 1 之间
YOLO 格式的每个 txt 文件对应一张同名图片,每行代表一个目标,格式是固定的五列:class_id x_center y_center width height,其中四个坐标值全部归一化到 0 到 1 之间,分别除以图片宽高得到。如果标注工具导出的是 COCO 格式或 VOC 格式,转成 YOLO 时还要额外做一次坐标除法,很多瑕疵检测数据集在转换这一步就埋了雷:比如某张 4032×3024 的产线原图缩放到 640 后标签没跟着缩,框直接偏到图像外。
0 0.591406 0.294973 0.117188 0.063492 2 0.328125 0.870370 0.271094 0.216931第一列是类别编号,0和2必须和 data.yaml 里的类别顺序严格对应,模型按编号读取类别名,编号错了预测结果就张冠李戴。后四列是归一化后的框坐标,框的中心点和宽高都在 0 到 1 区间内,这是 YOLO 系列模型统一要求的输入格式。拿到数据集后抽三个 txt,用下面这段 Python 脚本验证坐标是否有越界、宽高是否为负,比肉眼翻图片效率高得多:
import os from pathlib import Path label_dir = Path("./baijiu_data/labels/train") error_lines = [] for txt_path in label_dir.glob("*.txt"): for line_no, line in enumerate(txt_path.read_text().splitlines(), 1): parts = line.split() if len(parts) != 5: error_lines.append((txt_path.name, line_no, "列数不为5")) continue cid, x, y, w, h = parts[0], *map(float, parts[1:]) if not (0 <= x <= 1 and 0 <= y <= 1): error_lines.append((txt_path.name, line_no, "中心点越界")) if w <= 0 or h <= 0 or x + w / 2 > 1 or y + h / 2 > 1: error_lines.append((txt_path.name, line_no, "宽高非法或框越界")) print(f"共检查 {len(list(label_dir.glob('*.txt')))} 个标签文件") for err in error_lines[:20]: print(err)这段逻辑分三层:先检查列数是否为 5,列数不对说明标注工具导出格式有问题;再检查中心点是否在 [0, 1] 范围内;最后检查宽高是否是正数,且框右下角是否超出图像边界。框越界在酒瓶检测数据里很常见,因为酒瓶颈部细长,标注时框容易画到图外,这类目标在训练时梯度会异常,影响边界回归的稳定性。越界的标注建议直接用脚本过滤或重算,而不是留到训练后让模型自己学。
2.3 解压与数据一致性校验:EOCD 报错、图片损坏和名字错位
数据集以 zip 形式分发,最容易出问题的是压缩包在传输过程中出现截断。在 Linux 下解压时若出现failed to copy spatial iop zip或invalid zip archive: could not find EOCD,一般是包不完整,EOCD(End of Central Directory)记录被截掉,这时任何解压工具都救不回来,只能重新获取源文件。包本身完好的情况下,也建议先做一次完整性校验:
unzip -t bottle_quality_dataset.zip | tail -n 5-t会让 unzip 逐文件计算 CRC 校验值并与压缩包内记录比对,tail 只显示最后几行,其中有No errors detected就说明包完整。不要跳过这步直接解压,ZIP 的目录结构在文件末尾,部分解压工具读到目录就开始暴力解压,磁盘写了一半才发现文件损坏,后面再排查反而浪费时间。解压完成后,还有一个常见问题是图片和标注文件名错位,比如img_0231.jpg对应的标签写成了img_0232.txt,这会让模型拿瓶盖缺陷的标签去学瓶身裂纹的图像,训练曲线看起来正常,但验证集 mAP 永远卡在低位。用 2.2 节里的脚本检查坐标合法性之外,还要补一层文件名对拍,把同目录下前缀相同但扩展名不同的文件做一一对应,数量对不上就说明有脏数据混入。
3. 用 YOLOv8 训练瓶装白酒疵品检测模型的全流程命令与参数
3.1 data.yaml 里的三个关键配置:类别顺序、路径映射与尾随空格
YOLOv8 训练自己的数据集,第一步是写好 data.yaml。这个文件决定了模型看到多少个类别、从哪里读训练和验证图片。以下是一个瓶装白酒缺陷检测场景的配置示例:
path: /data/baijiu_data train: images/train val: images/val names: 0: cap_defect 1: label_wrinkle 2: label_broken 3: code_blur 4: liquid_abnormal 5: bottle_crackpath 指向数据集根目录,train 和 val 是相对 path 的目录,不要写绝对路径到 images 那一层,YOLOv8 会自动拼接。names 里的编号顺序必须和标签文件第一列的数字保持一致,编号 0 是背景之外第一个类别。这里有个容易踩的坑:标签里出现6,但 names 只定义到 5,训练会直接报错 class index out of range;标签里类别编号从 1 开始而 yaml 从 0 开始,模型会把所有目标当成第二类,表现是某个类别 mAP 为 0,其他类别全部错位。另外 yaml 文件不要用记事本编辑并保存为带 BOM 的 UTF-8,ultralytics 解析时会报 Unexpected character,用 VS Code 或 vim 重写一遍就好。
3.2 第一次训练跑通的最小命令与 5 个必调参数
命令本身不复杂,关键在参数取舍。固定工位的瓶装白酒检测,成像条件稳定,模型容量不需要太大,第一次训练我一般会用 yolov8s 作为基线,跑 100 轮,看收敛曲线再决定是否换模型。
yolo detect train \ model=yolov8s.pt \ data=/data/baijiu_data/data.yaml \ epochs=100 \ imgsz=640 \ batch=16 \ workers=4 \ device=0 \ patience=20 \ project=./runs/baijiu \ name=v8s_baseline参数说明分段来看。imgsz=640是训练分辨率,产线原图多为 3000 像素以上的大图,模型内部会做缩放,640 是速度和精度的平衡点;batch=16按显存调,12GB 显存跑 640 分辨率一般能到 16,显存不够就降到 8,不要动 imgsz 去迁就 batch,酒瓶裂纹这类细小缺陷对分辨率很敏感;patience=20是早停轮数,验证集指标连续 20 轮不涨就停,避免无效训练时间。下面这张表是几个关键参数对训练结果的影响方向:
| 参数 | 调大后的效果 | 典型风险 |
|---|---|---|
| imgsz | 小目标召回率上升,边界更精细 | 显存翻倍,训练时间变长 |
| batch | 梯度更稳定,收敛更快 | 显存溢出,BN 统计量失真 |
| patience | 减少无效等待 | 过大容易过拟合验证集 |
| workers | 数据加载更快 | 过大时 CPU 成为瓶颈 |
| mosaic | 丰富背景和尺度分布 | 固定工位场景下可能引入无关背景 |
这里单独说 mosaic。YOLOv8 默认开启 mosaic 数据增强,训练时把 4 张图拼成一张,对通用检测很有效。但瓶装白酒产线场景背景高度一致,物体永远在画面中央,mosaic 拼出的图反而偏离真实分布,尤其是 bottle_crack 这种只占几十像素的小目标,拼图后边界更容易被截断。如果训了 20 轮发现验证集 mAP 震荡剧烈,先把 mosaic 关掉跑一轮对比,固定工位场景常常涨点。
3.3 标注审查:从预测框反推错标与漏标
第一次训练结束后,先别急着调参,用训练好的权重跑一遍验证集预测,然后抽查预测结果,这一步能暴露大量标注问题。常见做法是把预测结果保存成图片,按缺陷类别分组人工看一遍。下表是瓶装白酒场景里几类典型标注问题在预测结果上的表现:
| 标注问题 | 预测表现 | 原因分析 |
|---|---|---|
| 框画得过大 | 预测框比缺陷区域大一圈 | 标注时把阴影或反光区域也包进框里 |
| 漏标 | 同一位置有时有框有时没框 | 该缺陷在部分图片里没被标出 |
| 类别贴错 | 两类的置信度接近且持续互换 | 标注规范里对类别边界定义不清 |
| 框偏移 | 预测框偏移方向与标注一致 | 标注工具默认框中心线偏移 |
这一步最关键的是区分「模型没学好」和「标注本身就是错的」。我的经验是每类抽 20 张预测图,按上述四条逐一对照,如果某类缺陷 20 张里有 5 张以上标注有问题,修标注比调参收益大得多。
4. 训练集常见的坑:类别失衡、小目标和标注噪声
4.1 先算类别分布,再决定要不要调权重
瓶装白酒疵品数据集里,类别不平衡几乎是必然的,标签破损可能只有几百个框,液位异常却有两万个框。YOLOv8 默认按类别频率采样,多数类会主导梯度方向,少数类学不好。先跑一段统计脚本,把每类目标数量和每张图的框数分布打出来:
from collections import Counter from pathlib import Path label_dir = Path("./baijiu_data/labels/train") class_counter = Counter() boxes_per_image = [] for txt_path in label_dir.glob("*.txt"): lines = txt_path.read_text().splitlines() boxes_per_image.append(len(lines)) class_counter.update(int(line.split()[0]) for line in lines if line.strip()) print("类别编号 -> 目标数量") for cid in sorted(class_counter): print(f" {cid}: {class_counter[cid]}") print("平均每图框数:", sum(boxes_per_image) / len(boxes_per_image))判断是否要调权重的标准不是看类别数量差,而是看绝对量。如果某个类别只有 50 个框,再怎么调权重也很难学会,这时候应该想的不是权重,而是补数据或对该类做针对性增强。如果某个类别有 2000 个框,但只出现在 100 张图里,说明这 100 张图是从同一批次采集的,背景高度相似,模型学到的可能是背景而不是缺陷本身,这种情况下要检查训练集里该类图片的多样性。固定工位数据很容易出现这种「数量够但多样性差」的假象。
4.2 小目标缺陷的两种处理思路:更大的 imgsz 与滑窗切图
酒瓶裂纹、喷码模糊这类缺陷在 640×640 下往往只有 20×20 像素大小,属于典型小目标。YOLOv8 在 COCO 上的小目标 AP 本来就偏低,直接训产线数据效果不会好。两种调整手段我都很常用,各有侧重。
第一种是把 imgsz 从 640 提到 960 或 1280,简单直接,对小目标召回率的提升立竿见影,代价是训练时间翻倍、显存占用大幅上升。第二种是滑窗切图,把 3000×3000 的产线原图切成若干 640×640 的 patch,再按 patch 训练。切图后图像信息没有丢失,模型可以看到原始分辨率下的缺陷纹理,这是提升小目标检测最有效的方法。切图时要保证相邻 patch 有 10% 的重叠,避免缺陷正好落在切缝处被截断。产线固定工位场景里,瓶子在画面中的位置相对固定,切出来的 patch 类别分布相对稳定,不像通用场景那样容易切出大量背景 patch,所以这个方法在瓶装白酒检测里尤其好用。
4.3 标注噪声怎么修:错框、漏框、类别贴错各自的影响
标注噪声对检测模型的影响不是线性的。边界框偏移 5% 以内,模型基本不受影响,因为 IoU 仍高于 0.7 的匹配阈值;但漏框和错框的影响要大得多。一个漏标的缺陷会被当作背景参与训练,模型会在该位置学到「这里没有目标」的负反馈,同一位置的一个正样本往往需要多个负样本来抵消,所以漏框严重的数据集会表现为召回率低且怎么调都上不去。类别贴错的框会把模型往错误方向推,两个形态相近的类别之间尤其明显,比如 label_wrinkle 和 label_broken,特征差异本来就小,标签再互串,模型学到的决策边界会混乱,验证集上这两类互相误检。修标注噪声的原则是:先修漏框,再修类别贴错,最后才修边界框偏移。漏框影响的是召回率的上限,类别错误影响的是精确率,而边界框偏移对最终 IoU 指标的影响最轻,可以留到模型稳定后再精细调整。
5. 验证与迭代:先看漏检再看误检,按缺陷类型修数据
5.1 用混淆矩阵定位最该修的数据子集
训练结束后不要只看 validation 目录下打印的 mAP50 和 mAP50-95,这两个数字是全局平均,掩盖了类别间的差异。用 YOLOv8 自带的验证命令输出混淆矩阵:
yolo detect val \ model=./runs/baijiu/v8s_baseline/weights/best.pt \ data=/data/baijiu_data/data.yaml \ split=val \ plots=Trueplots=True会在 run 目录下生成 confusion_matrix.png 和各指标的曲线图。看混淆矩阵时遵循一个顺序:先看对角线之外哪里最亮,对角线之外最亮的方块指向的是最容易混淆的缺陷组合,比如 cap_defect 被识别成 label_wrinkle,说明这两类缺陷在训练集里形态接近或者标注边界不清;再看背景列,背景列数值大说明误检严重,模型把正常瓶身纹理或反光当成了缺陷,这时候修数据的方向是补充难负样本,而不是继续叠加增强。
5.2 按缺陷类别拆出来的 PR 曲线比整体 mAP 更说明问题
整体 mAP 被多数类主导,liquid_abnormal 这类易学类别会把平均值拉高,掩盖 bottle_crack 的低召回。按类别查看 PR 曲线,能直观看到每一类在哪个置信度阈值下召回率断崖下降。对固定工位检测来说,漏检比误检致命,产线里漏掉一个疵品意味着缺陷流到后端,而误检只要加一道人工复检即可兜底。如果某类 PR 曲线的膝盖出现在 0.7 置信度以下,说明模型对该类的特征学习不够充分,优先回到 4.2 节的小目标方案去调整,而不是一味调低置信度阈值。
5.3 三类高频修正:合并碎框、补漏标、重画模糊边界
以验证结果为输入,常见的修数据操作有三步。第一步是合并碎框。标签褶皱这类连续缺陷常被标成多个小框,导致一个完整缺陷被拆成三四个目标,训练时模型输出多个低置信度框,NMS 之后乱成一团,用标注工具把同一条褶皱上的小框合并成一个大框即可。第二步是补漏标。把预测结果和人工复核结合,优先补那些模型置信度低但人眼确认的缺陷样本,这是提升召回率最直接的手段。第三步是重画类别边界。标签破损和标签起皱如果持续互相误检,重新对标标注规范,明确「破损」必须是可见的撕裂或缺口,「起皱」是表面不平整,然后按新规范修标签。每次修完数据,重新训练一轮,对比混淆矩阵里的目标格是否变暗,而不是看总 mAP 有没有涨——总 mAP 涨了可能是因为多数类被优化得更好,而你要修的少数类毫无起色。
本文还有配套的精品资源,点击获取