用户登录
用户注册

分享至

图像的相似度Hash算法

  • 作者: 朵兰的小商铺
  • 来源: 51数据库
  • 2021-06-26

hash算法有三种,分别为平均哈希算法(ahash)、感知哈希算法你(phash)和差异哈哈希算法(dhash)。

针对以上三种的hash算法详解见博客园文章 

https://www.cnblogs.com/kalafinaian/p/11260808.html

本文实现针对平均哈希算法;

1 平均哈希算法(ahash)

1.1 算法步骤

       平均哈希算法是三种hash算法中最简单的一种,它通过下面几个步骤来获得图片的hash值,这几个步骤分别是(1) 缩放图片;(2)转灰度图; (3) 算像素均值;(4)根据相似均值计算指纹。具体算法如下所示:

  表1 ahash得到图片hash值地算法

缩放图片

输入图片大小尺寸各异,为了统一图片的输入,统一将图片尺寸缩放为8*8,一共得到了64个像素点。

转灰度图

输入图片有些为单通道灰度图,有些rgb三通道彩色图,有些为rgba四通道彩色图。也为了统一下一步输入标准,将非单通道图片都转为单通道灰度图。 其中rgb三通道转单通道算法有下面几种:

1.浮点算法:gray=r0.3+g0.59+b0.11

2.整数方法:gray=(r30+g59+b11)/100

3.移位方法:gray =(r76+g151+b*28)>>8; 

4.平均值法:gray=(r+g+b)/3; 

5.仅取绿色:gray=g;

算像素均值

通过上一步可得一个8x8的整数矩阵g,计算这个矩阵中所有元素的平均值,假设其值为a

据像素均值计算指纹

初始化输入图片的ahash = "" 

从左到右一行一行地遍历矩阵g每一个像素如果第i行j列元素g(i,j) >= a,则ahash += "1"如果第i行j列元素g(i,j) <a, 则ahash += "0"

       

 

 

 

 

 

 

 

 

 

 

 

 

 

得到图片的ahash值后,比较两张图片ahash值的汉明距离,通常认为汉明距离小于10的一组图片为相似图片。

  demo 界面/  

 

   

  获取ahash函数如下:

function tform1.gethash(src: tbitmap; itype: integer): int64;
var
  p: pbytearray;
  bmp: tbitmap;
  x, y: integer;
  gray, sum: integer;
  ct: array[0..7, 0..7] of byte;
  avg: single;
  ret: int64;
begin
  ret := 0;
  case itype of
    0:  // ahash  平均哈希算法
    begin
      bmp := tbitmap.create;
      try
        bmp.assign(src);
        bmp.width := 8;
        bmp.height := 8;
        bmp.pixelformat := pf24bit;
        sum := 0;
        for y := 0 to 7 do
        begin
          p := bmp.scanline[y];
          for x := 0 to 7 do
          begin
            //转灰度图 平均值法
            gray := (p[3 * x + 2] + p[3 * x + 1] + p[3 * x]) div 3;
            ct[y, x] := gray;
            sum := sum + gray;
          end;
        end;
        avg := sum/64;
        for y := 0 to 7 do
          for x := 0 to 7 do
            ret := ret shl 1 or ord(ct[y, x] > avg);
      finally
        bmp.free;
      end;
    end;
    1:  // phash  感知哈希算法
    begin

    end;
    2:  // dhash  差异哈希算法
    begin

    end;
  end;
  result := ret;
end;

计算汉明距离函数:原理参考:https://blog.csdn.net/u013243347/article/details/52220551

function tform1.hamming(hash1, hash2: int64): integer;
var
  a: int64;
begin
  result := 0;
  a := hash1 xor hash2;
  while a<>0 do
  begin
    a := a and (a-1);
    inc(result);
  end;
end;

demo 下载地址:https://download.csdn.net/download/huffmanlepand/11833317

软件
前端设计
程序设计
Java相关