自己琢磨的 图像相似度算法 JAVA版实现

本文介绍了作者通过自学和搜索引擎,实现了一个简单的图像相似度计算的Java程序。主要步骤包括图像二值化、提取黑色矩形阵列、矩阵排序及对比,以计算两张图像的相似度。由于作者对图像学没有深入研究,提供的代码可能存在错误,适合学习交流,不适合直接用于生产环境。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     最近有个项目里要整理缩略图和原图是否匹配,然后就去找工具和方法做了,之后很好奇图像相似度是怎么算的,google了下貌似很深奥,而且无最简单的例子java代码源码下载,估计图形学的人不削用java吧。      

     个人从来没有研究过图像学,也没看过什么论文或者相关文档,写这个完全是靠google和百度,自己写了个实验了下,测试用例也少,估计有大BUG的存在,所以看的人权当学习交流,切勿生产使用。


     思路:

      1,二值化,(不做颜色比对了,生成黑白图)

      2 ,取黑色的矩形阵列,(不管图片大小,只取同颜色的矩形区域,判断规则下文讲)

      3,排序取前几个矩阵,(去最大矩阵的 %d 面积以上的矩阵,%d作为参数)。

      4,取得2张图的矩阵,对比矩阵距离面积等,根据面积权重,得到相似度。

  


如这么图取的矩阵就是红色区域,没画全。


   

好了,开始了,下面的代码要是有人发现问题PM我,我去改正:

     1,二值化:

package cn.my.image.Compare.test;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

public class Binarization {
	private static float RP = 0.333f;
	private static float GP = 0.334f;
	private static float BP = 0.333f;
	private static int Threshold = 0;
	private int h;
	private int w;
	public Binarization(){
		
	}
	/**
	 * set your threshold such as 160  这里手工设判断黑白的标准,默认是图像全局的平均值。
	 * @param threshold
	 */
	public Binarization(int threshold){
		Threshold = threshold;
	}
	/**
	 * init with r,g,b Proportion  设置R G B的权重比,默认平分
	 * @param r
	 * @param g
	 * @param b
	 */
	public Binarization(float r,float g,float b,int threshold){
		RP = r;
		GP = g;
		BP = b;
		Threshold = threshold;
	}
	public int getH(){
		return h;
	}
	public int getW() {
		return w;
	}
	public int getArea(){
		return w*h;
	}
	
	public int[][] toBinarization(InputStream stream) throws IOException {
		BufferedImage bi=ImageIO.read(stream);//input image
		h=bi.getHeight();//get height
		w=bi.getWidth();//get width
		int sumRGB = 0;
		int[][] gray=new int[w][h];
		for (int x = 0; x < w; x++) {
			for (int y = 0; y < h; y++) {
				gray[x][y]=getGray(bi.getRGB(x, y));
				sumRGB = sumRGB + gray[x][y];
			}
		}
		if(Threshold ==0){
			Threshold = sumRGB/(h*w); //threshold by avager
		}
		int[][] binary=new int[w][h];
		
		for (int x = 0; x < w; x++) {
			for (int y = 0; y
预处理:读取图片 第一步,缩小尺寸。 将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。 第二步,简化色彩。 将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。 第三步,计平均值。 计所有64个像素的灰度平均值。 第四步,比较像素的灰度。 将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。 第五步,计哈希值。 将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。 得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计"汉明距离"(Hammingdistance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。 你可以将几张图片放在一起,也计出他们的汉明距离对比,就可以看看两张图片是否相似。 这种算法的优点是简单快速,不受图片大小缩放的影响,缺点是图片的内容不能变更。如果在图片上加几个文字,它就认不出来了。所以,它的最佳用途是根据缩略图,找出原图。 实际应用中,往往采用更强大的pHash算法和SIFT算法,它们能够识别图片的变形。只要变形程度不超过25%,它们就能匹配原图。这些算法虽然更复杂,但是原理与上面的简便算法是一样的,就是先将图片转化成Hash字符串,然后再进行比较。 以上内容大部分直接从阮一峰的网站上复制过来,想看原著的童鞋可以去在最上面的链接点击进去看。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值