感知哈希、平均哈希、差异值哈希

感知哈希算法是一类哈希算法的总称,其作用在于生成每张图像的“指纹”(fingerprint)字符串,比较不同图像的指纹信息来判断图像的相似性。结果越接近图像越相似。感知哈希算法包括均值哈希(aHash)、感知哈希(pHash)和差异值哈希(dHash)。

aHash速度较快,但精确度较低;pHash则反其道而行之,精确度较高但速度较慢;dHash兼顾二者,精确度较高且速度较快。

在得到64位hash值后,使用汉明距离量化两张图像的相似性。汉明距离越大,图像的相似度越小,汉明距离越小,图像的相似度越大。

  • 区别

    1. 均值哈希和差值哈希算法的时间都比感知哈希少,因为感知哈希resize为32*32,并且要进行DCT离散余弦变换,这个计算比较耗时

    2. 改变图片的亮度,色度,对比度,锐度,均值哈希的效果都是最好的,几乎不受影响,其次是差值哈希,最差是感知哈希

    3. 但是感知哈希在图片旋转以及resize后,效果比前两者要好

  • 算法

    • 平均哈希(aHash)

      1. 图片缩放,一般为88,或者3232
      2. 将图片灰度化
      3. 求平均值,并根据平均值将每一个像素二值化
      4. 将8*8=64位bit,每8个比特为一个十六进制值,转换成字符串,生成哈希值(指纹)
    • 感知哈希(pHash)

      1. 图片缩放 为32*32大小
      2. 将图片灰度化
      3. 对图片进行离散余弦变换(DCT),转换的频域
      4. 取频域左上角8*8大小(图片的能量都集中在低频部分,低频位于左上角)
      5. 计算平均值,并根据平均值二值化(同平均哈希)
      6. 生成哈希值
    • 差异值哈希(dHash)

      1. 图片缩放为9*8大小
      2. 将图片灰度化
      3. 差异值计算(每行相邻像素的差值,这样会生成8*8的差值,前一个像素大于后一个像素则为1,否则为0)
      4. 生成哈希值
  • 其他关键词

    • 计算距离

      生成每一个图片的哈希值后,需要计算哈希值的距离,来判断两张图片的相似度。一般使用汉明距离,也就是逐位计算两张图片的哈希值是否相同。

    • 灰度图相关算法

      对于彩色转灰度,其基础的心理学公式为: 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变换:

        一维DCT.png

        其中,f(i)为原始的信号,F(u)是DCT变换后的系数,N为原始信号的点数,c(u)可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵。

      • 二维离散余弦变换的正变换公式为:

        二维DCT.png

      缩小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说明是不同的照片。

参考文档:

感知哈希 ,平均哈希,差异值哈希

感知哈希算法

Last modification:November 17th, 2020 at 02:55 pm