批量删除不同文件名重复图片脚本异常:仅保留1张文件求助
重复图片删除脚本异常原因分析
尝试遍历文件夹删除文件名不同但内容重复的图片,5000张图片中本该保留十多张唯一图,运行脚本后却只剩1张未被删除。
问题脚本
import os import cv2 directory = r'C:\Users\Grid\scratch' for filename in os.listdir(directory): a=directory+'\\'+filename n=(cv2.imread(a)) q=0 for filename in os.listdir(directory): b=directory+'\\'+filename m=(cv2.imread(b)) comparison = n == m equal_arrays = comparison.all() if equal_arrays==True and q==1: os.remove(b) q=1
异常原因分析
- 循环变量冲突:外层和内层循环共用
filename变量,内层循环会覆盖外层的filename值,导致外层循环后续迭代的文件路径混乱,触发非预期的文件读取和删除操作。 - 边遍历边删除的致命问题:
os.listdir在循环启动时就生成了文件列表,后续删除文件后,外层循环仍会尝试访问列表中已被删除的文件。此时cv2.imread读取已删除文件会返回None,当外层循环处理到这类无效文件时,内层遍历中若遇到其他已删除的文件(同样返回None),None == None会被判定为内容相同,进而触发删除,最终把剩余的有效文件也误删。 - 图片比较逻辑缺失校验:
- 未检查
cv2.imread的返回值,一旦图片读取失败(文件已删、格式不兼容、损坏),就会用None参与比较,导致错误的重复判定。 - 未先校验图片尺寸,若两张图尺寸不同,直接执行
n == m会抛出ValueError,中断脚本或导致后续逻辑混乱。
- 未检查
- 重复删除逻辑漏洞:外层每处理一张图,就会删除所有与它相同的其他图。当外层循环到后期唯一的图片时,若此时存在已删除文件产生的
None值,会被误判为重复,进而被删除。
修正方向
- 分离循环变量:外层用
file_path1,内层用file_path2,避免变量覆盖。 - 先批量收集图片信息:先读取所有有效图片的路径、尺寸和哈希值(如dHash),再通过哈希值判定重复,最后批量删除重复文件,不要边遍历边删。
- 增加读取校验:每次用
cv2.imread读取后,先判断返回值是否为None,跳过无效文件。 - 先校验尺寸:两张图尺寸不同时直接判定为不重复,避免数组比较报错。
内容的提问来源于stack exchange,提问作者Kuba
相关产品推荐
相关产品推荐

