最近有个项目里要整理缩略图和原图是否匹配,然后就去找工具和方法做了,之后很好奇图像相似度是怎么算的,google了下貌似很深奥,而且无最简单的例子java代码源码下载,估计图形学的人不削用java吧。
个人从来没有研究过图像学,也没看过什么论文或者相关文档,写这个完全是靠google和百度,自己写了个实验了下,测试用例也少,估计有大BUG的存在,所以看的人权当学习交流,切勿生产使用。
思路:
1,二值化,(不做颜色比对了,生成黑白图)
2 ,取黑色的矩形阵列,(不管图片大小,只取同颜色的矩形区域,判断规则下文讲)
3,排序取前几个矩阵,(去最大矩阵的 %d 面积以上的矩阵,%d作为参数)。
4,取得2张图的矩阵,对比矩阵距离面积等,根据面积权重,得到相似度。
如这么图取的矩阵就是红色区域,没画全。
好了,开始了,下面的代码要是有人发现问题PM我,我去改正:
1,二值化:
package cn.my.image.Compare.test;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
public class Binarization {
private static float RP = 0.333f;
private static float GP = 0.334f;
private static float BP = 0.333f;
private static int Threshold = 0;
private int h;
private int w;
public Binarization(){
}
/**
* set your threshold such as 160 这里手工设判断黑白的标准,默认是图像全局的平均值。
* @param threshold
*/
public Binarization(int threshold){
Threshold = threshold;
}
/**
* init with r,g,b Proportion 设置R G B的权重比,默认平分
* @param r
* @param g
* @param b
*/
public Binarization(float r,float g,float b,int threshold){
RP = r;
GP = g;
BP = b;
Threshold = threshold;
}
public int getH(){
return h;
}
public int getW() {
return w;
}
public int getArea(){
return w*h;
}
public int[][] toBinarization(InputStream stream) throws IOException {
BufferedImage bi=ImageIO.read(stream);//input image
h=bi.getHeight();//get height
w=bi.getWidth();//get width
int sumRGB = 0;
int[][] gray=new int[w][h];
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
gray[x][y]=getGray(bi.getRGB(x, y));
sumRGB = sumRGB + gray[x][y];
}
}
if(Threshold ==0){
Threshold = sumRGB/(h*w); //threshold by avager
}
int[][] binary=new int[w][h];
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if(getAverageColor(gray, x, y, w, h)>Threshold){
binary[x][y] = 1 ; /// 1 for White
}else{
b