感知哈希算法(Perceptual Hash Algorithm,简称pHash) 是哈希算法的一种,主要可以用来做以图搜索/相似图片搜索工作。
感知哈希算法(pHash)首先将原图像缩小成一个固定大小的像素图像,然后将图像转换为灰度图像,通过使用离散余弦变换(DCT)来获取频域信息。然后,根据DCT系数的均值生成一组哈希值。最后,利用两组图像的哈希值的汉明距离来评估图像的相似度。
魔法: 概括地讲,感知哈希算法一共可细分八步:
将目标图像缩小为一个固定的大小,通常为32x32像素。作用是去除各种图像尺寸和图像比例的差异,只保留结构、明暗等基本信息,目的是确保图像的一致性,降低计算的复杂度。
使用 OpenCV 的 resize 函数将图像缩放为32x32像素。
OpenCV 的 cv2.resize() 函数提供了4种插值方法,以根据图像的尺寸变化来进行图像重采样。
将缩小的图像转换为灰度图像。
输出打印:
感知哈希算法的核心是应用离散余弦变换。DCT将图像从空间域(像素级别)转换为频域,得到32×32的DCT变换系数矩阵,以捕获图像的低频信息。这里我们使用 OpenCV 的 cv2.dct 函数来执行DCT。
这行代码执行了离散余弦变换(DCT),它将图像数据从空间域(像素级别)转换为频域,以便在频域上分析图像。
基于DCT的图像感知哈希算法是一种能够有效感知图像全局特征的算法,将图片认为是一个二维信号,包含了表现大范围内的亮度变化小的低频部分与局部范围亮度变化剧烈的高频部分,而高频部分一般存在大量的冗余和相关性。通过DCT变换,可以将高能量信息集中到图像的左上角区域。可以理解为图像的特征频率区域。
如下图,将图像进行DCT后得到其变换结果,图像左上角变化明显,而右下角几乎没有变化。
经过DCT变换后,图像的频率特征集中在图像的左上角,保留系数矩阵左上角的8×8系数子矩阵(因为虽然DCT的结果是32×32大小的矩阵,但左上角8×8的矩阵呈现了图片中的最低频率)。
备注: 这里为什么要缩放DCT?以及其它缩放方式有哪些?不同缩放方式结果有何不同?不进行缩放DCT会怎么样?等等问题,我们在文末对比解答。
计算DCT变换后图像块的均值,以便后面确定每个块的明暗情况。
输出打印:
如果块的DCT系数高于均值,表示为1,否则表示为0。
由于我们只提取了DCT矩阵左上角的8×8系数子矩阵(图片特征频率区域),所以,最后会得到一个64位的二进制值(8x8像素的灰度图像)。
或者,使用等价的 lambda 表达式。效果一样。
输出打印:
由于64位二进制值太长,所以按每4个字符为1组,由2进制转成16进制。这样就转为一个长度为16的字符串。这个字符串也就是这个图像可识别的哈希值,也叫图像指纹,即这个图像所包含的特征。
输出打印:
通过比较两个图像的哈希值的汉明距离(Hamming Distance),就可以评估图像的相似度,距离越小表示图像越相似。
汉明距离:两个长度相同的字符串在相同位置上的字符不同的个数。即一组二进制数据变成另一组数据所需要的步骤数。汉明距离越小,则相似度越高。汉明距离为0,即两张图片完全一样。
我们来简单测试一下基于感知哈希算法的以图搜图 – 基于一张原图找最相似图片,看看效果如何。 这里,我准备了10张图片,其中9张是苹果,但形态不一,1张是梨子。
输出打印:
简单的测试分析:
10张测试图片中,汉明距离在5以内的有8张图片;汉明距离在10以外只有1张图片。 从抽样简单测试结果看,感知哈希算法表现更友好、更准确。
备注:如果汉明距离0,则表示这两张图片非常相似;如果汉明距离小于5,则表示有些不同,但比较相近;如果汉明距离大于10,则表明是完全不同的图片。
经过实验和测试,感知哈希算法的撸棒性更好。总体与均值哈希算法(aHash)差不多,区别在于二值化方式不一样。
特点: 传统, 属于一种外观相似哈希算法。 优点: 简单、相对准确、计算效率高;感知哈希考虑了图像的全局特征,对图像的尺寸和旋转变化具有一定的鲁棒性;适用于快速图像相似性搜索。 缺点: 对一些局部变化不够敏感;对于复杂、多色调的图像较难辨别,属于一种外观相似的相似度计算。
为什么要缩放DCT?DCT缩放方式有哪些?不同DCT缩放方式有何不同?不进行DCT缩放效果会怎么样?
对于这些问题,我们来通过下面三组对比分析,一探究竟。
方式一: DCT变换后,无DCT特征频率区域缩放 方式二: DCT变换后,将DCT系数显式调整为8x8 方式三: DCT变换后,只提取DCT系数左上角8x8像素 从上图的DCT变换过程来看,从原图读取,到缩小到指定大小的像素图像,再到像素图像灰度化,对于图像的加工结果都是一样的。区别仅在于对灰度图像使用离散余弦变换(DCT)之后,对DCT系数的使用方式不一样。
同一张图片使用不同DCT变换方式获得的哈希值结果:
从上述的DCT变换结果来看,同一张图片获得图像的二进制哈希值各不一样。
不同图片使用相同DCT变换方式获得的哈希值结果: 从上图的DCT变换结果来看,不同图片使用不同方式的DCT变换,最终查找的相似图片结果都不尽相同。
如上代码,这三种方法获取到的图像二进制哈希值之所以不同,是因为它们在DCT变换后的处理方式不同:
由于这些方法考虑的DCT系数区域不同,它们生成的哈希值会有差异。一般来说,get_pHash1 方法考虑了整个图像块的频率分布,因此哈希值可能更稳定,但它也可能受到图像整体性的影响。而 get_pHash2 和 get_pHash3 方法只考虑了一个小块的频率信息,所以哈希值可能更容易受到图像的局部特征影响。
选择哪种方法取决于你的应用需求。如果你希望更稳定的哈希值,get_pHash1 可能是一个不错的选择。如果你希望更灵敏地检测局部特征,get_pHash2 或 get_pHash3 可能更适合。
本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕,E-mail:975644476@qq.com
本文链接:http://chink.83seo.com/news/414.html