计算两张黑白图片的相似度
2010-01-20 11:33
260 查看
如果有两张分辨率为32x32的黑白图片,要计算这两张图片的相似度该怎么办?
根据这篇文章《数学之美 系列 12 - 余弦定理和新闻的分类》的介绍,我们只需要计算一下两个1024位(32x32=1024)的向量之间的夹角的余弦即可,结果越接近于1,相似度就越高。
好了,理论基础有了,下面说怎么存储我们的向量。
因为图片上只有两种颜色,所以用1位二进制足以表示。那就认为白色的点为0,黑色的点为1。这样,我们每一张图片就可以放在32个32位整数里,每行用一个整数表示,既节省了空间,又降低了操作时的复杂度。
接下来说如何计算。
如果老老实实的按照以下公式进行计算,我们需要取出整数中相应位的值,然后相乘或者分别平方,显然这种方法很浪费时间。
代码
public double GetCosine(int[] e1, int[] e2)
{
int a = 0;//分母1
int b = 0;//分母2
int c = 0;//分子
for (int y = 0; y < 32; ++y)
{
//两个数组中的整数按位与
int i = e2[y] & e1[y];
//按位加
for (int x = 1; x < 33; ++x)
{
c += (i >> x) & 1;
a += (e2[y] >> x) & 1;
b += (e1[y] >> x) & 1;
}
}
//计算分母
int d = a * b;
return d == 0 ? 0 : c / Math.Sqrt(d);
}
如果看到了这里,你已经知道了我们该如何计算两个图片的相似度,按我的经验,计算结果超过0.8,就可以认为这两个图片一样了。
如果把这里的图片换成验证码,而你碰巧已经知道其中一个验证码的值,那么另外一个验证码的值你现在也知道了。
根据这篇文章《数学之美 系列 12 - 余弦定理和新闻的分类》的介绍,我们只需要计算一下两个1024位(32x32=1024)的向量之间的夹角的余弦即可,结果越接近于1,相似度就越高。
好了,理论基础有了,下面说怎么存储我们的向量。
因为图片上只有两种颜色,所以用1位二进制足以表示。那就认为白色的点为0,黑色的点为1。这样,我们每一张图片就可以放在32个32位整数里,每行用一个整数表示,既节省了空间,又降低了操作时的复杂度。
接下来说如何计算。
如果老老实实的按照以下公式进行计算,我们需要取出整数中相应位的值,然后相乘或者分别平方,显然这种方法很浪费时间。
代码
public double GetCosine(int[] e1, int[] e2)
{
int a = 0;//分母1
int b = 0;//分母2
int c = 0;//分子
for (int y = 0; y < 32; ++y)
{
//两个数组中的整数按位与
int i = e2[y] & e1[y];
//按位加
for (int x = 1; x < 33; ++x)
{
c += (i >> x) & 1;
a += (e2[y] >> x) & 1;
b += (e1[y] >> x) & 1;
}
}
//计算分母
int d = a * b;
return d == 0 ? 0 : c / Math.Sqrt(d);
}
如果看到了这里,你已经知道了我们该如何计算两个图片的相似度,按我的经验,计算结果超过0.8,就可以认为这两个图片一样了。
如果把这里的图片换成验证码,而你碰巧已经知道其中一个验证码的值,那么另外一个验证码的值你现在也知道了。
相关文章推荐
- 【matlab】:matlab实现计算两张图片的相似度
- 利用空间距离比较两张图片颜色的相似度
- JAVA 比较两张图片的相似度的代码
- OpenCV学习二十四:基于直方图的图片相似度计算函数 compareHist
- JAVA 比较两张图片的相似度的代码(未测试)
- 比较两张图片的相似度-python
- JAVA 比较两张图片的相似度
- opencv 判断两张图片的相似度
- 两张图片相似度比较
- 转:OpenCV学习笔记3:找出人脸,同时比较两张图片中的人脸相似度
- JAVA 比较两张图片的相似度的代码
- Java 比较两张图片的相似度
- OpenCV学习笔记3:找出人脸,同时比较两张图片中的人脸相似度
- java--比较两张图片的相似度
- JAVA 比较两张图片的相似度
- JAVA 比较两张图片的相似度
- 利用颜色直方图计算8张图片的相似度,并按相似度的高低依次显示出图片
- Java根据像素比较两张图片的相似度
- 如何实现“比较两张图片的相似度”,或者说“比较两张图片是否基本一致”的算法?
- OpenCV学习:找出人脸,同时比较两张图片中的人脸相似度