基于内容的图片检索(Content Based Image Retrieval, CBIR),也有人称之为以图搜图,是一个很老的研究领域,它是利用机器学习、模式识别、计算机视觉等相关技术对图片的内容进行分析、检测、检索的一种应用。随着近年来模式识别与机器学习的快速发展,该领域又逐渐火热起来,并涌现出很多实际可用的商业系统。
这篇文章以兴趣为导向介绍了一种简单的,无需要用到机器学习技术的搜索技术。
具体实现思路:
1.将图片缩小成16*16的大小(也可以缩小成8*8,但精确度会降低)
2.将图片转为灰度图,并计算图片像素长度/16*像素宽度/16范围内的平均灰度值,将之记录成一个灰度矩阵。
3.遍历灰度矩阵,设置一个阈值,如灰度值中点127,大于127的设置为1,小于设置为0.
4.图片库里的图片均进行以上操作,即遍历图像矩阵生成的长度为256的二进制数字符串设置为每个图片特有的‘’图片指纹‘’。
5.将新的图片进行1-4操作,然后将得到的二进制字符串与图片库中的每个图片指纹进行对比计算“汉明距离”;
6.根据“汉明距离”判断最相近的图片。
java代码及实现的效果:
public class GetImage {
public String Getimage16str(String path){
int[][] imgArr = cs0210.ImageEff.getImagePixArray(path);
int si = imgArr.length / 16;
int sj = imgArr[0].length / 16;
// 计算灰度矩阵 缩小图片
int[][] pha = new int[17][17];
for(int i = 0 ; i < imgArr.length ; i += si){
for(int j = 0 ; j < imgArr[i].length ; j += sj){
int grayend = 0;
for(int k = 0 ; k < si ; k++){
for(int l = 0 ; l < sj ; l++){
int red = (imgArr[i][j] >> 16) & 0xFF ;
int green = (imgArr[i][j] >> 8) & 0xFF;
int blue = (imgArr[i][j] >> 0) & 0xFF;
int gray = (red + green + blue) / 3;
grayend += gray;
}
}
pha[i/si][j/sj] = grayend/(si*sj);
}
}
String code = "";
for(int i = 0 ; i < 16; i++){
for(int j = 0 ; j < 16 ; j++){
int num = pha[i][j];
if(num < 127){
code += "0";
//g.setColor(Color.WHITE);
}else{
code += "1";
//g.setColor(Color.BLACK);
}
//g.fillRect(100+i*si,100+j/sj,si,sj);
}
}
return code;
}
public static void main(String[] args) {
GetImage GI = new GetImage();
String[] strings = new String[5];
String str1 = GI.Getimage16str("C:\\Users\\ch\\Desktop\\fj2.png");
String str2 = GI.Getimage16str("C:\\Users\\ch\\Desktop\\gettargetimage\\fj1.png");
String str3 = GI.Getimage16str("C:\\Users\\ch\\Desktop\\gettargetimage\\fj2.png");
String str4 = GI.Getimage16str("C:\\Users\\ch\\Desktop\\gettargetimage\\fj3.png");
String str5 = GI.Getimage16str("C:\\Users\\ch\\Desktop\\gettargetimage\\fj4.png");
String str6 = GI.Getimage16str("C:\\Users\\ch\\Desktop\\gettargetimage\\fj5.png");
String str7 = GI.Getimage16str("C:\\Users\\ch\\Desktop\\gettargetimage\\fj6.png");
//System.out.println(str1);
MinStrExchange mse = new MinStrExchange();
int test = mse.MinStrExc(str1,str2);
int test2 = mse.MinStrExc(str1,str3);
int test3 = mse.MinStrExc(str1,str4);
int test4 = mse.MinStrExc(str1,str5);
int test5 = mse.MinStrExc(str1,str6);
int test6 = mse.MinStrExc(str1,str7);
System.out.println(test);
System.out.println(test2);
System.out.println(test3);
System.out.println(test4);
System.out.println(test5);
System.out.println(test6);
}
}
public class MinStrExchange {
public int MinStrExc(String str1, String str2){
int[][] matrix = new int[str1.length()+1][str2.length()+1];
matrix[0][0] = 0;
for(int i = 1;i<matrix.length;i++){
matrix[i][0]=i;
}
for(int i = 1;i<matrix[0].length;i++){
matrix[0][i]=i;
}
for(int i = 1;i<matrix.length;i++){
for(int j = 1;j<matrix[0].length;j++){
int zuo=matrix[i][j-1]+1;
int shang = matrix[i-1][j]+1;
int equal = 0;
if(str1.charAt(i-1)!=str2.charAt(j-1)){
equal = 1;
}
int zuoshang = matrix[i-1][j-1]+equal;
matrix[i][j] = Math.min(Math.min(zuo,shang),zuoshang);
}
}
int exchangenumber = matrix[str1.length()][str2.length()];
return exchangenumber;
}
}
实现效果:
图片库
需要搜索的图片
结果:
可见原图差异最小,基本为0。