我用JAVA做了个简易图像相似度计算器

简单说两句:

笔主利用这个七夕前后两天的寂寞时光,用JAVA磨了一个简单的图像相似度计算小程序,就在刚才终于纠结完毕,输出了1.0版本,小小的满足了一下可怜的虚荣心..→_→

原理是使用最简单最基础的感知哈希算法,算法原理戳这里,绝对比笔主讲的要好:

http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html

UI设计图:

实际运行效果图:

关键算法:

 1 // 全流程
 2 public static void main(String[] args) throws IOException {
 3     // 获取图像
 4     File imageFile = new File("c:/1.jpg");
 5     Image image = ImageIO.read(imageFile);
 6     // 转换至灰度
 7     image = toGrayscale(image);
 8     // 缩小成32x32的缩略图
 9     image = scale(image);
10     // 获取灰度像素数组
11     int[] pixels = getPixels(image);
12     // 获取平均灰度颜色
13     int averageColor = getAverageOfPixelArray(pixels);
14     // 获取灰度像素的比较数组(即图像指纹序列)
15     pixels = getPixelDeviateWeightsArray(pixels, averageColor);
16     // 获取两个图的汉明距离(假设另一个图也已经按上面步骤得到灰度比较数组)
17     int hammingDistance = getHammingDistance(pixels, pixels);
18     // 通过汉明距离计算相似度,取值范围 [0.0, 1.0]
19     double similarity = calSimilarity(hammingDistance);
20 }
21
22 // 将任意Image类型图像转换为BufferedImage类型,方便后续操作
23 public static BufferedImage convertToBufferedFrom(Image srcImage) {
24     BufferedImage bufferedImage = new BufferedImage(srcImage.getWidth(null),
25             srcImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);
26     Graphics2D g = bufferedImage.createGraphics();
27     g.drawImage(srcImage, null, null);
28     g.dispose();
29     return bufferedImage;
30 }
31
32 // 转换至灰度图
33 public static BufferedImage toGrayscale(Image image) {
34     BufferedImage sourceBuffered = convertToBufferedFrom(image);
35     ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
36     ColorConvertOp op = new ColorConvertOp(cs, null);
37     BufferedImage grayBuffered = op.filter(sourceBuffered, null);
38     return grayBuffered;
39 }
40
41 // 缩放至32x32像素缩略图
42 public static Image scale(Image image) {
43     image = image.getScaledInstance(32, 32, Image.SCALE_SMOOTH);
44     return image;
45 }
46
47 // 获取像素数组
48 public static int[] getPixels(Image image) {
49     int width = image.getWidth(null);
50     int height = image.getHeight(null);
51     int[] pixels = convertToBufferedFrom(image).getRGB(0, 0, width, height,
52             null, 0, width);
53     return pixels;
54 }
55
56 // 获取灰度图的平均像素颜色值
57 public static int getAverageOfPixelArray(int[] pixels) {
58     Color color;
59     long sumRed = 0;
60     for (int i = 0; i < pixels.length; i++) {
61         color = new Color(pixels[i], true);
62         sumRed += color.getRed();
63     }
64     int averageRed = (int) (sumRed / pixels.length);
65     return averageRed;
66 }
67
68 // 获取灰度图的像素比较数组(平均值的离差)
69 public static int[] getPixelDeviateWeightsArray(int[] pixels,final int averageColor) {
70     Color color;
71     int[] dest = new int[pixels.length];
72     for (int i = 0; i < pixels.length; i++) {
73         color = new Color(pixels[i], true);
74         dest[i] = color.getRed() - averageColor > 0 ? 1 : 0;
75     }
76     return dest;
77 }
78
79 // 获取两个缩略图的平均像素比较数组的汉明距离(距离越大差异越大)
80 public static int getHammingDistance(int[] a, int[] b) {
81     int sum = 0;
82     for (int i = 0; i < a.length; i++) {
83         sum += a[i] == b[i] ? 0 : 1;
84     }
85     return sum;
86 }
87
88 // 通过汉明距离计算相似度
89 public static double calSimilarity(int hammingDistance){
90     int length = 32*32;
91     double similarity = (length - hammingDistance) / (double) length;
92
93     // 使用指数曲线调整相似度结果
94     similarity = java.lang.Math.pow(similarity, 2);
95     return similarity;
96 }

UI部分的代码就不公开了,成品下载地址如下:

等候审批中,稍后提供..T T

