简单说两句:

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

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

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

UI设计图:

实际运行效果图:

关键算法:

 // 全流程
public static void main(String[] args) throws IOException {
// 获取图像
File imageFile = new File("c:/1.jpg");
Image image = ImageIO.read(imageFile);
// 转换至灰度
image = toGrayscale(image);
// 缩小成32x32的缩略图
image = scale(image);
// 获取灰度像素数组
int[] pixels = getPixels(image);
// 获取平均灰度颜色
int averageColor = getAverageOfPixelArray(pixels);
// 获取灰度像素的比较数组(即图像指纹序列)
pixels = getPixelDeviateWeightsArray(pixels, averageColor);
// 获取两个图的汉明距离(假设另一个图也已经按上面步骤得到灰度比较数组)
int hammingDistance = getHammingDistance(pixels, pixels);
// 通过汉明距离计算相似度,取值范围 [0.0, 1.0]
double similarity = calSimilarity(hammingDistance);
} // 将任意Image类型图像转换为BufferedImage类型,方便后续操作
public static BufferedImage convertToBufferedFrom(Image srcImage) {
BufferedImage bufferedImage = new BufferedImage(srcImage.getWidth(null),
srcImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bufferedImage.createGraphics();
g.drawImage(srcImage, null, null);
g.dispose();
return bufferedImage;
} // 转换至灰度图
public static BufferedImage toGrayscale(Image image) {
BufferedImage sourceBuffered = convertToBufferedFrom(image);
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(cs, null);
BufferedImage grayBuffered = op.filter(sourceBuffered, null);
return grayBuffered;
} // 缩放至32x32像素缩略图
public static Image scale(Image image) {
image = image.getScaledInstance(32, 32, Image.SCALE_SMOOTH);
return image;
} // 获取像素数组
public static int[] getPixels(Image image) {
int width = image.getWidth(null);
int height = image.getHeight(null);
int[] pixels = convertToBufferedFrom(image).getRGB(0, 0, width, height,
null, 0, width);
return pixels;
} // 获取灰度图的平均像素颜色值
public static int getAverageOfPixelArray(int[] pixels) {
Color color;
long sumRed = 0;
for (int i = 0; i < pixels.length; i++) {
color = new Color(pixels[i], true);
sumRed += color.getRed();
}
int averageRed = (int) (sumRed / pixels.length);
return averageRed;
} // 获取灰度图的像素比较数组(平均值的离差)
public static int[] getPixelDeviateWeightsArray(int[] pixels,final int averageColor) {
Color color;
int[] dest = new int[pixels.length];
for (int i = 0; i < pixels.length; i++) {
color = new Color(pixels[i], true);
dest[i] = color.getRed() - averageColor > 0 ? 1 : 0;
}
return dest;
} // 获取两个缩略图的平均像素比较数组的汉明距离(距离越大差异越大)
public static int getHammingDistance(int[] a, int[] b) {
int sum = 0;
for (int i = 0; i < a.length; i++) {
sum += a[i] == b[i] ? 0 : 1;
}
return sum;
} // 通过汉明距离计算相似度
public static double calSimilarity(int hammingDistance){
int length = 32*32;
double similarity = (length - hammingDistance) / (double) length; // 使用指数曲线调整相似度结果
similarity = java.lang.Math.pow(similarity, 2);
return similarity;
}

UI部分的代码就不公开了,成品下载地址如下(使用JDK1.5):

http://download.csdn.net/detail/u011088871/7711833

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

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

  1. 如何使用Java AWT 创建一个简易计算器

    摘要:手把手教你使用 Java AWT 创建一个简易计算器. 本文分享自华为云社区<手把手教你使用 Java AWT 创建一个简易计算器>,作者:海拥 . 关于AWT AWT (抽象窗口工 ...

  2. 做了一个简易的git 代码自动部署脚本

    做了一个简易的git 代码自动部署脚本 http://my.oschina.net/caomenglong/blog/472665 发表于2个月前(2015-06-30 21:08)   阅读(200 ...

  3. Java做acm所需要的基础知识之排序问题

    Java做acm所需要的基础知识. 以前做acm的题都是用C/C++来写代码的,在学习完Java之后突然感觉Java中的方法比C/C++丰富很多,所以就整理一下平时做题需要用到的Java基础知识. 1 ...

  4. Java图形界面学习---------简易登录界面

    /** * @author Administrator * Java图形界面学习---------简易登录界面 * date:2015/10/31 */ import java.awt.BorderL ...

  5. ajax实现用户登陆,退出,java做后端

    最近http老师布置了个任务,用cookie完成登陆,退出.Http老师讲的是node.js写后端,由于自己还是擅长java些,还是用Java做了. 以前跟着教程写过一个网站,当初是用jsp+serv ...

  6. 使用Java类库POI生成简易的Excel报表

    使用Java类库POI生成简易的Excel报表 1.需求 1.数据库生成报表需要转义其中字段的信息.比如 1,有效 2.无效等 2.日期格式的自数据需要转义其格式. 3.标题的格式和数据的格式需要分别 ...

  7. java做web项目比较多

    WEB就是轻量级:如果要炫,FLEX或即将普及的html5.0都能做到像C/S那样. java做web项目比较多:如果是桌面程序,还是走C/S比较成熟. 如果是B/S架构的,后台还是JAVA,前台可以 ...

  8. 使用java做paypal开发时购买东西支付不成功的原因

    使用java做paypal开发时购买东西支付不成功的原因 没有设置网站习惯设定,登陆自己的paypal账户,在网站习惯设定上填写回调的url路径,这样就可以 支付成功了并且异步修改订单的状态. 支付成 ...

  9. 【转】Java做服务器开发语言

    版权声明:本文为博主原创文章,未经博主允许不得转载. 随着游戏市场的兴起,特别是网页游戏.手机游戏的崛起,对游戏开发技术的需求越来越多.网络游戏开发是一个庞大的体系,总体来说是客户端与服务器端.客户端 ...

随机推荐

  1. css文本截字,超出文本省略号显示

    一.单行文本截字 p { text-overflow: ellipsis;/*显示省略号代替裁剪的文本*/ white-space: nowrap;/*空白处理方式 不换行*/ overflow: h ...

  2. Linux编译移植Qt5的环境_OMAPL138平台

    Linux编译移植Qt5_OMAPL138 [导语]:昨天编译Qt5各种失败,各种离奇的错误在Google上面也搜索不到,真是让人"蛋疼菊紧",今天把所有的环境全部清理干净,也重新 ...

  3. django中的ContentType使用

    使用背景 最近设计表的时候遇到一个问题,有两门课程  一门专业课,一门学位课,我们按照时间长度来进行售卖,比如专业课一个月19元,两个月35元,三个月50元. 可以这么做但是领导不让我这么设计.... ...

  4. 9-C++远征之多态篇-学习笔记

    C++远征之多态篇 面向对象三大特征:封装,继承,多态 多态: 发出一条命令时,不同的对象接收到同样的命令做出的动作不同 多态篇会学习到的目录: 普通虚函数 & 虚析构函数 纯虚函数:抽象类 ...

  5. 学习RUNOOB.COM进度一

    了解MongoDB 由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能. 特点 面向文档,操作简单容易 设置任何索引,实现更快排序 本地 ...

  6. 配置vue-yarm-PM2工具环境

    步骤: 第一步:安装yarn 参考网址:https://yarn.bootcss.com/docs/install.html#linux-tab a.用pm2启动已创建的server.js   #pm ...

  7. Python3爬虫(十一) 爬虫与反爬虫

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.重要概念 二.爬虫反爬虫进化论

  8. python中判断输入是否为数字(包括浮点数)

    1.当num确定为数字后 num=123.4print(isinstance(num,float))#判断是否为浮点数 print(isinstance(num,int))#判断是否为整数 2.当nu ...

  9. [网站公告]18:07-18:20阿里云SLB故障造成网站不能正常访问

    (注:由于阿里云SLB管理控制台监控数据不准,实际故障时间是18:07-18:20.) 17:55-18:2018:07-18:20,我们使用的阿里云SLB(负载均衡)中有3台出现突发故障,造成全站无 ...

  10. session、token、cookie的区别

    token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件cookie就是写在客户端的一个txt文件,里面包括你登录信息之类的,这样你下次在登录某个网站,就会自动调用co ...