zoukankan      html  css  js  c++  java
  • 我用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部分的代码就不公开了,成品下载地址如下(使用JDK1.5):

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

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

  • 相关阅读:
    CC3200作为STA模式连接路由器sl_WlanConnect出现exception occured at:0xa72fcf6
    HI2115软件开发板V150版本AT+NSOST指令
    利尔达NB-IOT模块对接移动onenet平台步骤
    ip4addr_ntoa和不可重入函数
    VHDL入门学习-程序组成
    nexys4-DDR开发板温度传感器ADT7420U
    2016-2017股票亏损反省
    一起来学linux:例行性任务之at和crontab
    linux c编程:进程间通信
    一起来学linux:sudo
  • 原文地址:https://www.cnblogs.com/wavky/p/3888903.html
Copyright © 2011-2022 走看看