【matlab】:matlab实现计算两张图片的相似度
2016-04-17 21:46
2667 查看
通过直方图的方法
每张图片都可以生成其灰度图像直方图(histogram)。如果两张图片的直方图很接近,就可以认为它们很相似。
因此,此处我们利用两幅图像的直方图来进行相似度的比较。原理较为简单,具体算法如下:
1、获得输入灰度图像的直方图分布;
2、将直方图划分为64个区,每个区为连续的4个灰度等级;
3、对每个区的4个值进行求和运算,得到1个数据,如此,会得到64个数据,即为该幅图像的一个向量(指纹);
4、根据步骤【1、2、3】,我们将输入的两幅图像转化为了2个向量,记为A、B;
5、计算两个向量的相似度,可以用皮尔逊相关系数或者余弦相似度计算,这里我们采用【余弦相似度】;
下面就顺便介绍一下余弦相似度的概念及用法:
对于两个向量,我们可以把它们想象成空间中的两条线段,都是从原点([0,
0, ...])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。
![](http://image.beekka.com/blog/201303/bg2013032002.png)
以二维空间为例,上图的a和b是两个向量,我们要计算它们的夹角θ。余弦定理告诉我们,可以用下面的公式求得:
![](http://image.beekka.com/blog/201303/bg2013032004.png)
![](http://image.beekka.com/blog/201303/bg2013032003.png)
假定a向量是[x1, y1],b向量是[x2, y2],那么可以将余弦定理改写成下面的形式:
![](http://image.beekka.com/blog/201303/bg2013032006.png)
![](http://image.beekka.com/blog/201303/bg2013032005.png)
数学家已经证明,余弦的这种计算方法对n维向量也成立。假定A和B是两个n维向量,A是 [A1, A2, ..., An] ,B是 [B1, B2, ..., Bn] ,则A与B的夹角θ的余弦等于:
![](http://image.beekka.com/blog/201303/bg2013032007.png)
使用这个公式,我们就可以得到,句子A与句子B的夹角的余弦。
![](http://image.beekka.com/blog/201303/bg2013032008.png)
余弦值越接近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),'°']);
%完
下面为实验所用图片和效果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/06/e858c68021941e96f992aefa3538e950)
school1.jpg
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/06/2e8a05ad94b9abf819981fd8bf0ff21d)
school2.jpg
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/06/bc4dc87f574fa4e012bd0d1f849672ef)
school1.jpg直方图分布
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/06/40977705fcab41c5c4aff451edb2587f)
school2.jpg直方图分布
每张图片都可以生成其灰度图像直方图(histogram)。如果两张图片的直方图很接近,就可以认为它们很相似。
因此,此处我们利用两幅图像的直方图来进行相似度的比较。原理较为简单,具体算法如下:
1、获得输入灰度图像的直方图分布;
2、将直方图划分为64个区,每个区为连续的4个灰度等级;
3、对每个区的4个值进行求和运算,得到1个数据,如此,会得到64个数据,即为该幅图像的一个向量(指纹);
4、根据步骤【1、2、3】,我们将输入的两幅图像转化为了2个向量,记为A、B;
5、计算两个向量的相似度,可以用皮尔逊相关系数或者余弦相似度计算,这里我们采用【余弦相似度】;
下面就顺便介绍一下余弦相似度的概念及用法:
对于两个向量,我们可以把它们想象成空间中的两条线段,都是从原点([0,
0, ...])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。
![](http://image.beekka.com/blog/201303/bg2013032002.png)
以二维空间为例,上图的a和b是两个向量,我们要计算它们的夹角θ。余弦定理告诉我们,可以用下面的公式求得:
![](http://image.beekka.com/blog/201303/bg2013032004.png)
![](http://image.beekka.com/blog/201303/bg2013032003.png)
假定a向量是[x1, y1],b向量是[x2, y2],那么可以将余弦定理改写成下面的形式:
![](http://image.beekka.com/blog/201303/bg2013032006.png)
![](http://image.beekka.com/blog/201303/bg2013032005.png)
数学家已经证明,余弦的这种计算方法对n维向量也成立。假定A和B是两个n维向量,A是 [A1, A2, ..., An] ,B是 [B1, B2, ..., Bn] ,则A与B的夹角θ的余弦等于:
![](http://image.beekka.com/blog/201303/bg2013032007.png)
使用这个公式,我们就可以得到,句子A与句子B的夹角的余弦。
![](http://image.beekka.com/blog/201303/bg2013032008.png)
余弦值越接近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),'°']);
%完
下面为实验所用图片和效果:
school1.jpg
school2.jpg
school1.jpg直方图分布
school2.jpg直方图分布
相关文章推荐
- Isight软件调用matlab
- 使用 matlab 数字图像处理(十)—— 维纳滤波复原
- MATLAB基础2
- matlab 复矩阵共轭
- 使用 matlab 数字图像处理(九)—— 去卷积(deconvolution,逆滤波复原)
- Matlab函数重载_变参数个数
- Differences between Octave and MATLAB
- Matlab隐函数求导作图
- 【机器学习】Matlab中实现QQ-plot的一个好工具gqqplot
- 【matlab】:matlab实现对一个图片进行平移
- 使用 matlab 数字图像处理(八)—— 画圆
- 【matlab】:matlab如何实现计算三个点组成的角的角度值
- 基于MATLAB的QPSK通信系统
- 機器學習基石(Machine Learning Foundations) 机器学习基石 作业四 Q13-20 MATLAB实现
- 使用 matlab 数字图像处理(七)—— 频率域处理
- 用matlab实现感知机学习算法,训练分类器并解决井字游戏
- 使用 matlab 数字图像处理(六)—— 空域滤波
- 使用 matlab 数字图像处理(五)—— 双线性插值(Bilinear Interpolation)
- 使用 matlab 数字图像处理(三)—— 实现图像的旋转(不使用 imrotate)
- C# matlab混合编程