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

6.8 KiB
Raw Blame History

合并图印花内容匹配设计

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 候选,例如:
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. 推荐方案

第一版采用:

多尺度模板匹配 + 有限宽高比变形 + alpha mask + 边缘辅助分数

处理流程:

  1. 读取 MERGED_IMAGE。
  2. 遍历 STAMP_DIR 下所有支持图片。
  3. 对每张印花保留 alpha 通道;如果没有 alpha,则按整张图参与匹配。
  4. 对印花做多尺度缩放,例如 0.10 ~ 2.00。
  5. 在每个基础缩放比例上,再尝试有限的宽高比变形,例如:
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 覆盖。

  1. 每个 scale_x / scale_y 组合执行一次 cv2.matchTemplate:
    • RGB 彩色分数:主分数,比灰度分数更能区分颜色相近但内容不同的印花。
    • alpha mask:忽略透明区域。
    • 边缘图分数:辅助分数。
  2. 计算综合分:
综合分 = 0.75 * 模板匹配分 + 0.25 * 边缘匹配分
  1. 保存每张印花的最佳结果:分数、位置、scale_x、scale_y、aspect_y、匹配尺寸。
  2. 按综合分排序并 print Top N。

不建议直接暴力搜索完整的 scale_x × scale_y 网格,因为运行量会明显放大。优先采用“基础 scale + 少量 aspect_y 候选”的方式,覆盖常见压扁 / 拉伸场景,同时控制耗时。

先不做旋转搜索。若实际发现印花经常旋转,再增加角度搜索,例如 -30° ~ 30°,但运行会明显变慢。

4.1 宽高不等比例变形说明

合并衣服和印花时,如果用户或模板把印花宽高分别设置为不同数值,原始印花可能发生非等比例变形。例如:

原始印花:1000x1000
合成尺寸:1000x800

这种情况下,只搜索单个 scale 的版本不够稳。因为等比例搜索只能生成:

800x800
1000x1000
1200x1200

无法直接生成 1000x800。因此后续代码应支持独立的 scale_x 和 scale_y,但搜索范围应保持克制:

  • 继续保留基础 scale,控制整体尺寸。
  • 增加少量 aspect_y 候选,控制高度相对宽度的压缩 / 拉伸。
  • 默认不做所有 scale_x × scale_y 组合,避免每张印花匹配次数过多。

输出也应从单一:

scale: 0.38

改为:

scale_x: 0.38
scale_y: 0.30
aspect_y: 0.80

这样可以直接看出匹配结果是否依赖宽高不等比例变形。

5. 第三方库

最小依赖:

  • opencv-python:模板匹配、灰度转换、缩放、边缘检测。
  • numpy:OpenCV 图像数组处理。

建议依赖:

  • Pillow:用于读取 Windows 中文路径图片,再转成 numpy 数组,避免 OpenCV 在中文路径上不稳定。

当前开发机已确认可用:

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,并提示分数偏低,便于人工判断。