检查某个文件夹中是否有任何图像重复的最高效(比我的好)的方法



我不确定我做得是否正确。我已经创建了多个文件的多个"副本",所有这些文件都应该在某种程度上有所不同(图像增强(。现在,因为可能对我不利,我想检查是否有任何创建的文件与其他创建的文件相等。要么我运气不好,要么我把代码搞砸了。因为有很多文件,我无法手动检查它们。也许有一种比循环2更快的方法。

我有以下代码。

import sys
import os
import glob
import numpy
import time
import datetime

start_time = time.time()
print(datetime.datetime.now().time())
img_dir = sys.argv[1] 
data_path = os.path.join(img_dir,'*g')
files = glob.glob(data_path)
something_went_wrong = False
for f1 in files:
for f2 in files:
if f1 != f2:
if open(f1,"rb").read() == open(f2,"rb").read():
something_went_wrong = True
print(f1)
print(f2)
print("---")
print(something_went_wrong)
print("--- %s seconds ---" % (time.time() - start_time))

只需按照建议使用哈希即可。如果一个像素发生变化,散列也会发生变化。

import hashlib
def hash_file(filename):
# use sha1 or sha256 or other hashing algorithm
h = hashlib.sha1()
# open file and read it in chunked
with open(filename,'rb') as file:
chunk = 0
while chunk != b'':
chunk = file.read(1024)
h.update(chunk)
# return string
return h.hexdigest()

https://www.pythoncentral.io/hashing-files-with-python/

它不受文件名或元数据的影响!将结果放入数据帧中,而不是很容易获得重复的

此方法使用哈希函数与文件列表的字典相结合,其中包含每个元素出现的次数,这对另一种方法略有扩展。

假设你说的是不同文件夹中的重复文件名,这意味着我会以稍微不同的方式将初始file_list放在一起,但这是我如何解决这个问题的基础(取决于glob.glob返回的内容(

import hashlib

file_list = []
def test_hash(filename_to_test1, filename_to_test2):
"""
"""
filename_seq = filename_to_test1, filename_to_test2
output = []
for fname in filename_seq:
with open(fname, "rb") as opened_file:
file_data = opened_file.readlines()
file_data_as_string = b"".join(file_data)
_hash = hashlib.sha256()
_hash.update(file_data_as_string)
output.append(_hash.hexdigest())
if output[0] == output[1]:
print "File match"
else:
print "Mismatch between file and reference value"
possible_duplicates = {}
for idx, fname in enumerate(file_list):
if fname in possible_duplicates:
possible_duplicates[fname].append(idx)
elif fname not in possible_duplicates:
possible_duplicates[fname] = [idx]
for fname in possible_duplicates:
if len(possible_duplicates[fname]) > 1:
for idx, list_item in enumerate(possible_duplicates[fname]):
test_hash(possible_duplicates[fname][0], possible_duplicates[fname][idx])

如注释所述,按大小分组可节省时间:

import os
from collections import defaultdict
def fin_dup(dir):
files=defaultdict(set)
res=[]
for fn in os.listdir(dir):
if os.path.isfile(fn):
files[os.stat(fn).st_size].add(fn) # groups files by size
for size,s in sorted(files.items(),key=lambda x : x[0],reverse=True): #big first 
while s:
fn0=s.pop()
s0={fn0}
for fn in s:
if open(fn0,'rb').read() == open(fn,'rb').read(): s0.add(fn)
s -= s0
if len(s0) > 1: res.append(s0)
return res

此功能只需不到1秒的时间即可扫描包含1000个文件的目录,并找到79个重复文件。仅散列文件就需要10秒。

最新更新