PHash算法(Perceptual Hash algorithm),即感知哈希算法,计算基于低频的均值哈希。它对每一张图像生成一个指纹字符串,进而通过该字符串比较不同图片对应的指纹。若结果越接近,就说明图片相似度越高。可应用于以图搜图的应用中。下面是我们基于OpenCV实现的算法及相关分析。本算法思想见参考文献[3]。
7.5.1 PHash算法的使用
在Windows7环境下,使用Microsoft Visual Studio 2010开发环境,配置OpenCV2.4.9及以上版本。
该算法的项目文件名称是“phashProject.sln”,位于“..phash”路径下。具体操作步骤如下。
(1)打开PHash→phashProject.sln,然后打开源文件phashproject.cpp。
(2)输入训练数据集路径和格式替换时可在主函数下面两行代码中修改:
(3)修改输入测试数据的路径时,应在以下代码中修改:
sprintf(model_fileName, /"image150x200//S001-002.jpg");
(4)输出数据在与项目phashproject.cpp文件同一路径下的hanmingdistance.txt文件中。
按照以上步骤提示执行phashproject.cpp文件即可。
7.5.2 PHash算法原理
Phash算法的基本原理是:首先将图片转换为灰度图,再将图片调整到32×32像素的尺寸并通过DCT变换,取左上角8×8像素的区域。然后,计算这64个像素的灰度平均值,将每个像素的灰度值与平均值进行比较,大于平均值的记为1,否则记为0,从而得到64位哈希值。
7.5.3 PHash算法实现
PHash算法的具体计算步骤如下。
(1)将输入图片转换成灰度图:
若是RGB彩色图像,则将其转换成灰度图像。
(2)缩小图片的尺寸为32×32像素:
这样做的目的是便于DCT变换,节省运行时间。
(3)DCT(Discrete Cosine Transform)变换:
dct(image, imageDct);//DCT变换
对于一般的图像而言,大多数DCT系数值都接近于0,因此去掉这些系数不会对重建图像的质量产生较大的影响。这样,利用DCT进行图像压缩可以节省大量的存储空间和运行时间。
(4)缩小DCT,保留左上角8×8像素的区域:
一般来说,变换后的DCT系数值较大的会集中在区域的左上部,即低频分量都集中在左上部。所以,我们只取左上角8×8像素的区域。
(5)计算8×8像素区域的平均值,进行像素值比较并求hash值:
计算最终DCT变换后的所有像素点(8×8)的平均值,并对每一个像素点遍历,若像素点大于平均值,则记为1;反之,则记为0。组合成64个信息位作为该图像的信息指纹,顺序保持一致性即可。
(6)指纹(hash值)匹配:
计算两幅图像哈希值之间的汉明距离(两个相同长度的哈希值之间的汉明距离)。显然,汉明距离越大,表示图片越不相似。
7.5.4 PHash算法的实验数据、实验结果及分析
1.实验数据
实验的输入图像集在项目路径下,若需要替换图像集,则可在主函数的前两行进行修改。其中,第一行表示图像的路径名,第二行表示图像的类型。
输入查询图像的路径:
2.实验结果
查询图像如图7-1所示。
图7-1 查询图像(1)
检索出的部分相似图像如图7-2所示。
图7-2 检索出的部分相似图像(1)
实验结果保存在与phashproject.cpp同一路径下的hanming-distance.txt和fileName.txt文件内。其中,fileName.txt表示图像集的图像名,hanming-distance.txt中每一行表示对应图像与查询图像的汉明距离。部分结果如表7-1所示。
表7-1 部分实验结果(1)
续表
续表
3.实验分析
相似图像的相似度(汉明距离)大多在小于等于5的范围内。本算法中我们设置的阈值为6,也就是说,凡是汉明距离小于6的,都被我们认为是相似图像,并输出“yes”作标记。本算法中查准率为40/48×100%=83.3%,查全率为40/42×100%=95.2%。