java判断图片相同_java 识别图片相似度及图片是否相同

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 getDirMD5(File file,boolean listChild) {

if(!file.isDirectory()){

return null;

}

//

Map map=new HashMap();

String md5;

File files[]=file.listFiles();

for(int i=0;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判断图片相同)