解压后打开 run.bat 批处理文件就可以跑起来了 :)

我用JAVA做了个简易图像相似度计算器,布布扣,bubuko.com

时间: 2024-10-05 04:58:13

我用JAVA做了个简易图像相似度计算器的相关文章

java做的一个简易的微信签到系统

1.发送签到会提示你签到成功,并获得2积分 2.一天只能签到一次 3.连续一星期签到会额外送12个积分 4.可以查询你当前积分总数 效果图:本订阅好还在完善中,可能还不能用,不久后将会一步步完善功能,用于生活,到时欢迎大家关注"z植物空间z"订阅号, 部分代码: // 保存用户信息 public static void saveWeixinUser(String openId) { MySQLUtil mysql = new MySQLUtil(); Connection conn =

java swing开发最简易计算器源代码

原文:java swing开发最简易计算器源代码 源代码下载地址:http://www.zuidaima.com/share/1550463496948736.htm 用java swing写的简易计算器 /** *@author www.zuidaima.com */ package com.zuidaima.swing; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; i

java做题笔记

java做题笔记 初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 3.其次,初始化父类的普通成员变量和代码块,在执行父类的构造方法: 4.最后,初始化子类的普通成员变量和代码块,在执行子类的构造方法: (1)初始化父类的普通成员变量和代码块,执行 C c = new C(); 输出C (2)super("B"); 表示调用父类的构造方法,不调用父类的

java做的二维码客户端

原文:java做的二维码客户端 源代码下载地址:http://www.zuidaima.com/share/1550463611882496.htm 暂时不支持中文,我以前没发现

java做的比较完善的FTP上传下载文件服务器源码

Filename: ftp.java Author: leetsing(elove) Create date: 2004-08-30 Use: connect to FTP server,then upload and download file Modify date: 2004-09-05 add to upload file 2004-09-13 add to download file Copy right: Magisky Media Technology Co.,Ltd. *****

教你用java做个微信红包,自己做运气王!

java微信红包 微信是如今人们日常生活离不开的app,日常交流,小额转账,视频通话等都很方便.微信红包也是人们使用得最多的功能,朋友一起出去吃个饭,饭后AA用微信红包:逢年过节,给亲朋好友发个红包--这篇文章教你用java做个红包小项目!注意事项因为金额涉及到分,小数点后保留两位,数值类型的转换操作需要注意:此中方案相对简陋,并未实现每次红包最大值在0.01-剩余红包均值的2倍间:/* 红包设计要求: 1-红包最小值为0.01,最大值为200 2-红包的金额面值为小数点后两位 3-避免单个红包

深入学习图像处理——图像相似度算法

最近一段时间学习并做的都是对图像进行处理,其实自己也是新手,各种尝试,所以我这个门外汉想总结一下自己学习的东西,图像处理的流程.但是动起笔来想总结,一下却不知道自己要写什么,那就把自己做过的相似图片搜索的流程整理一下,想到什么说什么吧. 首先在进行图片灰度化处理之前,我觉得有必要了解一下为什么要进行灰度化处理. 图像灰度化的目的是什么? 将彩色图像转化为灰度图像的过程是图像的灰度化处理.彩色图像中的每个像素的颜色由R,G,B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多

图像相似度计算

http://blog.sina.com.cn/s/blog_4a540be60100vjae.html 图像相似度计算 (2011-12-13 22:16:23) 转载▼ 标签: 图像 相似 svd nmf 巴氏距离 直方图距离 图像哈希 图像校正 图像内容检索 分类: 计算机视觉 图像相似度计算主要用于对于两幅图像之间内容的相似程度进行打分,根据分数的高低来判断图像内容的相近程度. 可以用于计算机视觉中的检测跟踪中目标位置的获取,根据已有模板在图像中找到一个与之最接近的区域.然后一直跟着.已

OpenCV进行图像相似度对比的几种办法

对计算图像相似度的方法,本文做了如下总结,主要有三种办法: 1.PSNR(Peak Signal to Noise Ratio)峰值信噪比,一种全参考的图像质量评价指标. 简介: http://www.cnblogs.com/vincent2012/archive/2012/10/13/2723152.html PSNR是最普遍和使用最为广泛的一种图像客观评价指标,然而它是基于对应像素点间的误差,即基于误差敏感的图像质量评价.由于并未考虑到人眼的视觉特性(人眼对空间频率较低的对比差异敏感度较高,