【WHash】更有空间感的感知哈希
背景
在重复图识别领域,对于识别肉眼相同图片,感知哈希效果是很鲁棒的。上一篇文章 【PHash】更懂人眼的感知哈希 介绍的PHash识别效果很好,但是它有一个缺点,只关注低频信息,并没有关注图片的空间信息,极端情况就可能出现完全不同的两张图片,phash值很近。而WHash利用小波变换不仅重点关注低频信息,同时也关注图片的空间信息。
WHash算法
- WHash算法如下:
下面附上源代码,代码很短,也可以先忽略: - python源码如下:
def whash(image, hash_size = 8):
#check
assert hash_size & (hash_size-1) == 0, "hash_size is not power of 2"
image_scale = max(2**int(numpy.log2(min(image.size))), hash_size)
ll_max_level = int(numpy.log2(image_scale))
level = int(numpy.log2(hash_size))
assert level <= ll_max_level, "hash_size in a wrong range"
#预处理
image = image.convert("L").resize((image_scale, image_scale), Image.ANTIALIAS)
pixels = numpy.asarray(image) / 255.
# 小波变换,haar
coeffs = pywt.wavedec2(pixels, 'haar', level = ll_max_level)
# 去掉最低频
coeffs[0] *= 0
# 小波逆变换
dwt_low = pywt.waverec2(coeffs[:level+1], 'haar')
#二值化,中值
med = numpy.median(dwt_low)
diff = dwt_low > med
return diff
WHash算法其实也比较简单,主要利用了小波变换获取低频信息,主要就是下面3步:
- 图片预处理(resize,转灰度图)
- 小波变换
- 二值化
其中预处理就是缩放+转灰度图,而二值化跟PHash一样,都是利用中值当作基准值。
这里的重点在于小波变换,下面简单直观的给大家看下小波变换究竟是什么?
直观理解小波变换
在图片上进行小波变换,可以把图片的低频跟高频信息拆分,如下所示:
其中,A是低频信息,H是水平高频信息,V是垂直高频信息、D是对角高频信息。
在实际运用,并不是只进行一次低频高频拆分,会进行多次,如下图所示:
在WHash这里,我们只是拿最右边那张图片,左上角1/4信息进行二值化,其他信息都是抛弃的。
在WHash里面,小波变换并不是单纯的拿到了图片的低频信息,而且还保存了本身图片的空间信息,所以它实际使用过程中,比PHash鲁棒一些。当然如果PHash对只对低频部分进行DCT逆变换,然后再进行二值化,也是可以考虑上空间信息的,跟WHash一样的道理。
【WHash】更有空间感的感知哈希的更多相关文章
- 感知哈希算法的java实现
一.原理讲解 实现这种功能的关键技术叫做"感知哈希算法"(Perceptual Hash Algorithm), 意思是为图片生成一个指纹(字符串格式), 两张图片的指纹 ...
- 谷歌百度以图搜图 "感知哈希算法" C#简单实现
/// <summary> /// 感知哈希算法 /// </summary> public class ImageComparer { /// <summary> ...
- 感知哈希算法——Python实现【转】
转自:https://blog.csdn.net/m_buddy/article/details/78887248 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...
- 感知哈希算法 python 3.4
#!/usr/bin/python # -*- coding: UTF-8 -*- #Less than 10 add to list and sort import glob import os i ...
- 图片哈希概论及python中如何实现对比两张相似的图片
Google 以图搜图的原理,其中的获取图片 hash 值的方法就是 AHash. 每张图片都可以通过某种算法得到一个 hash 值,称为图片指纹,两张指纹相近的图片可以认为是相似图片. 以图搜图的原 ...
- 更有效率的使用Visual Studio(二)
没想到上一篇文章有这么多人喜欢,多谢大家支持.继续- 很多比较通用的快捷键的默认设置其实是有一些缩写在里面的,这个估计也是MS帮助我们记忆.比如说注释代码的快捷键是Ctrl + E + C,我们如果知 ...
- 从HashMap透析哈希表
##扯数据结构 先看一下哈希表的概念: 哈希表是一种数据结构,它可以提供快速的插入操作和查找操作.第一次接触哈希表,他会让人难以置信,因为它的插入和删除.查找都接近O(1)的时间级别.用哈希表,很多操 ...
- 更有效率的使用Visual Studio(一)
很多比较通用的快捷键的默认设置其实是有一些缩写在里面的,这个估计也是MS帮助我们记忆.比如说注释代码的快捷键是Ctrl + E + C,我们如果知道它是 Ctrl + Edit + Comment C ...
- 更有效率的使用 Visual Studio - 快捷键
工欲善其事,必先利其器.虽然说Vim和Emacs是神器,但是对于使用Visual Studio的程序员来说,我们也可以通过一些快捷键和潜在的一些功能实现脱离鼠标写代码,提高工作效率,像使用Vim一样使 ...
随机推荐
- TypeError: Cannot read property 'Component' of undefined
继续跟着阮一峰的教程走,下面写到PropTypes的getDefaultProps时,又出现了问题,基于上一个createClass的报错换成了Component写法 错误描述: 解决方法:引入rea ...
- Ceph的Mon数据重新构建工具
关于mon的数据的问题,一般正常情况下都是配置的3个mon的,但是还是有人会担心 Mon 万一三个同时都挂掉了怎么办,那么集群所有的数据是不是都丢了,关于后台真实数据恢复,有去后台取对象,然后一个个拼 ...
- 在Service中创建全局Dialog对话框
需要使用到悬浮窗权限 val builder: AlertDialog.Builder = AlertDialog.Builder(this)builder.setMessage("from ...
- flink1.10版local模式提交job流程分析
1.WordCount程序实例 2.本地监听9000端口后测试结果 3.job提交流程 4.local模式执行StreamGraph任务 5.流程分析 flink job提交流程个人理解可以大致分为定 ...
- [LeetCode题解]876. 链表的中间结点 | 快慢指针
解题思路 使用快慢指针.这里要注意的是,while 的条件会影响当中间节点有两个时,slow 指向的是第一个,还是第二个节点. // 返回的是第一个 while(fast.next != null & ...
- Java并发编程 - Runnbale、Future、Callable 你不知道的那点事(一)
从事Java开发已经快两年了,都说Java并发编程比较难,比较重要,关键面试必问,但是在我的日常开发过程中,还真的没有过多的用到过并发编程:这不疫情嘛,周末不能瞎逛,就看看师傅们常说的 Runnabl ...
- 6、Sping Boot消息
1.消息概述 可通过消息服务中间件来提升系统异步通信.扩展解耦能力 消息服务中两个重要概念:消息代理(message broker)和目的地(destination)当消息发送者发送消息以后,将由消息 ...
- 工作三年终于社招进字节跳动!字节跳动,阿里,腾讯Java岗面试经验汇总
前言 我大概我是从去年12月份开始看书学习,到今年的6月份,一直学到看大家的面经基本上百分之90以上都会,我就在5月份开始投简历,边面试边补充基础知识等.也是有些辛苦.终于是在前不久拿到了字节跳动的o ...
- 苹果电脑下载电影教程:如何用folx下载《小妇人》
由西尔莎罗南.艾玛沃特森等知名影星重新演绎的<小妇人>又带动了新一轮的<小妇人>热潮.这部由露易莎创作的长篇小说,曾被多次拍摄,无论是小说本身,还是其影视资源,都能让观众回味无 ...
- [LGOJ1273]有线电视网
solution 用了一个很有意思的转移方法. $dp[i][j] $ 表达 \(i\) 作为根,\(j\)个终端时最大的收益,即钱数,当\(0\leq dp[1][i]\)时,即以1为根可以转移到\ ...