Repository navigation
Expand file tree
/
Copy pathconfig.yaml
More file actions
274 lines (263 loc) · 18.1 KB
/
Copy pathconfig.yaml
File metadata and controls
274 lines (263 loc) · 18.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# ============================================================
# 缺陷合成流水线配置
# 所有大模型调用走 OpenAI 兼容协议,适配你的"中转站"
# ============================================================
api:
# 中转站的 OpenAI 兼容地址,一般以 /v1 结尾
base_url: "https://api.gpt.ge/v1"
# 中转站的 key。请勿把真实 key 写在这里(本文件会进 git)。
# 用环境变量注入: PowerShell -> $env:RELAY_API_KEY="sk-xxxx"
# 也可用 RELAY_BASE_URL 覆盖上面的 base_url。
api_key: "REPLACE_ME_OR_USE_ENV_RELAY_API_KEY"
timeout: 300 # 单次请求超时(秒); gpt-image-2 出2K图常超180s
http_retries: 2 # 超时/连接失败的指数退避重试次数
max_workers: 3 # 并发线程数(编目/生成)。调高更快但注意中转站限流
models:
# 视觉理解模型(读图->结构化描述/定位/质检)。
vision: "gpt-5.6-sol"
# 图像编辑模型(参考引导地在裁块上加缺陷)。推荐:
# gemini-2.5-flash-image (nano-banana): 保持原图一致性最好, 全局漂移最小 -> 配 gemini_chat
# gpt-image-2: 支持1-8参考图 + 显式mask + 2K/4K, 细节强(会整图重渲染, 靠回贴兜底) -> 配 openai_images
# 备选: gpt-image-1 / qwen-image-edit / seedream
edit: "gpt-image-2"
# 图像编辑后端调用方式:
# gemini_chat -> 走 /chat/completions, 多图输入, 返回图(nano-banana/qwen-image-edit 常见)
# openai_images-> 走 /images/edits, 支持 参考图(image[]) + 显式 mask (gpt-image-2/1 / dall-e-2)
edit_backend: "openai_images"
data:
# ---- 类别命名约定: `<产品>_角度<N>` ----
# 现有类别(两个根目录都按这个命名):
# 500多效极润_角度1~4 AQUA MOIST 500mL, 暗背景, 1200x2400
# 60ml多效极润_角度1~4 60mL 不透明白瓶, 亮背景有桌布, 675x1370 (只有干净图,
# 没有缺陷样本 -> 只能用跨产品参考)
# 120蓝瓶_角度1~4 AQUA-SHINING 120mL 透明瓶, 796x1656
# (干净图只有角度4; 缺陷图 4 个角度都有)
# 500水次方_角度1~4 water labo / 海俪恩, 1200x2400
# 360森呼吸_角度1~4 1030x2350
# 改名原因(2026-08-26): 原名 1~4.jpg / 1~4.bmp / 5.1~5.4 看不出是哪种瓶子, 而且
# `1~4.bmp` 在两个根目录下是**不同产品**(正样本=120蓝瓶, 负样本=60ml多效极润)。
# 流水线按同名类别目录配对、cross_class 又只是目录名字符串比较, 于是"拿 60ml
# 白瓶当目标 + 120蓝瓶的缺陷当参考"被记成同类。实测当时缺陷库 212/838 条产品
# 归属标错。改名后产品身份写进类别名, 产品级判断走 dataset.product_of(),
# 标注新增 cross_product 字段。迁移脚本: tools/migrate_classes_by_product.py
#
# 瓶身 ROI(比例坐标 [x0, y0, x1, y1], 0~1), 按类别指定, 留空=整幅画面。
# 用途: 亮背景拍法(60ml多效极润 画面里有浅色桌布)无法自动把桌布与瓶身背光面分开,
# 固定工位下瓶子位置稳定, 因此直接框定范围。缺陷掩膜会与该矩形求交,
# 裁块也只会落在其中 -> 从根上避免"缺陷画到桌布上"。
# 暗背景拍法(500多效极润 / 500水次方)靠边界暗区剔除即可, 无需 ROI。
# 用 `python run.py seg-check --grid` 生成带比例网格的预览来读取坐标。
bottle_roi: {}
# 有缺陷样本根目录(相对本项目上一级)
defect_root: "../实拍正样本(有缺陷)"
# 无缺陷样本根目录
clean_root: "../实拍负样本(无缺陷)"
# 类别列表; 留空则自动扫描 defect_root 下的子目录
classes: []
# 允许的图片扩展名
extensions: [".bmp", ".jpg", ".jpeg", ".png"]
output:
root: "outputs" # 产物根目录
catalog: "outputs/catalog" # 缺陷目录(描述+裁剪)
images: "outputs/generated" # 合成图
masks: "outputs/masks" # 缺陷掩膜
rejected: "outputs/rejected" # 质检驳回的样本(不混入训练集, 供人工复核)
debug: "outputs/debug" # 中间产物(debug=true 时)
annotations: "outputs/annotations.jsonl" # 标注
# ---- 缺陷编目(build-catalog) ----
# 注意: 之前缺这一段, 代码走的是内置默认值, 这些旋钮无法调整。
# 下列取值与原默认值完全一致, 因此补上本段不会改变当前缺陷库的构建行为。
catalog:
# 缺陷类型白名单; 模型给出的近义词会被归一, 不在白名单的条目直接丢弃
defect_types: ["变形", "划痕"]
crop_pad_ratio: 0.35 # 划痕类: 参考裁剪在 bbox 外的外扩比例
crop_pad_ratio_deform: 0.7 # 变形类: 褶皱需要更多上下文才看得出走向
crop_min_size: 320 # 参考裁剪最短边下限(以缺陷为中心补足)
# 对参考裁剪做 CLAHE 增强后入库。会改变参考图的对比度与明暗关系,
# 生成模型可能照抄这种被拉高的对比 -> 默认关闭
enhance_reference: false
# 额外给编目用的 VLM 送一张 CLAHE 增强图辅助看清微弱褶皱(bbox 仍以原图为准)。
# 开启会让每张图的 VLM 输入翻倍(成本上升)
vlm_enhance_aid: false
generation:
patch_size: 768 # 局部编辑裁块边长下限(像素)
# 自适应裁块: 按参考缺陷 bbox 长边 × margin 决定裁块大小。
# 大面积褶皱塞进过小裁块会被迫画成缩小版 -> 表现为"缺陷不够夸张"
adaptive_patch: true
adaptive_patch_margin: 1.3
max_patch_size: 2048 # 裁块单边上限(图高2400, 竖向贯穿褶皱需要大值)
# 参考缺陷 severity 下限: 过弱的缺陷不适合当复刻标准(1~2分的建议排除)
min_reference_severity: 3
# 按类型单独设下限, 覆盖上面的通用值。
# 划痕本身就是细线, VLM 给的 severity 天然偏低(实测 7 条里 6 条是 1~2 分),
# 用统一的 3 分门槛会把划痕参考几乎全部滤掉 -> 产出里没有划痕样本。
min_reference_severity_by_type:
划痕: 2
num_per_clean: 2 # 每张干净图生成几个缺陷版本
allow_cross_class: true # 是否允许参考其他类别缺陷
cross_class_ratio: 0.35 # 使用跨类参考的比例(0~1)
# 结构参考图: 额外给模型一张"缺陷浮雕图", 只含褶皱几何,
# 剥离源瓶的颜色/印刷图案/光照与镜面高光 -> 避免过曝亮边被照抄。
# 实测: 中频(褶皱)保留~100%, 文字级高频残留降到32~50%, 低频光照 std 从38~49降到9.5~12
use_structure_reference: true
structure_sigma_small: 6.0 # 高频截断, 越大越能抹掉印刷文字(6.0 为甜点)
structure_sigma_large: 40.0 # 低频截断, 越小越能压掉源瓶整体光照
structure_gain: 3.0 # 浮雕对比增益
mask_binarize_thresh: 128 # 软alpha -> 二值标注掩膜的阈值
max_retries: 3 # 质检不过时最大重试次数(会按最弱维度定向强化)
# 光度对齐: 差分前把生成图的全局亮度/色偏对齐到原图,
# 否则模型整图重渲染的漂移会被误当作缺陷并被 defect_gain 放大
photometric_align: true
min_defect_area_ratio: 0.0005 # 缺陷占裁块比例下限(过小视为没生成)
# 单个连通域面积上限。面积是"全局漂移 vs 大面积褶皱"的很差判据: 真实的大褶皱
# 同样会连成贯通裁块的大域(实测 0.69~0.76)。旧值 0.45 会把这类缺陷整体丢弃,
# 表现为"模型压根没生成"。现已改为: 超限的域不再静默丢弃, 过滤后若掩膜为空
# 则回退保留最大的那个域, 由瓶身/边界约束裁剪、由质检判断贴回效果。
max_defect_area_ratio: 0.85
# 掩膜约束(只做限制, 不改画面):
# 裁块边界内缩比例。掩膜必须在触及裁块边缘前归零, 否则贴回后裁块内外的
# 标签图案接不上 -> 表现为"瓶身上下不一样"的断层
border_fade_ratio: 0.08
bottle_erode: 6 # 瓶身掩膜内缩(像素), 避开瓶身轮廓边缘
min_bottle_cover: 0.55 # 裁块内瓶身占比下限, 防止把缺陷画到桌布/背景上
debug: true # 存中间产物(原patch/模型原始输出/对齐后/mask/结果)便于归因
feather: 10 # 掩膜回贴羽化半径(仅 blend_mode=feather 时用)
# 融合方式:
# feather -> 羽化叠加, 完整保留褶皱强度(推荐, 默认)
# poisson_mixed-> 泊松梯度混合, 边缘最自然但会洗淡大面积低频褶皱(仅锐利缺陷可用)
# poisson -> 泊松替换
blend_mode: "feather"
# 缺陷增益: result = 原图 + gain*alpha*(编辑图-原图)
# 1.0 = 掩膜内完全采用模型输出, 不做任何像素增强(推荐, 默认)
# >1 会放大缺陷但实测会把高光削平(16~25%像素饱和), 严重损害融合自然度, 不建议开
defect_gain: 1.0
severity_adaptive_gain: false
# 缺陷差分阈值: 越小越能保留低对比褶皱(但过小会引入噪声), 默认18, 水立方微弱褶皱可试 10~14
diff_threshold: 14
seed: 42
# ---- 平坦底图编辑 + 乘性贴回(flat-edit) ----
# 解决"褶皱贴回后与标签文字重叠形成重影"的根因。
# 原因: 编辑模型整块重渲染, 底图上有文字它就会重画一遍(实测笔画平均偏移
# 1.15px, 粗细/对比度也变), 羽化过渡带里原文字与重画文字叠加 -> 重影。
# 事后低通能压重影但会同时磨平褶皱棱线(压到重影10%时棱线仅剩55%), 两者
# 频率重叠无法兼得。
# 解法: 把低通移到"输入"上 —— 先把裁块低通成只剩光照渐变的平坦底图再送模型,
# 模型没有文字可画, 只输出"平坦底色+褶皱明暗"; 用 编辑结果/平坦底图 求出
# 明暗调制场, 乘到原图上。原图墨迹只被调亮调暗、位置不动 -> 重影在构造上
# 不可能产生; 而棱线由分子提供(只有分母被模糊), 锐度不受损失。
# 附带收益: 差分是在无文字的一对图之间做的, 掩膜天然只框住褶皱,
# 顺带修掉了标注 bbox 被文字错位噪声虚增的问题。
# 已知让步: 文字不会随褶皱弯曲(只被调明暗)。对 YOLO 检测缺陷形态几乎无影响。
flat_edit: false
# 低通 sigma 按裁块短边比例取值(文字笔画宽度随分辨率等比变化)。
# 实测印刷边缘残留: sigma=8->15.3%, 12->10.8%, 20->6.1%, 24->5.0%;
# 而瓶身光照结构在 sigma<=40 时保留度始终 ~100%(光照尺度远大于文字),
# 所以放大 sigma 几乎免费, 不要停在 8~12。
flat_sigma_ratio: 0.022
flat_sigma_min: 12.0
flat_sigma_max: 32.0
# 暗部保护 eps 必须取相对值(eps = max(floor, ratio*底图亮度))。
# 固定 eps 会对暗区造成远比亮区严重的衰减: 实测真实阴影 s=0.6 时, eps=12 在
# 底图亮度10处只还原39.3%、20处56.3%, 而180处有92.0% —— 这是随亮度变化的
# 系统性偏差, 会让同一条参考在暗类别(3.jpg/4.jpg)上稳定地掉 severity。
# 取 eps=k*lf 时 (s+k)/(1+k) 与亮度无关, 衰减变均匀; k=0.05 时一律还原约94%
# (按真实像素分布加权, 各类别 90.8%~92.6%)。残余约6%的均匀衰减不做补偿:
# 它随 s 在 92~95% 间浮动, 不是严格常数, 硬补偿反而引入新的不精确。
ratio_eps_ratio: 0.05
ratio_eps_floor: 2.0
# 调制幅度边界。两侧都是 tanh 软饱和的"渐近线", 不是硬截断:
# 硬截断会把超限像素全部钉死在同一个值上, 形成深度完全一致的平台。实测上界
# 取 +0.30 硬截断时, 掩膜内平均 16.45% 的像素(个别样本 37.32%)被钉在边界上,
# 深浅不一的褶皱被压成同一档 -> 正是质检反馈的"亮边均匀、浮雕化"。
# 改软饱和后任何像素都取不到边界值, 超限部分被单调压缩而非抹平, 深浅次序
# 得以保留; 上下界都软化, 只软化一侧会引入不对称失真。
# 因为软饱和会让实际取值低于渐近线, 上界从 0.30 略放到 0.40 作为补偿
# (受光侧仍受"不得亮于周围完好标签"的物理约束, 不宜再大);
# 下界 -1.0 -> -1.10, 给深折痕留一点余量。死白风险由下面的软限幅膝点兜住。
# 注意 shading_strength 在饱和之前参与, 所以边界始终是真实的安全上限。
ratio_log_clamp_lo: -1.10
ratio_log_clamp_hi: 0.40
# 提亮侧软限幅膝点: 超过该值用 tanh 单调压缩、渐近趋近255但不触及。
# 旧的加性回贴是凸组合、结构上不会溢出所以不需要限幅; 乘性会真的越界
# (原图240的像素乘1.2就超), 硬裁会让一片区域塌成同一个255 -> 死白连片。
# 膝点必须定高、只当安全网: clamp收到+0.30后真正溢出的只剩约0.02%, 膝点定低
# 会把本来完好的亮部(235~255)一并压进很窄范围, 经uint8量化后互相碰撞,
# 次序反而比硬裁更差。实测(统一在 target>245 评估):
# 255(不限幅): 死白0.021%, 死白最大连通102px, 亮部次序0.9564
# 252 : 死白0%, 连通0, 次序0.9320 <- 采用
# 235 : 死白0%, 连通0, 次序0.8950
ratio_highlight_knee: 252.0
ratio_mask_thresh: 0.06 # 由调制强度求掩膜的阈值(对数域, 0.06 ≈ 明暗变化 6%)
# 明暗调制强度倍率(flat 模式下取代 defect_gain; defect_gain 是像素差值倍率,
# 乘性明暗场无此概念, 设了会告警并忽略)。severity_adaptive_gain 仍生效, 会
# 按 1+0.12*(severity-3) 乘到这个值上。>1 加强褶皱但会同步放大模型的瑕疵。
shading_strength: 1.0
# ---- 真实明暗场直接传递(relief transfer) ----
# 编辑模型无法把参考的几何映射到目标坐标系: 实测参考主走向与生成主走向的角度差
# 均值 68 度(纯随机期望 45 度), 走向吻合率仅 14%; 补上最强的"1:1复刻+禁止等距
# 平行"指令后仍是 14%(精确的零改善)。而模型自身高度自洽(同一参考在不同干净图上
# 产出走向的圆集中度 0.96~1.00), 说明它稳定地画自己的先验, 与参考无关。
# 因此几何不再交给模型发明, 改为直接搬运真实缺陷的明暗调制场:
# 参考裁剪 -> 对数域带通(去源瓶光照/去印刷笔画) -> 等比对齐 -> 乘性回贴。
# 几何保真度是构造性的(实测 ent/dom 与参考逐位相等), 且确定性、零 API 成本。
relief_sigma_small: 10.0 # 高频截断; 直接传递时印刷笔画残留会变成真实阴影, 故比
# 模型引导用的 6.0 更大, 需按文字残留/棱线保留权衡
relief_sigma_large: 40.0 # 低频截断; 压掉源瓶整体光照
# 幅度倍率(不是绝对目标值)。1.0 = 忠实还原真实幅度, 从而保留不同参考之间真实
# 存在的深浅差异(实测真实 p99 从 0.76 到 1.69, 差 2.2 倍)。
# 注意不要用"渲染好的浮雕图 + 单一幅度常数"的做法: 浮雕图内部按 p99 归一化过,
# 会把这 2.2 倍差异压成 0.5%, severity 信息永久丢失。
relief_amplitude: 1.0
# relief 路径单独的软饱和边界, 不复用模型路径的 [-1.1, +0.4]:
# 那个上界是为压制模型镜面过曝而收紧的, 而真实缺陷的亮侧幅度真实存在
# (实测 p99 均值 1.105, 最大 1.95), 用 0.4 会截掉大半。
relief_clamp_lo: -1.2
relief_clamp_hi: 1.2
# 几何位移强度(像素)。flat-edit 的乘性回贴只改亮度、像素位置一动不动, 而真实
# 褶皱一定会把印刷内容推弯; 缺了这一步即便明暗几何与参考一致, 看上去也只是
# "贴了一层阴影"(QC 反复反馈"印刷线条不随形变扭曲、仅叠加明暗纹理")。
# 实现: 把去噪后的明暗场当高度场代理, 位移方向与幅度都取自 ∇s ->
# 棱线顶/谷底不动、折痕陡侧位移最大(物理上正确)。幅度按掩膜内 |∇s| 的
# 95 分位归一化, 所以这个值的含义就是"最大位移像素数", 不随裁块尺寸、
# 褶皱尺度或 clamp 边界漂移。
# 0=关闭。取负值可翻转弯曲方向(朝亮侧还是暗侧)。
# 4.0 是首批的保守取值, 符号与幅度都需要看 debug 里的 3c/3d 位移场图确认。
displace_strength: 4.0
# 位移前的明暗场去噪 sigma(像素)。模型在平坦底图上会生成纹理噪点(实测高频
# 能量比平坦底图高 5~17 倍), 混入明暗场会污染位移方向与幅度;
# 2.0 能抹掉噪点、保留褶皱棱线。
displace_sigma: 2.0
qc:
enable: true
# 面向 YOLO 训练数据标定的阈值(不是科研级1:1保真标准)。
# 门槛集中在人工审核发现的两个真实问题: 缺陷高光突兀、缺陷区与瓶身接缝断层。
# 注意: 缺陷面积大/变形夸张不扣分, 真实样本中本就存在。
min_realism_score: 5.5 # 加权综合分阈值(1~10)
qc_image_long_side: 1024 # 送质检的裁块长边(裁块级别, 不再压缩整图)
min_scores:
type_match: 5 # 必须是薄膜形变, 不能是脏斑点/污渍/异物
severity_match: 4 # 别太淡
highlight_natural: 5 # 高光不能突兀(主要门槛)
seam_continuity: 5 # 缺陷区与瓶身要连续(主要门槛)
# shape_fidelity 不设门槛: 对 YOLO 训练无意义, 仅记录进标注供事后筛选
# 综合分权重: 偏向高光与接缝
weights:
type_match: 0.20
shape_fidelity: 0.05
severity_match: 0.15
highlight_natural: 0.25
seam_continuity: 0.25
blend_quality: 0.10
# 兜底: 关闭时不合格样本一律进 outputs/rejected, 不混入训练集
keep_best_effort: false
best_effort_margin: 1.0
max_bg_change_ratio: 0.02 # 掩膜外允许变化的像素比例上限(硬约束校验)
bg_change_pixel_thresh: 12 # 判定"像素变化"的灰度差阈值
# 下面两项控制"是否把 VLM 的主观布尔判断当作驳回闸门"。默认 false:
# gate_only_local: "是否只有局部变化"已由 bg_change 逐像素严格验证, 无需再问
# VLM。开启会导致大面积变形被误杀(实测 realism 7.5 的样本仅因此被驳回)。
# gate_on_bottle: 缺陷落在桌布上不影响使用(人工标注时不打框), 且 VLM 难以
# 分辨桌布与瓶身背光面(灰度高度重叠)。
# 注意: 关闭这两项后, "缺陷画到桌布上"不再被自动拦截, 依赖人工标注环节把关。
gate_only_local: false
gate_on_bottle: false