通过直方图的方法
每张图片都可以生成其灰度图像直方图(histogram)。如果两张图片的直方图很接近,就可以认为它们很相似。
1、获得输入灰度图像的直方图分布;2、将直方图划分为64个区,每个区为连续的4个灰度等级;3、对每个区的4个值进行求和运算,得到1个数据,如此,会得到64个数据,即为该幅图像的一个向量(指纹);4、根据步骤【1、2、3】,我们将输入的两幅图像转化为了2个向量,记为A、B;5、计算两个向量的相似度,可以用皮尔逊相关系数或者余弦相似度计算,这里我们采用【余弦相似度】;
以二维空间为例,上图的a和b是两个向量,我们要计算它们的夹角θ。余弦定理告诉我们,可以用下面的公式求得:
假定a向量是[x1, y1],b向量是[x2, y2],那么可以将余弦定理改写成下面的形式:
数学家已经证明,余弦的这种计算方法对n维向量也成立。假定A和B是两个n维向量,A是 [A1, A2, ..., An] ,B是 [B1, B2, ..., Bn] ,则A与B的夹角θ的余弦等于:
使用这个公式,我们就可以得到,句子A与句子B的夹角的余弦。
余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫"余弦相似性"。
6、得到两个向量的夹角之后,我们就可以通过角度的大小来判别它们的相似程度。
7、至此,我们就完成了两幅图像的相似度计算,因此,可以通过此算法来寻找相似的图像。
下面为实验MATLAB代码:
%相似图像搜索:利用直方图分布相似度
%1:获得输入两幅图片的直方图分布
%2:将直方图依次划分为64个区,即每个区有4个灰度等级
%3:分别将各自的64个区生成64个元素,即一个向量(图像指纹)
%4:计算两个向量的余弦相似度
%5:判断,若相似度
function v=tineyesearch_hist(picture1,picture2)
t1=picture1;
[a1,b1]=size(t1);
t2=picture2;
t2=imresize(t2,[a1 b1],'bicubic');%缩放为一致大小
t1=round(t1);
t2=round(t2);
e1=zeros(1,256);
e2=zeros(1,256);
%获取直方图分布
for i=1:a1
for j=1:b1
m1=t1(i,j)+1;
m2=t2(i,j)+1;
e1(m1)=e1(m1)+1;
e2(m2)=e2(m2)+1;
end
end
figure;
imhist(uint8(t1));
figure;
imhist(uint8(t2));
%将直方图分为64个区
m1=zeros(1,64);
m2=zeros(1,64);
for i=0:63
m1(1,i+1)=e1(4*i+1)+e1(4*i+2)+e1(4*i+3)+e1(4*i+4);
m2(1,i+1)=e2(4*i+1)+e2(4*i+2)+e2(4*i+3)+e2(4*i+4);
end
%计算余弦相似度
A=sqrt(sum(sum(m1.^2)));
B=sqrt(sum(sum(m2.^2)));
C=sum(sum(m1.*m2));
cos1=C/(A*B);%计算余弦值
cos2=acos(cos1);%弧度
v=cos2*180/pi;%换算成角度
figure;
imshow(uint8([t1,t2]));
title(['余弦值为:',num2str(cos1),' ','余弦夹角为:',num2str(v),'°']);
%完
下面为实验所用图片和效果: