Linux下基于相似度阈值查找重复照片并显示相似度占比
基于相似度查找重复照片并输出相似度百分比
用ImageMagick计算两张图片的相似度百分比
ImageMagick的compare命令可通过度量值转换得到相似度百分比。以RMSE(均方根误差)为例,RMSE取值范围为0到65535(对应8位图像的像素值范围),相似度计算公式为:相似度 = (1 - RMSE值/65535) × 100%。
执行以下命令即可获取两张图片的相似度:
compare -metric RMSE img1.jpg img2.jpg null: 2>&1 | awk '{printf "%.2f%%", (1 - $1/65535)*100}'
null:避免生成差异对比图,仅输出度量数据2>&1将compare输出到stderr的度量值重定向到stdout,方便后续处理
批量处理2TB照片的脚本方案
结合findimagedupes快速筛选候选重复组,再用ImageMagick计算每对的相似度,过滤符合阈值的结果:
#!/bin/bash # 设定相似度阈值(例如90%,可根据需求调整) THRESHOLD=90 # 目标照片目录 PHOTO_DIR="/path/to/your/photos" # 用findimagedupes获取候选重复组,每组一行包含多张相似图片 findimagedupes "$PHOTO_DIR" | while read -r image_group; do # 将组内图片转为数组 images=($image_group) # 生成组内所有两两图片组合 for ((i=0; i<${#images[@]}-1; i++)); do img_a="${images[$i]}" for ((j=i+1; j<${#images[@]}; j++)); do img_b="${images[$j]}" # 计算相似度百分比(缩小图片尺寸提升计算速度) similarity=$(compare -metric RMSE \ <(convert "$img_a" -resize 256x256!) \ <(convert "$img_b" -resize 256x256!) \ null: 2>&1 | awk '{printf "%.2f", (1 - $1/65535)*100}') # 过滤超过阈值的结果并输出 if (( $(echo "$similarity >= $THRESHOLD" | bc -l) )); then echo "相似度: ${similarity}% | $img_a ↔ $img_b" fi done done done
脚本优化说明
- 缩小图片尺寸:通过
convert -resize 256x256!将图片统一缩小到256x256像素,大幅减少计算量,同时不影响相似度判断的准确性 - 候选组预筛选:
findimagedupes基于图片哈希快速分组,避免全量两两对比,适合处理TB级别的照片库 - 浮点比较:用
bc -l处理相似度的浮点阈值判断,解决shell不支持浮点运算的问题
注意事项
- 确保已安装
findimagedupes、ImageMagick和bc工具 - 首次运行建议先在小批量照片上测试阈值和脚本逻辑
- 针对超大照片库,可增加按文件大小预分组的步骤,进一步减少计算量
内容的提问来源于stack exchange,提问作者IMTheNachoMan
相关产品推荐
相关产品推荐

