首页 > 技术文章 > 图片相似度——hash算法简介

gaosheng12138 2017-08-31 14:22 原文

一、均值hash

均值hash方法是对每幅图片生成一个“指纹”字符串,然后通过比较不同图片的指纹来确定图片的相似性,比较结果越接近,则说明图片越相似。 
计算均值hash的步骤。 
1、缩小尺寸 
去除高频和细节的最快方法是缩小图片,将图片缩小到8x8的尺寸,总共64个像素。不要保持纵横比,只需将其变成8*8的正方形。这样就可以比较任意大小的图片,摒弃不同尺寸、比例带来的图片差异。 
2、简化色彩 
将8*8的小图片转换成灰度图像,将64个像素的颜色(red,green,blue)转换成一种颜色(黑白灰度)。 
3、计算平均值 
计算所有64个像素的灰度平均值。 
4、比较像素的灰度 
将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。 
5、计算hash值 
将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。(我设置的是从左到右,从上到下用二进制保存)。

二、感知hash(phash)

感知hash和均值hash非常相似,使用离散余弦(DCT)降低频率。 
二维DCT变换就是将二维图像从空间域转换到频率域。形象的说,就是计算出图像由哪些二维余弦波构成,计算出的结果为c(u ,v), 其中u为二维波的水平方向频率,v为二维波的垂直方向频率; 最终会计算出很多的c(u,v) ; 每一个c称为一个DCT系数,代表的是频率为(u,v)的二维波的振幅(或者能量),所有这些二维波的叠加就是那个原始的图片。 
 
 
计算phash的步骤: 
1、缩小尺寸 
pHash以小图片开始,但图片大于8*8,32*32是最好的。这样做的目的是简化了DCT的计算,而不是减小频率。 
2、简化色彩 
将图片转化成灰度图像,进一步简化计算量。 
3、计算DCT 
DCT是把图片分解频率聚集和梯状形,虽然JPEG使用8*8的DCT变换,在这里使用32*32的DCT变换。 
4、缩小DCT 
虽然DCT的结果是32*32大小的矩阵,但我们只要保留左上角的8*8的矩阵,这部分呈现了图片中的最低频率。 
5、计算平均值 
如同均值哈希一样,计算DCT的均值, 
6、进一步减小DCT 
这是最主要的一步,根据8*8的DCT矩阵,设置0或1的64位的hash值,大于等于DCT均值的设为”1”,小于DCT均值的设为“0”。 
7、构造hash值 
将64bit设置成64位的长整型,组合的次序并不重要,只要保证所有图片都采用同样次序就行了。与均值哈希一样,pHash同样可以用汉明距离来进行比较。(只需要比较每一位对应的位置并算计不同的位的个数)

 

推荐阅读