如何识别存在分辨率差异的重复图片?
我最近也碰到了一模一样的头疼问题:手里一堆重复图片,要么是不同分辨率的版本,要么命名乱七八糟,不管怎么排序都散得七零八落。一开始试了gm compare,各种指标试了个遍,结果完全摸不准哪个能用来判断是不是同一张图,更别说该设多少阈值才算匹配了。
后来我换了个思路,发现用gm identify提取图片的颜色通道统计特征反而更靠谱——毕竟同一张图哪怕分辨率缩放了,整体的颜色分布、亮度这些统计值不会有太大变化,而不同的图片差异会很明显。
先说说为啥gm compare不太好用
直接用gm compare对比不同分辨率的图片时,很多基于像素的指标(比如MAE、MSE、PAE)会因为像素尺寸不匹配出现偏差,就像你给出的例子里,PAE的总差值直接到了最大值65535,但这其实是分辨率差异导致的像素对齐问题,不是图片内容真的完全不同。所以这类像素级对比的指标对分辨率不同的重复图不太友好。
用通道统计特征判断的思路
我用gm identify -verbose导出了图片的通道统计数据,重点看每个颜色通道(红、绿、蓝)的均值(Mean)和标准差(Std Dev):
- 同主题但不同分辨率的图片,这些数值会非常接近
- 完全不同的图片,数值差异会很显著
比如你给出的例子:
示例1:Image A、Image A@2x、Image B
| 通道 | Image A均值 | Image A@2x均值 | Image B均值 |
|---|---|---|---|
| Red | 0.6894 | 0.6902 | 0.4619 |
| Green | 0.6336 | 0.6371 | 0.3885 |
| Blue | 0.6023 | 0.6010 | 0.4098 |
Image A和它的2x分辨率版本,三个通道的均值差异都在0.01以内,而和Image B的差异直接到了0.2以上,一眼就能区分开。
示例2:BOSS系列图片
BOSS-1(原图)和BOSS-1-50(半尺寸)的通道统计值:
- Red均值:0.3528 vs 0.3504,差0.0024
- Green均值:0.4257 vs 0.4230,差0.0027
- Blue均值:0.4961 vs 0.4932,差0.0029
而BOSS-1和BOSS-8的均值差:
- Red均值差:0.3528 vs 0.3589,差0.0061
- Green均值差:0.4257 vs 0.4321,差0.0064
- Blue均值差:0.4961 vs 0.5214,差0.0253
标准差的差异也是类似的规律,同主题缩放的图片标准差几乎没变化,不同主题的差异会大很多。
具体怎么操作?
- 批量导出统计数据:用
gm identify -verbose遍历所有图片,把每个图片的Red/Green/Blue通道的Mean和Std Dev提取出来,存成表格或者JSON格式(写个小脚本批量处理会更高效)。 - 计算特征相似度:对每一对图片,计算它们对应通道均值、标准差的绝对差值,比如:
- 计算Red均值差、Red标准差差、Green均值差、Green标准差差、Blue均值差、Blue标准差差
- 把这些差值加起来,或者取最大的差值,作为两张图的“差异值”
- 设定阈值:用你手里已知的同主题不同分辨率的图片对,算出它们的差异值范围,比如我自己测试的数据集里,同主题缩放的图片所有通道的均值差都小于0.01,标准差差都小于0.02,那把这个设为阈值——只要两张图的所有通道差值都在这个范围内,就判定为重复。
- 人工校验:因为是统计特征,难免会有极小概率的误判,所以筛选出候选重复对后,最好快速扫一眼确认一下。
小提示
如果觉得手动计算麻烦,可以用Python写个简单的脚本,调用subprocess执行gm identify命令,提取数据后自动计算差异值,批量筛选重复图片,效率会高很多。
备注:内容来源于stack exchange,提问作者yarns

