qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

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

 笔主利用这个七夕前后两天的寂寞时光,用JAVA磨了一个简单的图像相似度计算小程序,就在刚才终于纠结完毕,输出了1.0版本,小小的满足了一下可怜的虚荣心..
  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部分的代码就不公开了,成品下载地址如下(使用JDK1.5):
  http://download.csdn.net/detail/u011088871/7711833
  解压后打开 run.bat 批处理文件就可以跑起来了 :)

posted on 2014-08-11 09:59 顺其自然EVO 阅读(259) 评论(0)  编辑  收藏 所属分类: 测试学习专栏


只有注册用户登录后才能发表评论。


网站导航:
 
<2014年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