圖片相似度判斷-差異值雜湊演算法JAVA版
阿新 • • 發佈:2018-12-22
差異值雜湊演算法(dHash)
- 圖片縮放為9*8大小
- 將圖片灰度化
- 差異值計算(每行相鄰畫素的差值,這樣會生成8*8的差值,前一個畫素大於後一個畫素則為1,否則為0)
- 生成雜湊值
package com.example.demo.hello; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; /** * 差異雜湊演算法 */ public class DHashUtil { /** * 計算dHash方法 * * @param file 檔案 * @return hash */ private static String getDHash(File file) { //讀取檔案 BufferedImage srcImage; try { srcImage = ImageIO.read(file); } catch (IOException e) { e.printStackTrace(); return null; } //檔案轉成9*8畫素,為演算法比較通用的長寬 BufferedImage buffImg = new BufferedImage(9, 8, BufferedImage.TYPE_INT_RGB); buffImg.getGraphics().drawImage(srcImage.getScaledInstance(9, 8, Image.SCALE_SMOOTH), 0, 0, null); int width = buffImg.getWidth(); int height = buffImg.getHeight(); int[][] grayPix = new int[width][height]; StringBuffer figure = new StringBuffer(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { //圖片灰度化 int rgb = buffImg.getRGB(x, y); int r = rgb >> 16 & 0xff; int g = rgb >> 8 & 0xff; int b = rgb & 0xff; int gray = (r * 30 + g * 59 + b * 11) / 100; grayPix[x][y] = gray; //開始計算dHash 總共有9*8畫素 每行相對有8個差異值 總共有 8*8=64 個 if(x != 0) { long bit = grayPix[x-1][y] > grayPix[x][y] ? 1 : 0; figure.append(bit); } } } return figure.toString(); } /** * 計算海明距離 * <p> * 原本用於編碼的檢錯和糾錯的一個演算法 * 現在拿來計算相似度,如果差異值小於一定閾值則相似,一般經驗值小於5為同一張圖片 * * @param str1 * @param str2 * @return 距離 */ private static long getHammingDistance(String str1, String str2) { int distance; if (str1 == null || str2 == null || str1.length() != str2.length()) { distance = -1; } else { distance = 0; for (int i = 0; i < str1.length(); i++) { if (str1.charAt(i) != str2.charAt(i)) { distance++; } } } return distance; } //DHashUtil 引數值為待處理資料夾 public static void main(String[] args) { File file1 = new File("xxx//1.jpg"); File file2 = new File("xxx//2.jpg"); System.out.println("圖片1hash值:"+getDHash(file1)); System.out.println("圖片2hash值:"+getDHash(file2)); System.out.println("海明距離為:"+getHammingDistance(getDHash(file1),getDHash(file2))); } }