2013-03-01 04:32 from—http://blog.csdn.net/zmazon/article/details/8618775
想必大家都用google或baidu的识图功能,上面就是我搜索冠希哥一幅图片的结果,达到图片比较目的且利用信息指纹比较有三种算法,这些算法都很易懂,下面分别介绍一下:
一、平均哈希算法(aHash)
此算法是基于比较灰度图每个像素与平均值来实现的,最适用于缩略图,放大图搜索。
步骤:
1.缩放图片:为了保留结构去掉细节,去除大小、横纵比的差异,把图片统一缩放到8*8,共64个像素的图片。
2.转化为灰度图:把缩放后的图片转化为256阶的灰度图。
附上灰度图相关算法(R = red, G = green, B = blue)
3.计算平均值: 计算进行灰度处理后图片的所有像素点的平均值。
4.比较像素灰度值:遍历灰度图片每一个像素,如果大于平均值记录为1,否则为0.
5.得到信息指纹:组合64个bit位,顺序随意保持一致性即可。
6.对比指纹:计算两幅图片的指纹,计算汉明距离(从一个指纹到另一个指纹需要变几次),汉明距离越大则说明图片越不一致,反之,汉明距离越小则说明图片越相似,当距离为0时,说明完全相同。(通常认为距离>10 就是两张完全不同的图片)
下面是我用Java写的此算法的程序,eclipse可直接运行。
下载地址:http://download.csdn.net/detail/nash_/5093143
待比较的原图:
图片库中的四张图:
输出结果:
similar_pic.jpg与原图很少相似
google.gif与原图完全不同
origin.jpg与原图是同一张图
ohter_word.jpg与原图极其相似
二、感知哈希算法(pHash)
平均哈希算法过于严格,不够精确,更适合搜索缩略图,为了获得更精确的结果可以选择感知哈希算法,它采用的是DCT(离散余弦变换)来降低频率的方法
步骤:
1.缩小图片:32 * 32是一个较好的大小,这样方便DCT计算
2.转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤)
3.计算DCT:DCT把图片分离成分率的集合
4.缩小DCT:DCT是32*32,保留左上角的8*8,这些代表的图片的最低频率
5.计算平均值:计算缩小DCT后的所有像素点的平均值。
6.进一步减小DCT:大于平均值记录为1,反之记录为0.
7.得到信息指纹:组合64个信息位,顺序随意保持一致性即可。
8.对比指纹:计算两幅图片的指纹,计算汉明距离(从一个指纹到另一个指纹需要变几次),汉明距离越大则说明图片越不一致,反之,汉明距离越小则说明图片越相似,当距离为0时,说明完全相同。(通常认为距离>10 就是两张完全不同的图片)
此算法可参考开源项目pHash,下载地址:http://www.phash.org/download/
三、差异哈希算法(dHash)
相比pHash,dHash的速度要快的多,相比aHash,dHash在效率几乎相同的情况下的效果要更好,它是基于渐变实现的。
步骤:
1.缩小图片:收缩到9*8的大小,一遍它有72的像素点
2.转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤)
3.计算差异值:dHash算法工作在相邻像素之间,这样每行9个像素之间产生了8个不同的差异,一共8行,则产生了64个差异值
4.获得指纹:如果左边的像素比右边的更亮,则记录为1,否则为0.
需要说明的是这种指纹算法不仅可以应用于图片搜索,同样适用于其他多媒体形式。除此之外,图片搜索特征提取方法有很多,很多算法还有许多可以改进的地方,比如对于人物可以先进行人脸识别,再在面部区域进行局部的哈希,或者背景是纯色的可以先过滤剪裁等等,最后在搜索的结果中还可以根据颜色、风景、产品等进行过滤。