简单说两句:

笔主利用这个七夕前后两天的寂寞时光,用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 批处理文件就可以跑起来了 :)

最新文章

  1. iOS开发——高级技术&amp;本地化与国际化详解
  2. aix磁盘分区挂载问题
  3. iOS证书失效
  4. PG_RMAN备份遇到 domain socket
  5. [Hibernate] - Study test project
  6. sql2000
  7. UnitOfWork实战
  8. asp.net core mvc剖析:启动流程
  9. js零碎整理
  10. Linux SvN操作
  11. Java I/O---序列化接口Serializable
  12. HDU - 2102 A计划 (BFS) [kuangbin带你飞]专题二
  13. ANI功能分析
  14. 深入解析Java反射基础
  15. CRLF在过滤XSS语句后打Cookie方式
  16. 使用Spark进行搜狗日志分析实例——map join的使用
  17. postgresql-无序uuid tps测试
  18. 字母算术的python算法
  19. mysql 和 sqlserver中备份一张表的区别
  20. http://www.liangxiansen.cn/2017/04/06/consul/

热门文章

  1. 当安装mongodb客户端出现了Failed to load list of databases
  2. Go生成UUID
  3. python2.7练习小例子(二十一)
  4. easyui 验证动态添加和删除问题
  5. 【APUE】Chapter15 Interprocess Communication
  6. 微信营销 推广 会议签到 活动签到 复用微信3D动画签到系统
  7. 2.Linux文件和目录
  8. Git 上传本地仓库到码云
  9. 虚拟现实-VR-UE4-创建一个自定义的角色 Character
  10. CCF-NOIP-2018 提高组(复赛) 模拟试题(五)