用有缺陷样本里的真实缺陷,给无缺陷样本合成逼真缺陷,扩充 YOLO 训练集。
核心思路:先用视觉大模型把真实缺陷编目成"缺陷库",再拿库里的缺陷作参考, 引导图像编辑模型在干净瓶身的局部裁块上复刻出同样的缺陷,最后只把缺陷区域 贴回原图 —— 掩膜以外的像素逐字节不变,保证光场、大小、形状、背景不被改动。
只关心两类缺陷:变形(褶皱/折痕/凹陷)和划痕。不做污渍/斑点/异物。
12 个类别,每个类别都要生成 700 张,四人各负责 3 个类:
| 人 | 负责类别 | 运行命令 |
|---|---|---|
| A | 1.jpg, 1.bmp, 5.1 | run.py gen-target --classes 1.jpg --count 700(三个类分别跑,见下) |
| B | 2.jpg, 2.bmp, 5.2 | run.py gen-target --classes 2.jpg --count 700 |
| C | 3.jpg, 3.bmp, 5.3 | run.py gen-target --classes 3.jpg --count 700 |
| D | 4.jpg, 4.bmp, 5.4 | run.py gen-target --classes 4.jpg --count 700 |
只跑自己负责的类别,不要跑别人的,避免重复消耗 API 额度。三个类别要分三次跑 (一次一个类别,方便断点续跑和排查问题),比如 A 依次执行:
.\.venv\Scripts\python.exe run.py gen-target --classes 1.jpg --count 700
.\.venv\Scripts\python.exe run.py gen-target --classes 1.bmp --count 700
.\.venv\Scripts\python.exe run.py gen-target --classes 5.1 --count 700给指定类别生成固定数量的样本,参考库按顺序循环使用,保证每个类别都能覆盖
到缺陷库里的每一条参考缺陷(而不是像 gen-sweep 那样受干净图数量限制)。
当前缺陷库过滤后约 653 条可用参考,--count 700 会让这 653 条各覆盖一遍,
多出的 47 张再从头循环一轮(覆盖两遍)。启动时会打印分配计划确认覆盖情况:
[plan] 1.jpg: 目标 700 张, 参考库 653 条 (完整覆盖 1 轮 + 前 47 条), 干净图 114 张(循环使用)
干净图只有 114 张,会被循环使用(同一张干净图会配上不同的参考缺陷生成多次), 这是预期行为,不是 bug。
git clone https://github.com/Kingpython123/yolo-dataAugmentation.git
cd yolo-dataAugmentation需要 Python 3.11(3.10+ 应该也可以)。
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install -r requirements.txt后面所有命令都用 .\.venv\Scripts\python.exe 开头,确保用的是虚拟环境里的 Python。
数据集体积太大没有进仓库,需要从共享盘/网盘拿。目录结构必须严格如下 (数据集放在项目的上一级目录):
父目录/
├── yolo-dataAugmentation/ ← clone 下来的代码(就是本项目)
│ ├── run.py
│ ├── config.yaml
│ └── outputs/catalog/ ← 缺陷库,已随 git 一起提供
└── 实拍负样本(无缺陷)/ ← 必需,放你负责的那三个类就行
├── 1.bmp/
├── 1.jpg/
└── 5.1/
注意:
- 只需要"无缺陷"数据集。"有缺陷"数据集不需要下载 —— 缺陷库
(
outputs/catalog/)已经建好并随仓库提供,里面含参考裁剪图和全部尺寸信息。 - 目录名必须是中文的
实拍负样本(无缺陷),括号是全角,跟原始数据集一致。 - 你只需要放自己负责的三个类别的子目录,其它类可以不放。
config.yaml 里的 api_key 是占位符,不要把真实 key 写进去(这个文件在 git 里,
写进去会泄露)。用环境变量注入,每次开新终端都要设一次:
$env:RELAY_API_KEY="sk-你的key"key 找 A 要。中转站地址已经写在 config.yaml 里,不用改。
# 1) 离线自检:验证分割/差分/回贴等图像环节正常
.\.venv\Scripts\python.exe run.py selftest
# 2) 缺陷库体检:应显示 668 条、裁剪图缺失 0
.\.venv\Scripts\python.exe run.py inspect
# 3) 连通性测试:验证 key 和中转站可用(会各调一次视觉/编辑模型,花一点点额度)
.\.venv\Scripts\python.exe run.py test-api第 1 步期望输出 分割前景占比 = 0.281、掩膜外像素变化比例 = 0.00000。
第 2 步如果提示"裁剪图缺失"不为 0,说明 outputs/catalog/crops/ 没拉全,重新 clone。
# 换成你自己负责的类别, 三个类分三次跑
.\.venv\Scripts\python.exe run.py gen-target --classes 1.jpg --count 700- 单张约 50~60 秒(要调用一次图像编辑 + 一次质检,都是大模型), 3 并发,700 张大约 3.5~4.5 小时。三个类别加起来约 11~14 小时, 务必挂后台跑,别关终端,也别一次跑完再走开——建议先跑一小批确认没问题。
- 进度会实时显示,中途可以 Ctrl+C 中断。
- 支持断点续跑:再次运行同样的命令会自动跳过已完成的样本,不会重复烧额度。
想强制重跑加
--force。
第一次务必先跑一个小数量确认没问题,比如:
.\.venv\Scripts\python.exe run.py gen-target --classes 1.jpg --count 10确认 outputs/generated/1.jpg/ 和 outputs/rejected/1.jpg/ 里的图质量正常后,
再跑 --count 700 的正式量。正式量跑起来后如果中途发现问题,Ctrl+C 停掉,
改完配置后重新执行同样的命令即可(断点续跑会跳过已完成的,不会重复烧额度)。
| 参数 | 说明 |
|---|---|
--force |
忽略断点续跑,重新生成 |
还有一个
gen-sweep命令(每条参考只用一次,产出数量受干净图数量限制), 用于早期小规模验证,分工生成请统一用gen-target,保证每人产出量一致 且都能覆盖到完整参考库。
跑完后产物在 outputs/ 下:
outputs/
├── generated/<类别>/*.png 质检通过的合成图
├── masks/<类别>/*_mask.png 对应的缺陷掩膜
├── rejected/<类别>/*.png 质检没过的合成图
└── annotations.jsonl 每张图一条记录(质检分数、裁块坐标、参考来源)
rejected/ 不是"废图"。质检是自动打分的,阈值偏严,里面有相当比例是
质量完全可用、只是某一项分数差一点被拦下的(实测有综合分 7.5 分的样本
仅因一项主观判断被驳回)。所以:
- 把
outputs/generated/和outputs/rejected/都打包提交 - 后续人工统一筛选,挑出能用的进训练集
annotations.jsonl也一起交,里面有每张图的质检分数,方便筛选时排序参考
打包时可以跳过 outputs/debug/(中间产物,体积很大,约 2GB,只在排查问题时才需要)。
人工筛的时候注意两点:
- 缺陷面积大、变形夸张不是缺点。真实样本里本来就存在大面积严重褶皱, 不要因为"变形太夸张"而丢掉。
- 有少数样本缺陷可能画到了桌布/背景上(1~4.bmp 这几类的自动分割区分不了 浅色桌布和瓶身背光面)。这种图不用丢,人工打标签时不给桌布上的缺陷打框即可。
| 现象 | 原因 / 处理 |
|---|---|
请先在 config.yaml 的 api.api_key 填入中转站的 key |
环境变量没设,重新 $env:RELAY_API_KEY="sk-..." |
缺陷库不存在 |
没在项目根目录下运行,cd 到含 run.py 的目录 |
类别无干净图 |
数据集路径不对,检查是否放在项目上一级、目录名是否为全角括号 |
大量 [warn] 编辑失败 |
中转站不稳定或额度不足,等一会重跑(断点续跑不会重复消耗) |
| 跑到一半中断 | 直接重跑同样的命令,会自动接着跑 |
排查具体某张图为什么不理想,可以看中间产物(config.yaml 里 debug: true 时会保存):
# 把某个类的中间产物拼成对比图:参考 → 浮雕图 → 目标块 → 模型输出 → 对齐后 → 掩膜
.\.venv\Scripts\python.exe run.py debug-preview --classes 1.bmp| 命令 | 花钱 | 说明 |
|---|---|---|
run.py selftest |
✗ | 离线自检图像环节 |
run.py inspect |
✗ | 缺陷库体检 |
run.py seg-check |
✗ | 瓶身分割效果预览 |
run.py debug-preview |
✗ | 中间产物拼图查看 |
run.py requalify |
✗ | 按当前阈值离线重判已有样本 |
run.py test-api |
极少 | 连通性测试 |
run.py gen-target --classes X --count N |
✓ | 正式生成(主命令) |
run.py gen-sweep --classes X,Y,Z |
✓ | 每条参考只用一次(早期验证用) |
run.py gen-ref --reference-entry ID --classes X |
✓ | 固定某条参考做定向实验 |
run.py build-catalog |
✓✓ | 重建缺陷库(不要跑,库已建好) |
build-catalog,缺陷库已经建好并随仓库提供,重建会消耗大量额度
且可能覆盖现有库。
单张合成的 10 个步骤:
- 选参考缺陷 —
gen-target模式下参考库按顺序循环使用,保证全覆盖 - 瓶身分割 + 自适应裁块 — 背景 = 与画面边界连通的暗区;裁块按参考 bbox 比例换算
- 参考引导编辑 — 给
gpt-image-2送三张图:目标裁块 + 参考彩色裁剪 + 参考的灰度浮雕图(只含褶皱几何,剥离源瓶颜色/印刷/高光,避免过曝亮边被照抄) - 光度对齐 — 把模型输出的全局亮度/色偏拉回目标水平,消除整图重渲染漂移
- 差分求掩膜 — 逐像素差分找出模型改动的区域
- 羽化 + 约束 — 与瓶身求交、裁块边界内缩归零(防止贴回后出现接缝断层)
- 掩膜有效性判定 — 区分"模型没改动"和"整块重绘",分别定向重试
- 掩膜回贴融合 —
结果 = 原图 + α×(编辑图−原图),掩膜外像素严格不变 - 多维质检 — 视觉模型六维打分 + 逐像素硬约束校验
- 落盘 — 合格进
generated/,否则重试(≤3 次)后进rejected/
架构图见 outputs/flow_diagram.html(浏览器打开,可打印为 PDF)。
设计原则:CV 只做度量与约束,不碰画面内容;画面内容 100% 由生成模型产生。
- 变形远多于划痕:缺陷库 668 条里变形占 93%、划痕仅 7%(划痕天生细线, VLM 给的 severity 天然偏低,已单独放宽门槛到 2 分,但基数依然偏少)。 700 张里划痕样本占比会明显低于变形。
- 1~4.bmp 的桌布问题:这几类是亮背景拍法,自动分割无法区分浅色桌布和 瓶身背光面,少数缺陷可能落在桌布上(人工标注时跳过即可)。
- 模型偶发不稳定:编辑模型可能调用失败或画得偏弱,122 张里可能有零星几张
质量不佳,会被隔离到
rejected/,不会污染generated/。