某些情况下,我们需要检测图片之间的相似性,比较简单、易用的解决方案是采用感知哈希算法
感知哈希算法是一类算法的总称,包括aHash、pHash、dHash。顾名思义,感知哈希不是以严格的方式计算Hash值,而是以更加相对的方式计算哈希值,因为“相似”与否,就是一种相对的判定。
- aHash:平均值哈希。速度比较快,但是常常不太精确
- pHash:感知哈希。精确度比较高,但是速度方面较差一些
- dHash:差异值哈希。Amazing!精确度较高,且速度也非常快。因此我就选择了dHash作为我图片判重的算法。
本文只讲下dhash,如果对ahash和phash感兴趣,可以参考这篇博客
https://blog.csdn.net/xaut_zjb/article/details/39578063
1.缩放图片
第一步是缩放大小,因为一般我们要处理的图片分辨率都非常高,比如640*480就有很多像素点。
from PIL import Image
im = Image.open('test.jpg')
im=im.resize((9,9))#缩放大小一般可定为32,16,9,8等值
2.灰度化
dHash是通过计算相邻像素之间的颜色强度差异得出,如果是RGB图像的话,那么一个像素点就是一个三维数组,还是有点复杂,所以灰度处理成一维数组
im=im.convert("L")
3.计算差异值
差异值是通过计算每行相邻像素的强度对比得出的,如果前一个像素的颜色强度大于第二个像素,那么差异值就设置为1,否则就设置0。
def getdif(image):
dif = []
width=image.size[0]
height=image.size[1]
pix = list(image.getdata()) # 得到像素数据 灰度0-255
for row in range(height):
rowStart = row * width
for index in range(width - 1):
leftindex = rowStart + index
rightindex = leftindex + 1
dif.append(pix[leftindex] > pix[rightindex])
return dif #这里没有转成hash值
4.计算图片汉明距离
汉明距离参考 https://baike.baidu.com/item/汉明距离
在信息论中,两个等长字符串之间的汉明距离(英语:Hamming distance)是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。
def gethamming(dif1=[], dif2=[]):
hamming_distance = 0
for i in range(len(dif1)):
if dif1[i] != dif2[i]:
hamming_distance += 1
if hamming_distance>5: #一般这个值需要自己调整,找一个合适的值
return False
else:
return True