检查目录中的文件是否相同

时间:2017-07-12 15:22:56

标签: python image hash

我在jpeg / png等中有5000多张图像的文件夹。如何查看是否有任何图像相同。图像是通过网页抓取收集的,并且已经按顺序重命名,因此我无法比较文件名。

我目前正在检查哈希值是否相同,但这是一个非常漫长的过程。我目前正在使用:

def sameIm(file_name1,file_name2):
    hash = imagehash.average_hash(Image.open(path + file_name1))
    otherhash = imagehash.average_hash(Image.open(path + file_name2))

    return (hash == otherhash)

然后是嵌套循环。将1张图像与5000张其他图像进行比较需要大约5分钟,因此每个图像的比较需要数天才能计算出来。

在python中有更快的方法吗?我在考虑并行处理,但这还需要很长时间吗?

还是有另一种比较文件的方法更快吗?

由于

4 个答案:

答案 0 :(得分:3)

确实有一种更快的方法:

import collections
import glob
import os


def dupDetector(dirpath, ext):
    hashes = collections.defaultdict(list)
    for fpath in glob.glob(os.path.join(dirpapth, "*.{}".format(ext)):
        h = imagehash.average_hash(Image.open(fpath))
        hashes[h].append(fpath)

    for h,fpaths in hashes.items():
        if len(fpaths) == 1:
            print(fpaths[0], "is one of a kind")
            continue
        print("The following files are duplicates of each other (with the hash {}): \n\t{}".format(h, '\n\t'.join(fpaths)))

使用带有文件哈希作为键的字典可以进行O(1)查找,这意味着您不需要进行成对比较。因此,您可以从二次运行时到线性运行时(yay!)

答案 1 :(得分:3)

为什么不只计算一次哈希?

hashes = [imagehash.average_hash(Image.open(path + fn)) for fn in file_names]
def compare_hashes(hash1, hash2):
    return hash1 == hash2

答案 2 :(得分:2)

一个解决方案是继续使用哈希,但将其存储在元组列表中(或者说,我不知道哪个更有效),其中第一个元素是图像的名称,第二个元素是哈希值。它应该花费相同的5分钟。

如果您有5000张图片, 您将列表的第一个元素的值与4999个其他元素的值进行比较

然后是第二个到4998个其他人(因为你已经检查了第一个)

然后第三个......

这个“只是”让你进行n²/ 2比较(其中n是图像的数量)

答案 3 :(得分:2)

只需使用地图结构计算每个图像的哈希值,然后将哈希值存储为键,将图像名称存储为值。 因此,您将拥有唯一图像名称数组

def get_hash(filename):
    return imagehash.average_hash(Image.open(path + filename))

def get_unique_images(filenames):
    hashes = {}
    for filename in filenames:
        image_hash = get_hash(filename)
        hashes[image_hash] = filename
    return hashes.values()