使用直方图原理实现图像内容相似度比较算法,用于模拟实现图片搜索功能
import com.datac.opencv.utils.MyFile; import javax.imageio.*; import java.awt.image.*; import java.awt.*; import java.io.*; import java.util.ArrayList; import java.util.List; /** * 直方图原理实现图像内容相似度比较算法: * @author lili * */ public class PhotoDigest { public static void main(String[] args) throws Exception { // float percent = compare(getData("C:\\img2\\2_FaceDetect_cut0.png"), // getData("C:\\img2\\3_FaceDetect_cut0.png")); String savepath ="C:\\var\\uploaded_files\\ckimg\\faces";//要查找的图片文件夹 String ckimg = "C:\\var\\uploaded_files\\ckimg\\faces\\DA319CF4BCAC46C39988FCDDEC26ED26.png";//需要匹配的图片 List<String> names = new ArrayList<String>(); MyFile.getFile(savepath,names);///獲得該 System.out.println("-------------直方图原理实现图像内容相似度比较算法-----------开始"); //去该文件夹下获得图片数据,然后生成:生成图片指纹 for (String namepath : names) { if(namepath.contains("cut")){//只比脸 float percent = compare(getData(ckimg), getData(namepath)); if (percent == 0) { System.out.println(namepath+"---无法比较"); } else { System.out.println(namepath+"---两张图片的相似度为:" + 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; } } }
————————————————- // 获得该文件夹内的所有文件图片
public class MyFile { /** * 獲得路徑 * @param path * @param names */ public static void getFile(String path,List<String> names){ // 获得指定文件对象 File file = new File(path); // 获得该文件夹内的所有文件 File[] array = file.listFiles(); for(int i=0;i<array.length;i++) { if(array[i].isFile())//如果是文件 { names.add(array[i].getPath()); // names.add(array[i].getPath()+"\\"+array[i].getName()); } else if(array[i].isDirectory())//如果是文件夹 { //文件夹需要调用递归 ,深度+1 getFile(array[i].getPath(),names); } } } }