如何删除图片数据中的重复数据

我们在工作中经常这种情况,leader给你一堆数据,让你用这些没有清洗过的数据完成项目。痛苦的是,这批数据居然存在很多重复的样本。那如何删除这些冗余数据呢?imagehash库非常好用。

github地址:https://github.com/chinalu/imagedups

imagehash是通过度量两张图片的相似度,并根据相似度判断是否是相似数据,从而帮助我们查找删除冗余数据。Hash算法准确的说有三种,分别为平均哈希算法(aHash)、感知哈希算法你(pHash)和差异哈哈希算法(dHash)。github中使用的平均哈希,所以我们这里仅介绍aHash。

平均哈希算法(aHah)

1.算法步骤
平均哈希算法是三种Hash算法中最简单的一种,它通过下面几个步骤来获得图片的Hash值,这几个步骤分别是(1) 缩放图片;(2)转灰度图; (3) 算像素均值;(4)根据相似均值计算指纹。具体算法如下所示:
如何删除图片数据中的重复数据_第1张图片
得到图片的ahash值后,比较两张图片ahash值的汉明距离,通常认为汉明距离小于10的一组图片为相似图片。当距离=0时即为重复数据。

2.示例展示
本文图片为Lena图来说明.
如何删除图片数据中的重复数据_第2张图片
进过resize之后形成8x8尺寸的图片
如何删除图片数据中的重复数据_第3张图片
之后,将图2灰度化,获得图3.
如何删除图片数据中的重复数据_第4张图片
图3对应的数据矩阵如下
如何删除图片数据中的重复数据_第5张图片很容得到如上矩阵所有元素的均值a= 121.328125, 将上述矩阵中大于或等于a的元素置为1, 小于a的元素置为0,可得:
如何删除图片数据中的重复数据_第6张图片所以可得Lena图的aHash为

   1011111010011110100111011010100110101011101000110000111000101100

   将二进制形式ahash转十六进制hash为

   be9e9da9aba30e2c

3.code
我们使用result_dict来寄存图片地址与图片hash值,其中key为hash值,value为图片地址,这样我们在遍历dict时,就可以根据hash值找到对应的图片地址,并删除冗余图片。为了效率,我们可以使用多进程来加速。

def async_hash(fpath, result_dict, result_lock):
    try:
        h = imagehash.average_hash(Image.open(fpath))
        h = "%s" % h
        sims = result_dict.get(h, [])
        sims.append(fpath)
        with result_lock:
            result_dict[h] = sims
    except Exception as e:
        pass

你可能感兴趣的:(哈希算法,算法)