50,527
社区成员
发帖
与我相关
我的任务
分享
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.IOException;
import javax.imageio.ImageIO;
/**
*
* 汉明距离越大表明图片差异越大,如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。
* pHash-like image hash.
* Based On: http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html
*
*/
public class ImageSimilarity {
private int size = 32;
private int smallSize = 8;
private double[] c;
private ColorConvertOp colorConvert = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
public ImageSimilarity() {
initCoefficients();
}
public ImageSimilarity(int size, int smallSize) {
this.size = size;
this.smallSize = smallSize;
initCoefficients();
}
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 int distance(String hash1,String hash2) {
int count = 0;
for(int i=0; i<hash1.length(); i++) {
if(hash1.charAt(i) != hash2.charAt(i)) {
count++;
}
}
return count;
}
private BufferedImage resize(BufferedImage image,int width,int height) {
BufferedImage resizedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
Graphics2D grap = resizedImage.createGraphics();
grap.drawImage(image, 0, 0, width, height, null);
grap.dispose();
return resizedImage;
}
private BufferedImage grayscale(BufferedImage image) {
colorConvert.filter(image, image);
return image;
}
private int getBlue(BufferedImage image,int x,int y) {
return (image.getRGB(x, y)) & 0xff;
}
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;
}
private String getHash(String imagePath) {
BufferedImage image = null;
String hash = "";
try {
image = ImageIO.read(new File(imagePath));
} catch (IOException e) {
e.printStackTrace();
}
image = resize(image,size,size);
image = grayscale(image);
double[][] vals = new double[size][size];
for(int x=0; x<image.getWidth(); x++) {
for(int y=0; y<image.getHeight(); y++) {
vals[x][y] = getBlue(image,x,y);
}
}
// long start = System.currentTimeMillis();
double[][] dctVals = applyDCT(vals);
// System.out.println("DCT: " + (System.currentTimeMillis() - start));
double total = 0;
for(int x=0; x<smallSize; x++) {
for(int y=0; y<smallSize; y++) {
total += dctVals[x][y];
}
}
total -= dctVals[0][0];
double avg = total / (double) ((smallSize * smallSize) - 1);
for(int x=0; x<smallSize; x++) {
for(int y=0; y<smallSize; y++) {
if(x != 0 && y != 0) {
hash += (dctVals[x][y] > avg ? "1" : "0");
}
}
}
System.out.println("\"" + imagePath + "\" 's hash: " + hash);
return hash;
}
public int compartImage(String imagePath1, String imagePath2) {
return distance(
getHash(imagePath1),
getHash(imagePath2));
}
public static void main(String[] args) {
ImageSimilarity is = new ImageSimilarity();
System.out.println("Score is: "
+ is.compartImage("D://image//test/four.png", "D://image//test/fourliang.png"));
}
}