感知哈希、平均哈希、差异值哈希
感知哈希算法是一类哈希算法的总称,其作用在于生成每张图像的“指纹”(fingerprint)字符串,比较不同图像的指纹信息来判断图像的相似性。结果越接近图像越相似。感知哈希算法包括均值哈希(aHash)、感知哈希(pHash)和差异值哈希(dHash)。
aHash速度较快,但精确度较低;pHash则反其道而行之,精确度较高但速度较慢;dHash兼顾二者,精确度较高且速度较快。
在得到64位hash值后,使用汉明距离量化两张图像的相似性。汉明距离越大,图像的相似度越小,汉明距离越小,图像的相似度越大。
-
区别
-
均值哈希和差值哈希算法的时间都比感知哈希少,因为感知哈希resize为32*32,并且要进行DCT离散余弦变换,这个计算比较耗时
-
改变图片的亮度,色度,对比度,锐度,均值哈希的效果都是最好的,几乎不受影响,其次是差值哈希,最差是感知哈希
-
但是感知哈希在图片旋转以及resize后,效果比前两者要好
-
-
算法
-
平均哈希(aHash)
- 图片缩放,一般为88,或者3232
- 将图片灰度化
- 求平均值,并根据平均值将每一个像素二值化
- 将8*8=64位bit,每8个比特为一个十六进制值,转换成字符串,生成哈希值(指纹)
-
感知哈希(pHash)
- 图片缩放 为32*32大小
- 将图片灰度化
- 对图片进行离散余弦变换(DCT),转换的频域
- 取频域左上角8*8大小(图片的能量都集中在低频部分,低频位于左上角)
- 计算平均值,并根据平均值二值化(同平均哈希)
- 生成哈希值
-
差异值哈希(dHash)
- 图片缩放为9*8大小
- 将图片灰度化
- 差异值计算(每行相邻像素的差值,这样会生成8*8的差值,前一个像素大于后一个像素则为1,否则为0)
- 生成哈希值
-
-
其他关键词
-
计算距离
生成每一个图片的哈希值后,需要计算哈希值的距离,来判断两张图片的相似度。一般使用汉明距离,也就是逐位计算两张图片的哈希值是否相同。
-
灰度图相关算法
对于彩色转灰度,其基础的心理学公式为: Gray = R0.299 + G0.587 + B0.114,部分变种也很流行:
- 浮点算法:Gray=R0.3+G0.59+B0.11
- 整数方法:Gray=(R30+G59+B11)/100
- 移位方法:Gray =(R76+G151+B28)>>8;
- 平均值法:Gray=(R+G+B)/3;
- 仅取绿色:Gray=G;
-
计算DCT
DCT变换的全称是离散余弦变换(Discrete Cosine Transform),主要用于将数据或图像的压缩,能够将空域的信号转换到频域上,具有良好的去相关性的性能。DCT变换本身是无损的,但是在图像编码等领域给接下来的量化、哈弗曼编码等创造了很好的条件,同时,由于DCT变换时对称的,所以,我们可以在量化编码后利用DCT反变换,在接收端恢复原始的图像信息。对原始图像进行离散余弦变换,变换后DCT系数能量主要集中在左上角,其余大部分系数接近于零,DCT具有适用于图像压缩的特性。将变换后的DCT系数进行门限操作,将小于一定值得系数归零,这就是图像压缩中的量化过程,然后进行逆DCT运算,可以得到压缩后的图像。
离散余弦变换的原理:
-
一维DCT变换:
其中,f(i)为原始的信号,F(u)是DCT变换后的系数,N为原始信号的点数,c(u)可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵。
-
二维离散余弦变换的正变换公式为:
缩小DCT:DCT的结果为32x32大小的矩阵,但只需保留左上角的8x8的矩阵,这部分呈现了图片中的最低频率。
-
-
-
MATLAB实现ahash
% 这种算法的优点是简单快速,不受图片大小缩放的影响,缺点是图片的内容不能变更。 % 如果在图片上加几个文字,它就认不出来了。所以,它的最佳用途是根据缩略图,找出原图。 clc; clear all; % 第一,将图像缩放到8*8大小,缩放不变性 I=imread('MN.jpg'); figure,imshow(I),title('原始图像'); J=imresize(I,[8,8]); figure,imshow(J),title('8*8图像'); % 第二、将图像灰度化到64个灰度级,灰度粗化 img = double(rgb2gray(J)); img_64 = floor(img/255*64); figure,imshow(img_64),title('8*8-64级图像'); % 第三、计算灰度平均值 gray_mean = sum(img_64(:))/64; % 第四、将所有像素的灰度和均值比较,大于的为1,小于的为0 feature_img = zeros(8,8); for i=1:8 for j=1:8 if img_64(i,j) >= gray_mean feature_img(i,j) = 1; end end end figure,imshow(feature_img),title('8*8特征图像'); % 第五步,计算哈希值。将其变换成一行即可。 hash_feature = reshape(feature_img,1,64) % 两个哈希值中小于5个不同,说明很相似的图。大于10说明是不同的照片。
参考文档: