精华内容
下载资源
问答
  • 基于JAVA图片相似度比对 效果演示: 这里写目录标题所需软件算法介绍工程讲解 所需软件 算法介绍 工程讲解

    前言

    一、工程简介

    基于Java的图片相似度对比,有前台页面,后台算法

    二、适用场景

    图像处理实习

    三、所用软件

    此次工程,所用软件图片所示:在这里插入图片描述

    四、工程介绍

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • import java.text.DecimalFormat; import android.R.integer; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import...
    package com.example.gameai.ui;
    
    import  java.text.DecimalFormat;
    
    import  android.R.integer;
    import android.content.res.Resources;
    import  android.graphics.Bitmap;
    import  android.graphics.BitmapFactory;
    import android.util.Log;
    
    import com.example.gameai.R;
    
    /**
     * Android图片对比(像素精准对比),速度较慢建议用多线程获取
     * @author xupp
     * @createData 2013-7-18
     */
    
    import java.text.DecimalFormat;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    
    public class PictureContrast
    {
        private static final String DIFFERENT_SIZE = "differentSize";
        private static final String RESULT_FORMAT = "00.0%";
    
        public static String similarity(Resources resources) {
            Bitmap bm1 = BitmapFactory.decodeResource(resources, R.drawable.ew);
            Bitmap bm2 = BitmapFactory.decodeResource(resources, R.drawable.ww);
            return similarity(bm1, bm2);
        }
    
        public static String similarity(Bitmap bm1, Bitmap bm2) {
            final int bm1Width = bm1.getWidth();
            final int bm2Width = bm2.getWidth();
            final int bmHeight = bm1.getHeight();
            int[] pixels1 = new int[bm1Width];
            int[] pixels2 = new int[bm2Width];
    
            if (bmHeight != bm2.getHeight() || bm1Width != bm2Width){
                return DIFFERENT_SIZE;
            }
    
            Log.i("1", "s: "+bm1);
    
            reset();
            for (int i = 0; i < bmHeight; i++) {
                bm1.getPixels(pixels1, 0, bm1Width, 0, i, bm1Width, 1);
                bm2.getPixels(pixels2, 0, bm2Width, 0, i, bm2Width, 1);
    
    
                comparePixels(pixels1, pixels2, bm1Width);
            }
    
            return percent(Count.sT, Count.sF + Count.sT);
        }
    
        private static void comparePixels(int[] pixels1, int[] pixels2, int length) {
            for (int i = 0; i < length; i++) {
                if (pixels1[i] == pixels2[i]) {
                    Count.sT++;
                } else {
                    Count.sF++;
                }
            }
        }
    
        private static String percent(int divisor, int dividend) {
            final double value = divisor * 1.0 / dividend;
            DecimalFormat df = new DecimalFormat(RESULT_FORMAT);
            Log.i("1", "!!!!!!!!!!: "+df.format(value));
            return df.format(value);
        }
    
        private static void reset() {
            Count.sT = 0;
            Count.sF = 0;
        }
    
    
    
        private static class Count {
            private static int sT;
            private static int sF;
        }
    }

     

    展开全文
  • java 识别图片相似度图片是否相同

    万次阅读 2017-09-04 11:12:44
    1.比较MD5值 判断图片是否相同 package com.zerdoor.util; import java.io.File; import java.io.FileInputStream; import java.math.BigInteger; import java.security.MessageDigest; import java.util....
    1.比较MD5值 判断图片是否相同
    package com.zerdoor.util;

    import java.io.File;
    import java.io.FileInputStream;
    import java.math.BigInteger;
    import java.security.MessageDigest;
    import java.util.HashMap;
    import java.util.Map;
    public class FileDigest {
    /**
    * 获取单个文件的MD5值!
    * @param file
    * @return
    */
    public static String getFileMD5(File file) {
    if (!file.isFile()){
    return null;
    }
    MessageDigest digest = null;
    FileInputStream in=null;
    byte buffer[] = new byte[1024];
    int len;
    try {
    digest = MessageDigest.getInstance("MD5");
    in = new FileInputStream(file);
    while ((len = in.read(buffer, 0, 1024)) != -1) {
    digest.update(buffer, 0, len);
    }
    in.close();
    } catch (Exception e) {
    e.printStackTrace();
    return null;
    }
    BigInteger bigInt = new BigInteger(1, digest.digest());
    return bigInt.toString(16);
    }
    /**
    * 获取文件夹中文件的MD5值
    * @param file
    * @param listChild ;true递归子目录中的文件
    * @return
    */
    public static Map<String, String> getDirMD5(File file,boolean listChild) {
    if(!file.isDirectory()){
    return null;
    }
    //<filepath,md5>
    Map<String, String> map=new HashMap<String, String>();
    String md5;
    File files[]=file.listFiles();
    for(int i=0;i<files.length;i++){
    File f=files[i];
    if(f.isDirectory()&&listChild){
    map.putAll(getDirMD5(f, listChild));
    } else {
    md5=getFileMD5(f);
    if(md5!=null){
    map.put(f.getPath(), md5);
    }
    }
    }
    return map;
    }
    public static void main(String[] args) {
    File file1 = new File("F:\\workspace_acg\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\acgweb\\uploads\\task\\1495872495006.jpg");
    String s = file1.getPath();
    File file2 = new File("F:\\workspace_acg\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\acgweb\\uploads\\task\\1\\20170527\\1495872475363.jpg");
    System.out.println(getFileMD5(file1).equals(getFileMD5(file2)));
    System.out.println(s);
    }
    }
    2.比较每一个的图片的像素相似度(效率较低)
    package com.zerdoor.util;

    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;

    import java.io.File;

    public class CompareImg {
    // 改变成二进制码
    public static String[][] getPX(String args) {
    int[] rgb = new int[3];
    File file = new File(args);
    BufferedImage bi = null;
    try {
    bi = ImageIO.read(file);
    } catch (Exception e) {
    e.printStackTrace();
    }
    int width = bi.getWidth();
    int height = bi.getHeight();
    int minx = bi.getMinX();
    int miny = bi.getMinY();
    String[][] list = new String[width][height];
    for (int i = minx; i < width; i++) {
    for (int j = miny; j < height; j++) {
    int pixel = bi.getRGB(i, j);
    rgb[0] = (pixel & 0xff0000) >> 16;
    rgb[1] = (pixel & 0xff00) >> 8;
    rgb[2] = (pixel & 0xff);
    list[i][j] = rgb[0] + "," + rgb[1] + "," + rgb[2];
    }
    }
    return list;
    }

    public static int compareImage(String imgPath1, String imgPath2) {
    String[] images = { imgPath1, imgPath2 };
    if (images.length == 0) {
    System.out.println("Usage >java BMPLoader ImageFile.bmp");
    System.exit(0);
    }
    // 分析图片相似度 begin
    String[][] list1 = getPX(images[0]);
    String[][] list2 = getPX(images[1]);
    int xiangsi = 0;
    int busi = 0;
    int i = 0, j = 0;
    for (String[] strings : list1) {
    if ((i + 1) == list1.length) {
    continue;
    }
    for (int m = 0; m < strings.length; m++) {
    try {
    String[] value1 = list1[i][j].toString().split(",");
    String[] value2 = list2[i][j].toString().split(",");
    int k = 0;
    for (int n = 0; n < value2.length; n++) {
    if (Math.abs(Integer.parseInt(value1[k]) - Integer.parseInt(value2[k])) < 5) {
    xiangsi++;
    } else {
    busi++;
    }
    }
    } catch (RuntimeException e) {
    continue;
    }
    j++;
    }
    i++;
    }
    list1 = getPX(images[1]);
    list2 = getPX(images[0]);
    i = 0;
    j = 0;
    for (String[] strings : list1) {
    if ((i + 1) == list1.length) {
    continue;
    }
    for (int m = 0; m < strings.length; m++) {
    try {
    String[] value1 = list1[i][j].toString().split(",");
    String[] value2 = list2[i][j].toString().split(",");
    int k = 0;
    for (int n = 0; n < value2.length; n++) {
    if (Math.abs(Integer.parseInt(value1[k]) - Integer.parseInt(value2[k])) < 5) {
    xiangsi++;
    } else {
    busi++;
    }
    }
    } catch (RuntimeException e) {
    continue;
    }
    j++;
    }
    i++;
    }
    String baifen = "";
    try {
    baifen = ((Double.parseDouble(xiangsi + "") / Double.parseDouble((busi + xiangsi) + "")) + "");
    baifen = baifen.substring(baifen.indexOf(".") + 1, baifen.indexOf(".") + 3);
    } catch (Exception e) {
    baifen = "0";
    }
    if (baifen.length() <= 0) {
    baifen = "0";
    }
    if (busi == 0) {
    baifen = "100";
    }
    System.out.println("相似像素数量:" + xiangsi + " 不相似像素数量:" + busi + " 相似率:" + Integer.parseInt(baifen) + "%");
    return Integer.parseInt(baifen);
    }

    public static void main(String[] args) {
    String file1 = "F:\\workspace_acg\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\acgweb\\uploads\\task\\1\\20170526\\1495780364826.png";
    String file2 = "F:\\workspace_acg\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\acgweb\\uploads\\task\\1495610591334.png";
    int compareImage = CompareImg.compareImage(file1, file2);
    System.out.println(compareImage);
    }

    }
    3.通过汉明距离计算相似度,取值范围 [0.0, 1.0]
    package com.zerdoor.util;

    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.color.ColorSpace;
    import java.awt.image.BufferedImage;
    import java.awt.image.ColorConvertOp;
    import java.io.File;
    import java.io.IOException;

    import javax.imageio.ImageIO;

    public class ImgSimilarity{
    // 全流程
    public static void main(String[] args) throws IOException {
    // 获取图像
    File imageFile1 = new File("F:\\workspace_acg\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\acgweb\\uploads\\task\\1496212755337.jpg");
    File file2 = new File("F:\\workspace_acg\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\acgweb\\uploads\\task\\1496212755337.jpg");
    getSimilarity(imageFile1, file2);
    }

    public static double getSimilarity(File imageFile1, File file2) throws IOException {
    int[] pixels1 = getImgFinger(imageFile1);
    int[] pixels2 = getImgFinger(file2);
    // 获取两个图的汉明距离(假设另一个图也已经按上面步骤得到灰度比较数组)
    int hammingDistance = getHammingDistance(pixels1, pixels2);
    // 通过汉明距离计算相似度,取值范围 [0.0, 1.0]
    double similarity = calSimilarity(hammingDistance)*100;
    System.out.println("相似度:"+similarity+"%");
    return similarity;
    }

    private static int[] getImgFinger(File imageFile) throws IOException {
    Image image = ImageIO.read(imageFile);
    // 转换至灰度
    image = toGrayscale(image);
    // 缩小成32x32的缩略图
    image = scale(image);
    // 获取灰度像素数组
    int[] pixels1 = getPixels(image);
    // 获取平均灰度颜色
    int averageColor = getAverageOfPixelArray(pixels1);
    // 获取灰度像素的比较数组(即图像指纹序列)
    pixels1 = getPixelDeviateWeightsArray(pixels1, averageColor);
    return pixels1;
    }

    // 将任意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;
    }
    }

    展开全文
  • java 图片相似度算法

    2019-02-28 14:49:44
    利用直方图原理实现图像内容相似度比较、均值哈希实现图像内容相似度比较、汉明距离算法实现图像内容相似度比较 直方图原理实现图像内容相似度比较算法: importjavax.imageio.*;...importjava.awt.i...

    转载自:https://www.sunjs.com/article/detail/24dd9a9e436e489185430c4c45034d69.html

     

    利用直方图原理实现图像内容相似度比较、均值哈希实现图像内容相似度比较、汉明距离算法实现图像内容相似度比较

    直方图原理实现图像内容相似度比较算法:

    import javax.imageio.*;
    import java.awt.image.*;
    import java.awt.*;
    import java.io.*;
     
    public class PhotoDigest {
        public static void main(String[] args) throws Exception {
            float percent = compare(getData("/Users/sun/Downloads/1.jpg"),
                    getData("/Users/sun/Downloads/2.jpg"));
            if (percent == 0) {
                System.out.println("无法比较");
            } else {
                System.out.println("两张图片的相似度为:" + percent + "%");
            }
        }
     
        public static int[] getData(String name) {
            try {
                BufferedImage img = ImageIO.read(new File(name));
                BufferedImage slt = new BufferedImage(100, 100,
                        BufferedImage.TYPE_INT_RGB);
                slt.getGraphics().drawImage(img, 0, 0, 100, 100, null);
                // ImageIO.write(slt,"jpeg",new File("slt.jpg"));
                int[] data = new int[256];
                for (int x = 0; x < slt.getWidth(); x++) {
                    for (int y = 0; y < slt.getHeight(); y++) {
                        int rgb = slt.getRGB(x, y);
                        Color myColor = new Color(rgb);
                        int r = myColor.getRed();
                        int g = myColor.getGreen();
                        int b = myColor.getBlue();
                        data[(r + g + b) / 3]++;
                    }
                }
                // data 就是所谓图形学当中的直方图的概念
                return data;
            } catch (Exception exception) {
                System.out.println("有文件没有找到,请检查文件是否存在或路径是否正确");
                return null;
            }
        }
     
        public static float compare(int[] s, int[] t) {
            try {
                float result = 0F;
                for (int i = 0; i < 256; i++) {
                    int abs = Math.abs(s[i] - t[i]);
                    int max = Math.max(s[i], t[i]);
                    result += (1 - ((float) abs / (max == 0 ? 1 : max)));
                }
                return (result / 256) * 100;
            } catch (Exception exception) {
                return 0;
            }
        }
    }
    

    均值哈希实现图像内容相似度比较算法:

    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.color.ColorSpace;
    import java.awt.image.BufferedImage;
    import java.awt.image.ColorConvertOp;
    import java.io.File;
    import java.io.IOException;
    import java.util.Arrays;
     
    import javax.imageio.ImageIO;
     
    /**
     * 均值哈希实现图像指纹比较
     * 
     */
    public final class FingerPrint {
     
        public static void main(String[] args) {
            try {
                FingerPrint fp1 = new FingerPrint(ImageIO.read(new File(
                        "/Users/sun/Downloads/1.jpg")));
                FingerPrint fp2 = new FingerPrint(ImageIO.read(new File(
                        "/Users/sun/Downloads/2.jpg")));
                System.out.println(fp1.toString(true));
                System.out.printf("sim=%f", fp1.compare(fp2));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        /**
         * 图像指纹的尺寸,将图像resize到指定的尺寸,来计算哈希数组
         */
        private static final int HASH_SIZE = 16;
        /**
         * 保存图像指纹的二值化矩阵
         */
        private final byte[] binaryzationMatrix;
     
        public FingerPrint(byte[] hashValue) {
            if (hashValue.length != HASH_SIZE * HASH_SIZE)
                throw new IllegalArgumentException(String.format(
                        "length of hashValue must be %d", HASH_SIZE * HASH_SIZE));
            this.binaryzationMatrix = hashValue;
        }
     
        public FingerPrint(String hashValue) {
            this(toBytes(hashValue));
        }
     
        public FingerPrint(BufferedImage src) {
            this(hashValue(src));
        }
     
        private static byte[] hashValue(BufferedImage src) {
            BufferedImage hashImage = resize(src, HASH_SIZE, HASH_SIZE);
            byte[] matrixGray = (byte[]) toGray(hashImage).getData()
                    .getDataElements(0, 0, HASH_SIZE, HASH_SIZE, null);
            return binaryzation(matrixGray);
        }
     
        /**
         * 从压缩格式指纹创建{@link FingerPrint}对象
         * 
         * @param compactValue
         * @return
         */
        public static FingerPrint createFromCompact(byte[] compactValue) {
            return new FingerPrint(uncompact(compactValue));
        }
     
        public static boolean validHashValue(byte[] hashValue) {
            if (hashValue.length != HASH_SIZE)
                return false;
            for (byte b : hashValue) {
                if (0 != b && 1 != b)
                    return false;
            }
            return true;
        }
     
        public static boolean validHashValue(String hashValue) {
            if (hashValue.length() != HASH_SIZE)
                return false;
            for (int i = 0; i < hashValue.length(); ++i) {
                if ('0' != hashValue.charAt(i) && '1' != hashValue.charAt(i))
                    return false;
            }
            return true;
        }
     
        public byte[] compact() {
            return compact(binaryzationMatrix);
        }
     
        /**
         * 指纹数据按位压缩
         * 
         * @param hashValue
         * @return
         */
        private static byte[] compact(byte[] hashValue) {
            byte[] result = new byte[(hashValue.length + 7) >> 3];
            byte b = 0;
            for (int i = 0; i < hashValue.length; ++i) {
                if (0 == (i & 7)) {
                    b = 0;
                }
                if (1 == hashValue[i]) {
                    b |= 1 << (i & 7);
                } else if (hashValue[i] != 0)
                    throw new IllegalArgumentException(
                            "invalid hashValue,every element must be 0 or 1");
                if (7 == (i & 7) || i == hashValue.length - 1) {
                    result[i >> 3] = b;
                }
            }
            return result;
        }
     
        /**
         * 压缩格式的指纹解压缩
         * 
         * @param compactValue
         * @return
         */
        private static byte[] uncompact(byte[] compactValue) {
            byte[] result = new byte[compactValue.length << 3];
            for (int i = 0; i < result.length; ++i) {
                if ((compactValue[i >> 3] & (1 << (i & 7))) == 0)
                    result[i] = 0;
                else
                    result[i] = 1;
            }
            return result;
        }
     
        /**
         * 字符串类型的指纹数据转为字节数组
         * 
         * @param hashValue
         * @return
         */
        private static byte[] toBytes(String hashValue) {
            hashValue = hashValue.replaceAll("\\s", "");
            byte[] result = new byte[hashValue.length()];
            for (int i = 0; i < result.length; ++i) {
                char c = hashValue.charAt(i);
                if ('0' == c)
                    result[i] = 0;
                else if ('1' == c)
                    result[i] = 1;
                else
                    throw new IllegalArgumentException("invalid hashValue String");
            }
            return result;
        }
     
        /**
         * 缩放图像到指定尺寸
         * 
         * @param src
         * @param width
         * @param height
         * @return
         */
        private static BufferedImage resize(Image src, int width, int height) {
            BufferedImage result = new BufferedImage(width, height,
                    BufferedImage.TYPE_3BYTE_BGR);
            Graphics g = result.getGraphics();
            try {
                g.drawImage(
                        src.getScaledInstance(width, height, Image.SCALE_SMOOTH),
                        0, 0, null);
            } finally {
                g.dispose();
            }
            return result;
        }
     
        /**
         * 计算均值
         * 
         * @param src
         * @return
         */
        private static int mean(byte[] src) {
            long sum = 0;
            // 将数组元素转为无符号整数
            for (byte b : src)
                sum += (long) b & 0xff;
            return (int) (Math.round((float) sum / src.length));
        }
     
        /**
         * 二值化处理
         * 
         * @param src
         * @return
         */
        private static byte[] binaryzation(byte[] src) {
            byte[] dst = src.clone();
            int mean = mean(src);
            for (int i = 0; i < dst.length; ++i) {
                // 将数组元素转为无符号整数再比较
                dst[i] = (byte) (((int) dst[i] & 0xff) >= mean ? 1 : 0);
            }
            return dst;
     
        }
     
        /**
         * 转灰度图像
         * 
         * @param src
         * @return
         */
        private static BufferedImage toGray(BufferedImage src) {
            if (src.getType() == BufferedImage.TYPE_BYTE_GRAY) {
                return src;
            } else {
                // 图像转灰
                BufferedImage grayImage = new BufferedImage(src.getWidth(),
                        src.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
                new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null)
                        .filter(src, grayImage);
                return grayImage;
            }
        }
     
        @Override
        public String toString() {
            return toString(true);
        }
     
        /**
         * @param multiLine
         *            是否分行
         * @return
         */
        public String toString(boolean multiLine) {
            StringBuffer buffer = new StringBuffer();
            int count = 0;
            for (byte b : this.binaryzationMatrix) {
                buffer.append(0 == b ? '0' : '1');
                if (multiLine && ++count % HASH_SIZE == 0)
                    buffer.append('\n');
            }
            return buffer.toString();
        }
     
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof FingerPrint) {
                return Arrays.equals(this.binaryzationMatrix,
                        ((FingerPrint) obj).binaryzationMatrix);
            } else
                return super.equals(obj);
        }
     
        /**
         * 与指定的压缩格式指纹比较相似度
         * 
         * @param compactValue
         * @return
         * @see #compare(FingerPrint)
         */
        public float compareCompact(byte[] compactValue) {
            return compare(createFromCompact(compactValue));
        }
     
        /**
         * @param hashValue
         * @return
         * @see #compare(FingerPrint)
         */
        public float compare(String hashValue) {
            return compare(new FingerPrint(hashValue));
        }
     
        /**
         * 与指定的指纹比较相似度
         * 
         * @param hashValue
         * @return
         * @see #compare(FingerPrint)
         */
        public float compare(byte[] hashValue) {
            return compare(new FingerPrint(hashValue));
        }
     
        /**
         * 与指定图像比较相似度
         * 
         * @param image2
         * @return
         * @see #compare(FingerPrint)
         */
        public float compare(BufferedImage image2) {
            return compare(new FingerPrint(image2));
        }
     
        /**
         * 比较指纹相似度
         * 
         * @param src
         * @return
         * @see #compare(byte[], byte[])
         */
        public float compare(FingerPrint src) {
            if (src.binaryzationMatrix.length != this.binaryzationMatrix.length)
                throw new IllegalArgumentException(
                        "length of hashValue is mismatch");
            return compare(binaryzationMatrix, src.binaryzationMatrix);
        }
     
        /**
         * 判断两个数组相似度,数组长度必须一致否则抛出异常
         * 
         * @param f1
         * @param f2
         * @return 返回相似度(0.0~1.0)
         */
        private static float compare(byte[] f1, byte[] f2) {
            if (f1.length != f2.length)
                throw new IllegalArgumentException("mismatch FingerPrint length");
            int sameCount = 0;
            for (int i = 0; i < f1.length; ++i) {
                if (f1[i] == f2[i])
                    ++sameCount;
            }
            return (float) sameCount / f1.length;
        }
     
        public static float compareCompact(byte[] f1, byte[] f2) {
            return compare(uncompact(f1), uncompact(f2));
        }
     
        public static float compare(BufferedImage image1, BufferedImage image2) {
            return new FingerPrint(image1).compare(new FingerPrint(image2));
        }
    }
    

     

    汉明距离算法实现图像内容相似度比较算法:

    import java.awt.Graphics2D;
    import java.awt.color.ColorSpace;
    import java.awt.image.BufferedImage;
    import java.awt.image.ColorConvertOp;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
     
    import javax.imageio.ImageIO;
     
    /* 
     * pHash-like image hash.  
     * Author: Elliot Shepherd (elliot@jarofworms.com 
     * Based On: http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html 
     */
    public class ImagePHash {
     
        private int size = 32;
        private int smallerSize = 8;
     
        public ImagePHash() {
            initCoefficients();
        }
     
        public ImagePHash(int size, int smallerSize) {
            this.size = size;
            this.smallerSize = smallerSize;
     
            initCoefficients();
        }
     
        public int distance(String s1, String s2) {
            int counter = 0;
            for (int k = 0; k < s1.length(); k++) {
                if (s1.charAt(k) != s2.charAt(k)) {
                    counter++;
                }
            }
            return counter;
        }
     
        // Returns a 'binary string' (like. 001010111011100010) which is easy to do
        // a hamming distance on.
        public String getHash(InputStream is) throws Exception {
            BufferedImage img = ImageIO.read(is);
     
            /*
             * 1. Reduce size. Like Average Hash, pHash starts with a small image.
             * However, the image is larger than 8x8; 32x32 is a good size. This is
             * really done to simplify the DCT computation and not because it is
             * needed to reduce the high frequencies.
             */
            img = resize(img, size, size);
     
            /*
             * 2. Reduce color. The image is reduced to a grayscale just to further
             * simplify the number of computations.
             */
            img = grayscale(img);
     
            double[][] vals = new double[size][size];
     
            for (int x = 0; x < img.getWidth(); x++) {
                for (int y = 0; y < img.getHeight(); y++) {
                    vals[x][y] = getBlue(img, x, y);
                }
            }
     
            /*
             * 3. Compute the DCT. The DCT separates the image into a collection of
             * frequencies and scalars. While JPEG uses an 8x8 DCT, this algorithm
             * uses a 32x32 DCT.
             */
            long start = System.currentTimeMillis();
            double[][] dctVals = applyDCT(vals);
            System.out.println("DCT: " + (System.currentTimeMillis() - start));
     
            /*
             * 4. Reduce the DCT. This is the magic step. While the DCT is 32x32,
             * just keep the top-left 8x8. Those represent the lowest frequencies in
             * the picture.
             */
            /*
             * 5. Compute the average value. Like the Average Hash, compute the mean
             * DCT value (using only the 8x8 DCT low-frequency values and excluding
             * the first term since the DC coefficient can be significantly
             * different from the other values and will throw off the average).
             */
            double total = 0;
     
            for (int x = 0; x < smallerSize; x++) {
                for (int y = 0; y < smallerSize; y++) {
                    total += dctVals[x][y];
                }
            }
            total -= dctVals[0][0];
     
            double avg = total / (double) ((smallerSize * smallerSize) - 1);
     
            /*
             * 6. Further reduce the DCT. This is the magic step. Set the 64 hash
             * bits to 0 or 1 depending on whether each of the 64 DCT values is
             * above or below the average value. The result doesn't tell us the
             * actual low frequencies; it just tells us the very-rough relative
             * scale of the frequencies to the mean. The result will not vary as
             * long as the overall structure of the image remains the same; this can
             * survive gamma and color histogram adjustments without a problem.
             */
            String hash = "";
     
            for (int x = 0; x < smallerSize; x++) {
                for (int y = 0; y < smallerSize; y++) {
                    if (x != 0 && y != 0) {
                        hash += (dctVals[x][y] > avg ? "1" : "0");
                    }
                }
            }
     
            return hash;
        }
     
        private BufferedImage resize(BufferedImage image, int width, int height) {
            BufferedImage resizedImage = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = resizedImage.createGraphics();
            g.drawImage(image, 0, 0, width, height, null);
            g.dispose();
            return resizedImage;
        }
     
        private ColorConvertOp colorConvert = new ColorConvertOp(
                ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
     
        private BufferedImage grayscale(BufferedImage img) {
            colorConvert.filter(img, img);
            return img;
        }
     
        private static int getBlue(BufferedImage img, int x, int y) {
            return (img.getRGB(x, y)) & 0xff;
        }
     
        // DCT function stolen from
        // http://stackoverflow.com/questions/4240490/problems-with-dct-and-idct-algorithm-in-java
     
        private double[] c;
     
        private void initCoefficients() {
            c = new double[size];
     
            for (int i = 1; i < size; i++) {
                c[i] = 1;
            }
            c[0] = 1 / Math.sqrt(2.0);
        }
     
        private double[][] applyDCT(double[][] f) {
            int N = size;
     
            double[][] F = new double[N][N];
            for (int u = 0; u < N; u++) {
                for (int v = 0; v < N; v++) {
                    double sum = 0.0;
                    for (int i = 0; i < N; i++) {
                        for (int j = 0; j < N; j++) {
                            sum += Math
                                    .cos(((2 * i + 1) / (2.0 * N)) * u * Math.PI)
                                    * Math.cos(((2 * j + 1) / (2.0 * N)) * v
                                            * Math.PI) * (f[i][j]);
                        }
                    }
                    sum *= ((c[u] * c[v]) / 4.0);
                    F[u][v] = sum;
                }
            }
            return F;
        }
     
        public static void main(String[] args) {
     
            ImagePHash p = new ImagePHash();
            String image1;
            String image2;
            try {
                image1 = p.getHash(new FileInputStream(new File(
                        "/Users/sun/Downloads/1.jpg")));
                image2 = p.getHash(new FileInputStream(new File(
                        "/Users/sun/Downloads/11.png")));
                System.out.println("1:1 Score is " + p.distance(image1, image2));
     
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
     
        }
    }
    

    结果说明:汉明距离越大表明图片差异越大,如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。

    《三种基于感知哈希算法的相似图像检索技术》

    根据Neal Krawetz博士的解释,原理非常简单易懂。我们可以用一个快速算法,就达到基本的效果。

    这里的关键技术叫做"感知哈希算法"(Perceptual hash algorithm),它的作用是对每张图片生成一个"指纹"(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。

    下面是一个最简单的实现:

    第一步,缩小尺寸。

    将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。

    第二步,简化色彩。

    将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。

    第三步,计算平均值。

    计算所有64个像素的灰度平均值。

    第四步,比较像素的灰度。

    将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。

    第五步,计算哈希值。

    将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

    得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算"汉明距离"(Hamming distance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。

    具体的代码实现,可以参见Wote用python语言写的imgHash.py。代码很短,只有53行。使用的时候,第一个参数是基准图片,第二个参数是用来比较的其他图片所在的目录,返回结果是两张图片之间不相同的数据位数量(汉明距离)。

    这种算法的优点是简单快速,不受图片大小缩放的影响,缺点是图片的内容不能变更。如果在图片上加几个文字,它就认不出来了。所以,它的最佳用途是根据缩略图,找出原图。

    实际应用中,往往采用更强大的pHash算法和SIFT算法,它们能够识别图片的变形。只要变形程度不超过25%,它们就能匹配原图。这些算法虽然更复杂,但是原理与上面的简便算法是一样的,就是先将图片转化成Hash字符串,然后再进行比较。

    展开全文
  • 对比图片相似度

    2020-07-13 14:50:23
    对比图片相似度 今天的这个小demo是用于两张图片对比 假设公司让你出一个人脸识别的功能大家有什么好的想法吗? 而我今天分享的就是解决这个问题的一个思路 二话不说上代码 `import java.awt.image....
  • Java图片相似度,图像识别

    千次阅读 2019-04-10 17:10:18
    Java图片相似对比实例 package com.icss.main; import java.awt.AWTException; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.image....
  • java版两图对比相似度

    2016-07-08 18:04:00
     System.out.println("两张图片相似度为:"+percent+"%");  }  public static int[] getData(String name)throws Exception{  BufferedImage img = ImageIO.read(new File(name));  ...
  • java 图片相似度判判断

    千次阅读 2019-07-04 13:14:15
    《三种基于感知哈希算法的相似图像检索技术》,发现原理很简单,很适合我等粗人,呵呵,于是在java下实现了这个算法的代码 : java实现 package net.gdface.image; import java.awt.Graphics; import java....
  • 声明这俩天在做图片对比的工具,这里将对比的核心功能代码贴上来共同学习,有什么缺点和不足请大家指出,谢谢。Lee出品,转载请注明出处:http://blog.csdn.net/hnulwt/article/details/43668161前言我采用图片比较...
  • 主要介绍了JAVA比较两张图片相似度的方法,涉及java针对图片像素操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • JAVA 比较两张图片相似度

    千次阅读 2018-04-28 14:17:17
    import java.awt.image.BufferedImage; import java.io.File;... /** * 比较两张图片相似度 * @author Guihua * */ public class BMPLoader { // 改变成二进制码 public static Str...
  • JAVA 比较两张图片相似度的代码

    万次阅读 2017-02-10 16:54:31
    import java.awt.image.BufferedImage; import java.io.File;... * 比较两张图片相似度 * @author Guihua * */ public class BMPLoader { // 改变成二进制码 public static String[][] getPX
  • java 图片相似度算法,大集合

    千次阅读 2018-05-02 11:50:48
    利用直方图原理实现图像内容相似度比较、均值哈希实现图像内容相似度比较、汉明距离算法实现图像内容相似度比较具体详情请参考个人博客版权属于: 技术客原文地址: ...商业转载请联系作者获得授权,非商业转载请注明出处...
  • 原文:...import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; ... * 比较两张图片相似度  * @author Guihua  *  */ public class B...
  • 两张图片相似度对比

    千次阅读 2019-07-03 18:12:55
    图片A,和图片B相似度对比代码如下 package HistogramFilter; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class HistogramFilter { public static ...
  • opencv 图片对比相似度

    万次阅读 2017-10-23 17:07:08
    判断标准:特征值相似度小于一个给定值的特征值个数2、直方图对比Android代码(http://blog.acronym.co.kr/580 ) List<Mat> listImage1 = new ArrayList(); List<Mat> listImage2 = new ArrayList(); Mat hsv_
  • Android 图片对比(图片相似度)代码

    万次阅读 2015-02-09 10:37:20
    声明这俩天在做图片对比的工具,这里将对比的核心功能代码贴上来共同学习,有什么缺点和不足请大家指出,谢谢。Lee出品,转载请注明出处:http://blog.csdn.net/hnulwt/article/details/43668161前言我采用图片比较...
  • package ... import java.awt.Graphics2D; import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; import java.awt.image.ColorConvertOp; import java.io.File; import jav...
  • 这里用到的关键技术叫做”感知哈希算法”(Perceptual hash algorithm),它的作用是对每张图片生成一个”指纹”(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。 下面是一个最简单...
  • 每张图片都可以生成颜色分布的直方图(color histogram)。如果两张图片的直方图很接近,就可以认为它们很相似。 任何一种颜色都是由红绿蓝三原色(RGB)构成的,所以上图共有4张直方图(三原色直方图 + 最后合成的...
  • opencv 检索图片包含关系 图片相似度对比 http://blog.csdn.net/CSND_Ayo/article/details/53198760
  • java--比较两张图片相似度

    千次阅读 2014-04-08 11:52:43
    import java.awt.image.BufferedImage; import java.io.File;... * 比较两张图片相似度 * @author Guihua * */ public class BMPLoader { // 改变成二进制码 public static String[][] getPX

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,170
精华内容 468
关键字:

java图片对比相似度

java 订阅