Files
cmbot/docs/12-stamp-template-matching.md
T

229 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 合并图印花内容匹配设计
## 1. 文档定位
本文档记录一个独立小工具需求:给定一张衣服图片(通常是已经合成好的效果图)和一个印花目录,通过图像内容匹配找出这张衣服图中最可能使用的是哪一张印花。
该需求不同于 `match_stamp.py` 当前的文件名后缀匹配。文件名匹配依赖 `1_TY037.png -> TY037.png` 这种命名规则;本文档讨论的是**即使不知道文件名编码,也从图片内容上匹配印花**。
第一阶段先做独立脚本验证,不接入 GUI,不改现有添加印花 / AI 穿搭流程。
## 2. 输入与输出
输入:
- `MERGED_IMAGE`:一张衣服图片,可理解为合并后的图片,例如 `output\20260623_094529\TY037\1_TY037.png`。
- `STAMP_DIR`:印花图片目录,例如 `D:\chengma\印花和底图\已处理印花\卡通71(66大码200斤 KEKE已上)\横1`。
输出:
- 不保存 CSV。
- 直接 `print` 匹配结果。
- 默认打印最佳匹配和 Top N 候选,例如:
```text
Best match:
score: 0.9231
stamp: D:\...\TY037.png
location: x=412, y=286
scale_x: 0.38
scale_y: 0.30
aspect_y: 0.80
size: 128x96
Top 5:
1. 0.9231 TY037.png
2. 0.6112 TY049.png
...
```
## 3. 方案比较
### 3.1 纯文件名匹配
按 `1_TY037.png` 提取 `TY037`,再找 `TY037.png`。
优点:
- 最快、最稳定。
- 不依赖图像算法。
缺点:
- 只能在命名规则可靠时使用。
- 不满足当前“根据图片内容找印花”的需求。
### 3.2 OpenCV `matchTemplate`
把每张印花当模板,在衣服图中滑动匹配,取最高相关分。
优点:
- 实现简单。
- 能输出匹配位置、分数、缩放尺寸。
- 对数字合成图比较有效。
缺点:
- 对缩放敏感,需要多尺度搜索。
- 对宽高不等比例变形敏感,例如印花原图 `1000x1000` 合成时被改成 `1000x800`,只做等比例缩放时分数会下降。
- 对旋转、透视、明显变色不够稳。
- 背景透明 PNG 需要使用 alpha mask,否则透明区域会干扰分数。
### 3.3 边缘辅助匹配
把合并图和印花都转成边缘图,再做匹配,用来辅助模板匹配分数。
优点:
- 对颜色变化更稳。
- 可减少纯颜色差异造成的误判。
缺点:
- 衣服纹理、褶皱和背景也会产生边缘,可能带来误匹配。
- 不能单独作为唯一判断,更适合作为辅助分数。
### 3.4 ORB / SIFT 特征点匹配
提取局部特征点,再做特征匹配。
优点:
- 理论上更能抗缩放和旋转。
缺点:
- 很多印花是卡通、大色块、线条少,特征点可能不足。
- 结果不如模板匹配直观,调参成本更高。
### 3.5 深度特征 / CLIP
用图像 embedding 比较相似度。
优点:
- 对变形、颜色变化和局部差异更鲁棒。
缺点:
- 依赖模型,部署重。
- 不适合当前“独立脚本快速验证”阶段。
## 4. 推荐方案
第一版采用:
```text
多尺度模板匹配 + 有限宽高比变形 + alpha mask + 边缘辅助分数
```
处理流程:
1. 读取 `MERGED_IMAGE`。
2. 遍历 `STAMP_DIR` 下所有支持图片。
3. 对每张印花保留 alpha 通道;如果没有 alpha,则按整张图参与匹配。
4. 对印花做多尺度缩放,例如 `0.10 ~ 2.00`。
5. 在每个基础缩放比例上,再尝试有限的宽高比变形,例如:
```text
aspect_y: 0.60 / 0.70 / 0.80 / 0.90 / 1.00 / 1.10 / 1.20
scale_x = scale
scale_y = scale * aspect_y
```
示例:原印花 `1000x1000`,合成后变为 `1000x800`,可由 `scale_x=1.00`、`scale_y=0.80`、`aspect_y=0.80` 覆盖。
6. 每个 `scale_x / scale_y` 组合执行一次 `cv2.matchTemplate`:
- RGB 彩色分数:主分数,比灰度分数更能区分颜色相近但内容不同的印花。
- alpha mask:忽略透明区域。
- 边缘图分数:辅助分数。
7. 计算综合分:
```text
综合分 = 0.75 * 模板匹配分 + 0.25 * 边缘匹配分
```
8. 保存每张印花的最佳结果:分数、位置、`scale_x`、`scale_y`、`aspect_y`、匹配尺寸。
9. 按综合分排序并 `print` Top N。
不建议直接暴力搜索完整的 `scale_x × scale_y` 网格,因为运行量会明显放大。优先采用“基础 scale + 少量 aspect_y 候选”的方式,覆盖常见压扁 / 拉伸场景,同时控制耗时。
先不做旋转搜索。若实际发现印花经常旋转,再增加角度搜索,例如 `-30° ~ 30°`,但运行会明显变慢。
### 4.1 宽高不等比例变形说明
合并衣服和印花时,如果用户或模板把印花宽高分别设置为不同数值,原始印花可能发生非等比例变形。例如:
```text
原始印花:1000x1000
合成尺寸:1000x800
```
这种情况下,只搜索单个 `scale` 的版本不够稳。因为等比例搜索只能生成:
```text
800x800
1000x1000
1200x1200
```
无法直接生成 `1000x800`。因此后续代码应支持独立的 `scale_x` 和 `scale_y`,但搜索范围应保持克制:
- 继续保留基础 `scale`,控制整体尺寸。
- 增加少量 `aspect_y` 候选,控制高度相对宽度的压缩 / 拉伸。
- 默认不做所有 `scale_x × scale_y` 组合,避免每张印花匹配次数过多。
输出也应从单一:
```text
scale: 0.38
```
改为:
```text
scale_x: 0.38
scale_y: 0.30
aspect_y: 0.80
```
这样可以直接看出匹配结果是否依赖宽高不等比例变形。
## 5. 第三方库
最小依赖:
- `opencv-python`:模板匹配、灰度转换、缩放、边缘检测。
- `numpy`:OpenCV 图像数组处理。
建议依赖:
- `Pillow`:用于读取 Windows 中文路径图片,再转成 `numpy` 数组,避免 OpenCV 在中文路径上不稳定。
当前开发机已确认可用:
```text
cv2: 可用
numpy: 可用
PIL: 可用
```
如果后续需要把脚本交给其它机器使用,需要补充安装说明,或把 `opencv-python` / `numpy` 写入独立工具依赖说明。是否纳入项目 `requirements.txt` 需另行决定;当前阶段先不改项目依赖。
## 6. 独立脚本约束
- 脚本不引用 cmbot 现有代码。
- 脚本不修改、移动、删除原始图片或合并图片。
- 第一版只 `print` 结果,不写 CSV、不写 Excel。
- 支持 Windows 中文路径。
- 默认只处理一张 `MERGED_IMAGE`;批量目录匹配可作为后续扩展。
## 7. 验收要点
- 给定 `1_TY037.png` 和包含 `TY037.png` 的印花目录,Top 1 应优先命中 `TY037.png`。
- 能打印 Top N 候选、综合分、模板分、边缘分、匹配坐标、`scale_x`、`scale_y`、`aspect_y`。
- 对透明 PNG 能忽略透明区域,不让透明背景参与匹配。
- 对 `1000x1000 -> 1000x800` 这类非等比例变形,能通过 `aspect_y=0.80` 附近候选提高匹配稳定性。
- 找不到可靠匹配时仍打印 Top N,并提示分数偏低,便于人工判断。