图像处理直方图匹配-巴氏系数原理及实现
? ? ? ? 在圖像處理中,巴氏系數可用于進行相似圖像匹配。
? ? ? ??巴氏系數公式:BC(p,q) = ∑√p(x)q(x)
? ? ? ??BC為巴氏系數計算結果,p、q分別為兩張圖像在直方圖上同一位置的概率分布,巴氏系數結果范圍為(0~1),0為完全不相同,1為完全相同。
? ? ? ??原理:先分別求出兩張圖像在直方圖上的概率分布,對相同位置的概率相乘(如果某一圖像在該處分布概率為0,則乘積結果也為0,表示在該處完全不相同),然后進行開方,再對開方后結果進行累加。如果兩張圖像在某一處分布概率完全一樣,那么該處計算結果與任意一張圖像在該處分布概率相同,如果兩張圖像完全相同,那么計算結果就是與任意一張圖像在直方圖上分布概率完全相同,累加結果必定為1。
? ? ? ??實現步驟:
? ? ? ? 1、分別計算兩張圖像在直方圖上概率分布,如果是灰度圖,可以直接計算在0~255上分布概率。彩色圖像稍微復雜一些,由于彩色圖像由RGB三個通道組成,也就是說彩色圖像有256*256*256=16777216個灰度級別,顯然要對每一個灰度級別進行計算,計算量會非常大,而且計算結果也會因為過度細分而產生較大差異。如果將彩色圖像直接轉為灰度圖,雖然降低了計算量,但會損失掉彩色信息。一般可以將每個通道除以16,從256個灰度級別降低到16個,再將三個通道合并為單一值,將16777216個灰度級別降低到4096個。
? ? ? ? 轉換代碼:
? ? ? ? ? ? ? ?? int value = (R / 16) * 16 * 15 + (G / 16) * 15 + (B / 16)
? ? ? ? 當然也可以采用位運算提速:
? ? ? ? ? ? ? ?? int value = (R / 16) << 8 | (G / 16) << 4 | (B / 16)
? ? ? ? 2、計算圖像在每個灰度級別上概率分布,統計每個灰度級別包含多少像素,將像素數量除以圖像總像素。
? ? ? ? ? ? ? ?? P = number / width * height
? ? ? ? 3、根據巴氏系數計算公式計算匹配結果。
? ? ? ? ? ? ? ?? result = Math.sqrt(srcMap.get(i) * destMap.get(i))? ??
? ? ? ??實現代碼:
public class BhattacharyyaCoefficient {//singleton private static BhattacharyyaCoefficient instance = new BhattacharyyaCoefficient();private BhattacharyyaCoefficient() {}public static BhattacharyyaCoefficient getInstance() {return instance;}//巴氏系數計算public double getBhattacharyyaCoefficient (BufferedImage srcImage, BufferedImage destImage) {Map<Integer, Double> srcMap = tranverseImage(srcImage);Map<Integer, Double> destMap = tranverseImage(destImage);double result = getMatchResult(srcMap,destMap);return result;}//計算匹配結果private double getMatchResult(Map<Integer, Double> srcMap, Map<Integer, Double> destMap) {double result = 0.0;for(int i = 0; i < 4096; i++) {result += Math.sqrt(srcMap.get(i) * destMap.get(i));}return result;}/*** 圖像RGB值轉換,把255壓縮到16,返回map* R = (R / 16) << 8,G = (G / 16) << 4,B = (B / 16)* @param image* @return*/private Map<Integer, Double> tranverseImage(BufferedImage image){int width = image.getWidth();int height = image.getHeight();Map<Integer, Double> map = new HashMap<>();for(int i = 0; i < 4096; i++) {map.put(i, 0.0);}for(int i = 0; i < width; i++) {for(int j = 0; j < height; j++) {int rgb = image.getRGB(i, j);int R = (rgb >> 16) & 0xff;int G = (rgb >> 8) & 0xff;int B = rgb & 0xff;int rgbs = tranverseRGBToInt(R, G, B);map.put(rgbs, map.get(rgbs) + 1);}}int totalPix = height * width;for(int i = 0; i < 4096; i++) {double value = map.get(i) / totalPix;map.put(i, value);}return map;}/*** 將rgb值轉為壓縮后int* result = (R / 16) << 8 | (G / 16) << 4 | (B / 16)* @param R* @param G* @param B* @return*/private int tranverseRGBToInt(int R,int G,int B) {int value = (R / 16) << 8 | (G / 16) << 4 | (B / 16);return value;} }? ? ? ? 測試:
public class BhattacharyyaTest {public static void main(String[] args) throws Exception{File srcFile = new File("E:\\桌面\\test\\原圖\\1.JPG");File destFile = new File("E:\\桌面\\test\\原圖\\2.JPG");BufferedImage srcImage = ImageIO.read(srcFile);BufferedImage destImage = ImageIO.read(destFile);double result = BhattacharyyaCoefficient.getInstance().getBhattacharyyaCoefficient(srcImage, destImage);System.out.println(result);} }? ? ? ??測試圖像:
? ? ? ??運行結果:0.9899107889267019
總結
以上是生活随笔為你收集整理的图像处理直方图匹配-巴氏系数原理及实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用java实现经纬度坐标度分秒与度批量转
- 下一篇: 傅里叶变换基本概念及复数类实现