当前位置:   article > 正文

JAVA二值图像相似_基于感知哈希算法的相似图像检索技术及java代码实现

感知哈希算法之ahash,dhash,phash java实现

目录

1、基于低频的均值哈希

2、增强版:pHash

3、差异哈希算法(dHash)

均值哈希实现图像内容相似度比较完整JAVA代码

大家都用google或baidu的识图功能,上面就是我搜索一幅图片的结果,该引擎实现相似图片搜素的关键技术叫做“感知哈希算法”(Perceptual hash algorithm),它的作用是对每张图片生成一个“指纹”(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。达到图片比较目的且利用信息指纹比较有三种算法,这些算法都很易懂,下面分别介绍一下:

a098d8ec3ddd10a803e5125a84757691.png

1、基于低频的均值哈希

一张图片就是一个二维信号,它包含了不同频率的成分。如下图所示,亮度变化小的区域是低频成分,它描述大范围的信息。而亮度变化剧烈的区域(比如物体的边缘)就是高频的成分,它描述具体的细节。或者说高频可以提供图片详细的信息,而低频可以提供一个框架。

而一张大的,详细的图片有很高的频率,而小图片缺乏图像细节,所以都是低频的。所以我们平时的下采样,也就是缩小图片的过程,实际上是损失高频信息的过程。下面5张图依次是原图,放缩至64*64、32*32、16*16、8*8的图。

8f367c1ceb6b97455382236bfdd21903.png    

bb630177cca1fc8831876e6b4b04a8f7.png  

0ca01cd0ccb48700e9073bde98c01dc3.png  

278ea3969247f1d797821307b0093e98.png  

b2c188217c2e8d1105dd415b178371dd.png

均值哈希算法主要是利用图片的低频信息,其工作过程如下:

(1)缩小尺寸:去除高频和细节的最快方法是缩小图片,将图片缩小到8x8的尺寸,总共64个像素。不要保持纵横比,只需将其变成8*8的正方形。这样就可以比较任意大小的图片,摒弃不同尺寸、比例带来的图片差异。

(2)简化色彩:将8*8的小图片转换成灰度图像。

(3)计算平均值:计算所有64个像素的灰度平均值。

(4)比较像素的灰度:将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。

(5)计算hash值:将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。(我设置的是从左到右,从上到下用二进制保存)。

//均值Hash算法

string HashValue(Mat &src)

{

string rst(64,'\0');

Mat img;

if(src.channels()==3)

cvtColor(src,img,CV_BGR2GRAY);

else

img=src.clone();

/*第一步,缩小尺寸。

将图片缩小到8x8的尺寸,总共64个像素,去除图片的细节*/

resize(img,img,Size(8,8));

/* 第二步,简化色彩(Color Reduce)。

将缩小后的图片,转为64级灰度。*/

uchar *pData;

for(int i=0;i

{

pData = img.ptr(i);

for(int j=0;j

{

pData[j]=pData[j]/4; }

}

/* 第三步,计算平均值。

计算所有64个像素的灰度平均值。*/

int average = mean(img).val[0];

/* 第四步,比较像素的灰度。

将每个像素的灰度,与平均值进行比较。大于或等于平均值记为1,小于平均值记为0*/

Mat mask= (img>=(uchar)average);

/* 第五步,计算哈希值。*/

int index = 0;

for(int i=0;i

{

pData = mask.ptr(i);

for(int j=0;j

{

if(pData[j]==0)

rst[index++]='0';

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/961650
推荐阅读
相关标签
  

闽ICP备14008679号