圖像處理------常見二值化方法彙總 分類: 視頻圖像處理 2015-07-24 14:51 33人閱讀 評論(0) 收藏

圖像二值化是圖像分析與處理中最多見最重要的處理手段,二值處理方法也很是多。越java

精準的方法計算量也越大。本文主要介紹四種常見的二值處理方法,一般狀況下能夠滿ide

足大多數圖像處理的須要。主要本文討論的方法僅針對RGB色彩空間。this

 

方法一:url

該方法很是簡單,對RGB彩色圖像灰度化之後,掃描圖像的每一個像素值,值小於127的spa

像素值設爲0(黑色),值大於等於127的像素值設爲255(白色)。該方法的好處是計算.net

量少速度快。缺點更多首先閾值爲127沒有任何理由能夠解釋,其次徹底不考慮圖像的orm

像素分佈情況與像素值特徵。能夠說該方法是史最弱智的二值處理方法一點也不爲過。對象

 

方法二:blog

最多見的二值處理方法是計算像素的平均值K,掃描圖像的每一個像素值如像素值大於Kip

像素值設爲255(白色),值小於等於K像素值設爲0(黑色)。該方法相比方法一,閾值的

選取稍微有點智商,能夠解釋。可是使用平均值做爲二值化閾值一樣有個致命的缺點,

可能致使部分對象像素或者背景像素丟失。二值化結果不能真實反映源圖像信息。

 

方法三:

使用直方圖方法來尋找二值化閾值,直方圖是圖像的重要特質,直方圖方法選擇二值

化閾值主要是發現圖像的兩個最高的峯,而後在閾值取值在兩個峯之間的峯谷最低處。

該方法相對前面兩種方法而言稍微精準一點點。結果也更讓人能夠接受。

 

方法四:http://en.wikipedia.org/wiki/Thresholding_(image_processing)

使用近似一維Means方法尋找二值化閾值,該方法的大體步驟以下:

1.      一個初始化閾值T,能夠本身設置或者根據隨機方法生成。

2.      根據閾值圖每一個像素數據P(n,m)分爲對象像素數據G1與背景像素數據G2。(n爲

行,m爲列)

3.      G1的平均值是m1, G2的平均值是m2

4.      一個新的閾值T’ = (m1 + m2)/2

5.      回到第二步,用新的閾值繼續分像素數據爲對象與北京像素數據,繼續2~4步,

直到計算出來的新閾值等於上一次閾值。

前面三種在之前的博文中都有涉及,最後一種二值化方法的代碼以下:

[java]  view plain copy
  1. package com.gloomyfish.filter.study;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. public class ThresholdBinaryFilter extends GrayFilter {  
  8.   
  9.     @Override  
  10.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  11.         int width = src.getWidth();  
  12.         int height = src.getHeight();  
  13.   
  14.         if ( dest == null )  
  15.             dest = createCompatibleDestImage( src, null );  
  16.   
  17.         int[] inPixels = new int[width*height];  
  18.         int[] outPixels = new int[width*height];  
  19.         src = super.filter(src, null); // we need to create new one  
  20.         getRGB( src, 00, width, height, inPixels );  
  21.         int index = 0;  
  22.         int means = getThreshold(inPixels, height, width);  
  23.         for(int row=0; row<height; row++) {  
  24.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  25.             for(int col=0; col<width; col++) {  
  26.                 index = row * width + col;  
  27.                 ta = (inPixels[index] >> 24) & 0xff;  
  28.                 tr = (inPixels[index] >> 16) & 0xff;  
  29.                 tg = (inPixels[index] >> 8) & 0xff;  
  30.                 tb = inPixels[index] & 0xff;  
  31.                 if(tr > means) {  
  32.                     tr = tg = tb = 255//white  
  33.                 } else {  
  34.                     tr = tg = tb = 0// black  
  35.                 }  
  36.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  37.             }  
  38.         }  
  39.         setRGB( dest, 00, width, height, outPixels );  
  40.         return dest;  
  41.     }  
  42.   
  43.     private int getThreshold(int[] inPixels, int height, int width) {  
  44.         // maybe this value can reduce the calculation consume;   
  45.         int inithreshold = 127;  
  46.         int finalthreshold = 0;  
  47.         int temp[] = new int[inPixels.length];  
  48.         for(int index=0; index<inPixels.length; index++) {  
  49.             temp[index] = (inPixels[index] >> 16) & 0xff;  
  50.         }  
  51.         List<Integer> sub1 = new ArrayList<Integer>();  
  52.         List<Integer> sub2 = new ArrayList<Integer>();  
  53.         int means1 = 0, means2 = 0;  
  54.         while(finalthreshold != inithreshold) {  
  55.             finalthreshold = inithreshold;  
  56.             for(int i=0; i<temp.length; i++) {  
  57.                 if(temp[i] <= inithreshold) {  
  58.                     sub1.add(temp[i]);  
  59.                 } else {  
  60.                     sub2.add(temp[i]);  
  61.                 }  
  62.             }  
  63.             means1 = getMeans(sub1);  
  64.             means2 = getMeans(sub2);  
  65.             sub1.clear();  
  66.             sub2.clear();  
  67.             inithreshold = (means1 + means2) / 2;  
  68.         }  
  69.         long start = System.currentTimeMillis();  
  70.         System.out.println("Final threshold  = " + finalthreshold);  
  71.         long endTime = System.currentTimeMillis() - start;  
  72.         System.out.println("Time consumes : " + endTime);  
  73.         return finalthreshold;  
  74.     }  
  75.   
  76.     private static int getMeans(List<Integer> data) {  
  77.         int result = 0;  
  78.         int size = data.size();  
  79.         for(Integer i : data) {  
  80.             result += i;  
  81.         }  
  82.         return (result/size);  
  83.     }  
  84.   
  85. }  

效果以下:

相關文章
相關標籤/搜索