图片哈希概述(image hash)

一切的起源都来自这篇文章:《相似图片搜索的原理》,阮一峰大佬 11 年的这篇博客讲述了 Google 以图搜图的原理,其中的获取图片 hash 值的方法就是 AHash。

每张图片都可以通过某种算法得到一个 hash 值,称为图片指纹,两张指纹相近的图片可以认为是相似图片。

以图搜图的原理就是获取你上传的图片的指纹,和图库的图片指纹对比,查找出最相似的若干张图片展示。

除了以图搜图,图片哈希还可以做什么呢?例如图片检索,重复图片剔除,图片相似度比较等等。

这种哈希算法大概有 4 种:

  • 差值哈希:DHash(Difference Hash)
  • 均值哈希:AHash(Average Hash)
  • 感知哈希:PHash(Perceptual Hash)
  • 小波哈希:WHash(Wavelet Hash)

常用的是前面三种,DHash、AHash、PHash。其中 PHash 是增强版的 AHash。

图片基本概念

图片是由像素点矩阵组成的,信息可保存在数组中,如下图 4*4 的图片,可保存在二维数组中:
在这里插入图片描述
左上角为起始点

row 表示行,对应图片的高 height,y 方向

col 表示列,对应图片的宽 width,x 方向

四种 Hash 算法的步骤

差值哈希

梯度散列

  1. 缩小尺寸,建议 9*8(col = row + 1)
  2. 灰度化
  3. 计算灰度差值(做差变为 8*8 的矩阵)
  4. 计算哈希值
均值哈希

平均散列

  1. 缩小尺寸,建议 8*8
  2. 灰度化
  3. 计算平均值
  4. 比较像素的灰度
  5. 计算哈希值
感知哈希

核心:离散余弦变换(DCT)

  1. 缩小尺寸,建议 32*32
  2. 灰度化
  3. 进行离散余弦变换(DCT)
  4. 取左上角的 8*8 的大小
  5. 计算平均值
  6. 比较像素的灰度
  7. 计算哈希值
小波哈希

核心:离散小波变换(DWT),和感知哈希步骤相同,只是将步骤 DCT 换为 DWT

  1. 缩小尺寸,建议 32*32
  2. 灰度化
  3. 进行离散小波变换(DWT)
  4. 取左上角的 8*8 的大小
  5. 计算平均值
  6. 比较像素的灰度
  7. 计算哈希值

步骤讲解

缩小尺寸

比较两张完全相同的图片是否相同的做好方法是什么?

记这张图片的像素点个数为 m,逐个像素点比较,不同像素点记为 n = 0,每有一个不同则+1,最后(n/m)*100则为两张图片的相似度。

如果两张图片是 1000 * 1000 的呢?

那将对比一百万次。太耗时了。因此要减少对比次数,那么就要减少像素点个数。基于抽样检测的原理,压缩图片就是首要要做的工作了。将 1000 * 1000 的图片压缩到 8 * 8 的大小,那么只需对比 64 次即可。

灰度化

如果对比的两张图片,第二种是经过第一张图片转换过来的,比如由 png 转为了 jpg 造成了色值失真,或传输过程中其他原因造成了色值失真,怎么办呢?

答案是进行灰度化。一个像素点是有 ARGB 组成的:A透明度、R红色、G绿色、B蓝色。每个色度分为 0~255 一共 256 个色阶,一般情况下除以 4,将色阶缩小到 64 位,通过这一步处理后,彩色图片基本上会变成黑白灰三种颜色,所以叫灰度化。

灰度化可以缩小色值失真带来的影响。比如红色是 200,失真后是 160,差值为 40;灰度后变为 50 - 40 = 10,差值变小了,计算 hash 时相似度会提升。

中间步骤

每种哈希算法的差异就在中间的通过何种策略获取 64 位二进制数据,之后的文章我们再详细讲解。

计算哈希值

这一步没有太多技术含量,经过不同算法前面的几步运算,会得到一个 64 位的二进制数组,将数组转为 16 进制就是计算哈希值。

ps:很多博客中讲到图片相似都提到"汉明距离",5以内表示图片相似,大于10则表示两张图片不同。但有的比较的是 64 位的二进制串,有的比较的是 16 位的十六进制串,度量方式不同结果可能大相径庭。

比如:

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

上面两个字符串的汉明距离是 12,两张图肯定不相似。

但如果转为十六进制:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
f f f 0 0 0 0 0 0 0 0 0 0 0 0 0

上面两个字符串的汉明距离是 3,表示两个图片相似。

经过测试:应该比较 64 位的二进制字符串,才是准确的。

本文原创发布于公众号 习习立 ,关注公众号回复 hash 获取源码。

  • 13
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值