同一套产品图,改了文件名、压到 80% 画质、再转成 WebP,上传之后还是被判素材雷同------问题到底出在哪一层?
我们在一次多店铺上新里遇到了这个情况:三个店铺用了同一家工厂给的主图,运营各自做了"处理"------A 店重命名,B 店压了画质,C 店裁掉水印条。结果三张图在平台的素材比对里依然被归为同源。排查后发现,三个人做的处理全部落在同一个层上,而平台看的层不止一个。
本文给出完整的处理流程:先把"平台能看到什么"拆成三层,再给一条可跑的批量去重脚本,最后讲清哪些动作有用。
一、先把"雷同"拆成三层
亚马逊多店铺的图在网络上的身份不止文件名。素材比对通常覆盖三个层次,处理时三层都要动,只动一层等于没做。
第一层是元数据层。 图片文件里除了像素,还带着拍摄设备、拍摄时间、GPS 坐标、处理软件,统称 Metadata,相机相关的部分是 EXIF,版权与描述部分是 IPTC。同一台相机同一时段拍的一批图,这部分几乎完全一致。
第二层是编码层。 同一张图用同一套参数重新编码两次,字节序列高度接近,简单哈希只差一两位甚至完全相同。改文件名不影响这一层;压画质影响有限。
第三层是像素层。 裁剪、旋转、改亮度能改变编码层,但改变不了"这张图看起来还是同一张图"。平台侧通常用感知哈希比对这一层:把图缩到很小的灰度尺寸,按相邻像素明暗生成几十位指纹,两张图做汉明距离比较,距离越小越相似。常见实现有 aHash、dHash、pHash。
这里有个反直觉的点:清洗 Metadata 最简单,但它防的是最容易被绕过的那一层。 只清 EXIF 不动画面内容,感知哈希一个字节都不会变。
顺带说清分工:设备与网络维度由指纹浏览器与代理承担,防关联浏览器解决的是账号之间的关联判定,团队权限与操作留痕一般放在跨境电商超级浏览器的协作模块里,素材维度是这之外的又一层。几层各自独立,任何一层缺位,其他层的投入都会打折。
二、设计:一条批量去重的流水线
理解三层之后,流程就清楚了:扫描图库 → 生成三层指纹 → 计算两两相似度 → 分组 → 施加处理动作 → 留档。
关键设计决策有三个。
决策一:先分组,再处理。 不要拿到图就批量洗一遍。先算相似度矩阵,把确实撞车的挑出来,只对这部分做深度处理,剩下的保持原样。
决策二:判定用组合条件,不用单一阈值。 单一哈希阈值误判率高------两张完全不同的白底图,dHash 距离也可能很近。做法是:编码哈希相同判同源;感知哈希距离小于等于 8 判高度相似;距离 9 到 16 且拍摄时间差小于 24 小时,判可疑转人工复核。
决策三:动作按强度分级,参数按店铺分散。 同一批图不要给所有店铺同一个处理结果,那样等于把"这几家店是同一批素材"又写了一遍。每个店铺用不同的随机种子、压缩参数与裁切偏移。
三、实现:可跑的批量去重脚本
环境:Python 3.10,依赖 Pillow 10 与 imagehash。
下面是完整脚本,做三件事:扫描目录、生成指纹、输出相似分组报告。
上新前跑完得到一份分组报告,接着按分组施加处理动作。下面是处理侧的核心函数------重编码加 Metadata 剥离:
四、哪些动作有用,哪些只是自我安慰
亚马逊多店铺常见的图片处理动作,按实际效果从强到弱排个序:
|----------------------|------------|------------------|
| 处理动作 | 影响层 | 实际效果 |
| 重拍 / 重新布景 / 换拍摄角度 | 像素层 | 效果最彻底,感知哈希完全改变 |
| 结构重排(换背景、换构图、加道具) | 像素层 | 强 |
| 局部替换(换模特、换配件) | 像素层 | 中强 |
| 裁剪 + 旋转 + 亮度微调 + 重编码 | 编码层 + 弱像素层 | 中,能过简单哈希,感知哈希仍接近 |
| 清洗 Metadata | 元数据层 | 弱,必须配合上面的动作 |
| 仅改文件名 / 仅压画质 | 无实质影响 | 基本无效 |
表里最该记住的是最后一行:改文件名和压画质几乎不产生任何效果,而这两件事恰恰是运营最常做的"处理"。
还有两个容易漏的点:一是文案层,五点描述与标题的模板化雷同和图片是并列信号;二是节奏层,亚马逊三个店铺同一天用同一批新图上新,同步本身也是信号。
五、踩过的四个坑
坑一:只清 Metadata 就以为完事了。 这一层最容易清洗,也最不重要。清完再跑一遍 dHash 比对,距离仍然是 0。
坑二:用同一个脚本把所有图一次性处理完。 结果所有店铺的图在同一天更新,字节层面不同了,行为上却高度同步。后来改成按店铺分配随机种子、错开上架。
坑三:阈值照抄默认值。 dHash 距离 8 这个阈值来自公开经验值,在白底图为主的 3C 类目上误判偏高------纯白底的两个不同产品缩到 9×8 之后几乎一样。这类类目应把阈值收紧到 4 到 5,并叠加 Metadata 条件。
坑四:处理完没有留档。 亚马逊下次上新又从原始图库拿图,问题原样重现。后来把报告按店铺归档,上新前先跑一遍比对。
另外提醒一句:环境层的事不在本文范围,但排期上要一起考虑。指纹浏览器负责设备指纹隔离,代理负责出口,两者和素材处理是并列动作,别把素材层当成唯一变量。
六、常见报错与排查
报错:ModuleNotFoundError: No module named 'imagehash' 原因:依赖没装全。解决方案:确认用的是项目虚拟环境,pip list 里应同时有 Pillow、imagehash、numpy 三项。
报错:处理中文路径的图时抛编码异常或找不到文件 原因:Windows 下默认编码与路径处理不一致。解决方案:全程用 pathlib 的 Path 对象,读写文本文件时显式指定 encoding='utf-8'。
报错:HEIC 或 AVIF 格式的图读不出来 原因:Pillow 默认不带这两种格式的解码器。解决方案:安装 pillow-heif 并在脚本开头注册解码器,或在上游统一转换成 JPEG 再入库。
写在最后
素材去重这件事的结论很朴素:平台比对的不是文件名,是三层指纹。处理动作必须至少触及像素层,只在文件属性上做文章没有意义。值得固化的只有两步:上新前跑一遍相似度扫描,处理时按店铺分散参数与上架节奏。
多店铺运营里,环境隔离、网络出口、团队权限、素材差异是四条并列的工作线。前三条分别由指纹浏览器、代理与跨境电商超级浏览器承接,第四条长期被忽略,而它恰恰是运营侧唯一完全可控的一条。防关联浏览器能覆盖的是设备与网络两层,素材层只能自己补。
本文代码基于 Python 3.10 + Pillow 10.3 + imagehash 4.3 验证(2026 年 9 月)。感知哈希阈值为经验值,不同类目需自行标定。文中涉及的相似度判定为工程实践归纳,不代表任何平台的实际算法。