-
圖像二值化
鎖定
在數字圖像處理中,二值圖像佔有非常重要的地位,圖像的二值化使圖像中數據量大為減少,從而能凸顯出目標的輪廓。
- 中文名
- 圖像二值化
- 外文名
- Image Binarization
- 釋 義
- 將整個圖像呈現出明顯的黑白效果
- 灰度值
- 0或255
- 實現函數
- OpenCV,matlab
- 算 法
- OTSU,Kittle
圖像二值化簡介
將256個亮度等級的灰度圖像通過適當的閾值選取而獲得仍然可以反映圖像整體和局部特徵的二值化圖像。在數字圖像處理中,二值圖像佔有非常重要的地位,首先,圖像的二值化有利於圖像的進一步處理,使圖像變得簡單,而且數據量減小,能凸顯出感興趣的目標的輪廓。其次,要進行二值圖像的處理與分析,首先要把灰度圖像二值化,得到二值化圖像。
所有灰度大於或等於閾值的像素被判定為屬於特定物體,其灰度值為255表示,否則這些像素點被排除在物體區域以外,灰度值為0,表示背景或者例外的物體區域。
圖像二值化原理
圖像的二值化處理就是將圖像上的點的灰度值為0或255,也就是將整個圖像呈現出明顯的黑白效果。即將256個亮度等級的灰度圖像通過適當的閾值選取而獲得仍然可以反映圖像整體和局部特徵的二值化圖像。在數字圖像處理中,二值圖像佔有非常重要的地位,特別是在實用的圖像處理中,以二值圖像處理實現而構成的系統是很多的,要進行二值圖像的處理與分析,首先要把灰度圖像二值化,得到二值化圖像,這樣子有利於在對圖像做進一步處理時,圖像的集合性質只與像素值為0或255的點的位置有關,不再涉及像素的多級值,使處理變得簡單,而且數據的處理和壓縮量小。為了得到理想的二值圖像,一般採用封閉、連通的邊界定義不交疊的區域。所有灰度大於或等於閾值的像素被判定為屬於特定物體,其灰度值為255表示,否則這些像素點被排除在物體區域以外,灰度值為0,表示背景或者例外的物體區域。
[1]
如果某特定物體在內部有均勻一致的灰度值,並且其處在一個具有其他等級灰度值的均勻背景下,使用閾值法就可以得到比較的分割效果。如果物體同背景的差別表現不在灰度值上(比如紋理不同),可以將這個差別特徵轉換為灰度的差別,然後利用閾值選取技術來分割該圖像。動態調節閾值實現圖像的二值化可動態觀察其分割圖像的具體結果。
圖像二值化程序實現
圖像二值化OpenCV
OpenCV中有兩個函數可以實現圖片的二值化:
(1)cvThreshold( dst, dst,230 , 255, CV_THRESH_BINARY_INV);
(2)cvAdaptiveThreshold( dst, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY, 9, -10);
方法(1)是手動指定一個閾值,以此閾值來進行二值化處理。其中的第四個參數決定了該方法的結果:
threshold_type=CV_THRESH_BINARY:
dst(x,y) = max_value, if src(x,y)>threshold 0, otherwise.
threshold_type=CV_THRESH_BINARY_INV:
dst(x,y) = 0, if src(x,y)>threshold; dst(x,y) = max_value, otherwise.
threshold_type=CV_THRESH_TRUNC:
dst(x,y) = threshold, if src(x,y)>threshold; dst(x,y) = src(x,y), otherwise.
threshold_type=CV_THRESH_TOZERO:
dst(x,y) = src(x,y), if (x,y)>threshold ; dst(x,y) = 0, otherwise.
threshold_type=CV_THRESH_TOZERO_INV:
dst(x,y) = 0, if src(x,y)>threshold ; dst(x,y) = src(x,y), otherwise.
值得一説的是threshold_type可以使用CV_THRESH_OTSU類型,這樣該函數就會使用大律法OTSU得到的全局自適應閾值來進行二值化圖片,而參數中的threshold不再起 作用。比如:cvThreshold( dst, dst,300 , 255, CV_THRESH_OTSU | CV_THRESH_BINARY_INV);這種方法對於灰度直方圖呈現二峯特徵的圖片處理起來效果很好。
方法(2)是一個自適應閾值二值化方法,通過設定最後兩個參數來調整效果。
圖像二值化Matlab
function level = Mygraythresh(I) %GRAYTHRESH Global image threshold using Otsu's method. % LEVEL = Mygraythresh(I) computes a global threshold (LEVEL) that can be % used to convert an intensity image to a binary image with IM2BW. LEVEL % is a normalized intensity value that lies in the range [0, 1]. % GRAYTHRESH uses Otsu's method, which chooses the threshold to minimize % the intraclass variance of the thresholded black and white pixels. % % Example % ------- % I = imread('coins.png'); % level = Mygraythresh(I); % BW = im2bw(I,level); % figure, imshow(BW) % % See also IM2BW. %I=rgb2gray(I); I=im2uint8(I(:)); depth=256; counts=imhist(I,depth); w=cumsum(counts); ut=counts .* (1:depth)'; u=cumsum(ut); MAX=0; level=0; for t=1:depth u0=u(t,1)/w(t,1); u1=(u(depth,1)-u(t,1))/(w(depth,1)-w(t,1)); w0=w(t,1); w1=w(depth,1)-w0; g=w0*w1*(u1-u0)*(u1-u0); if g > MAX MAX=g; level = t; end end level=level/256;
圖像二值化算法比較
圖像二值化1:OTSU
OTSU的中心思想是閾值T應使目標與背景兩類的類間方差最大。對於一幅圖像,設當前景與背景的分割閾值為t時,前景點佔圖像比例為w0,均值為u0,背景點佔圖像比例為w1,均值為u1。則整個圖像的均值為u = w0*u0+w1*u1。建立目標函數g(t)=w0*(u0-u)^2+w1*(u1-u)^2,g(t)就是當分割閾值為t時的類間方差表達式。OTSU算法使得g(t)取得全局最大值,當g(t)為最大時所對應的t稱為最佳閾值。OTSU算法又稱為最大類間方差法。
[2]
int Threshold(int *hist) //compute the threshold { float u0, u1; float w0, w1; int count0; int t, maxT; float devi, maxDevi = 0; //方差及最大方差 int i; int sum = 0; for (i = 0; i < 256; i++) { sum = sum + hist[i]; } for (t = 0; t < 255; t++) { u0 = 0; count0 = 0; //閾值為t時,c0組的均值及產生的概率 for (i = 0; i <= t; i++) { u0 += i * hist[i]; count0 += hist[i]; } u0 = u0 / count0; w0 = (float)count0/sum; //閾值為t時,c1組的均值及產生的概率 u1 = 0; for (i = t + 1; i < 256; i++) { u1 += i * hist[i]; } u1 = u1 / (sum - count0); w1 = 1 - w0; //兩類間方差 devi = w0 * w1 * (u1 - u0) * (u1 - u0); //記錄最大的方差及最佳位置 if (devi > maxDevi) { maxDevi = devi; maxT = t; } } return maxT; } //二值化處理 void OTSU(IplImage *src, IplImage *dst) { int i = 0, j = 0; int wide = src->widthStep; int high = src->height; int hist[256] = {0}; int t; unsigned char *p, *q; for (j = 0; j < high; j ++) { p = (unsigned char *)(src->imageData + j * wide); for (i = 0; i < wide; i++) { hist[p[i]]++; //統計直方圖 } } t = Threshold(hist); for (j = 0; j < high; j ++) { q = (unsigned char *)(dst->imageData + j * wide); p = (unsigned char *)(src->imageData + j * wide); for (i = 0; i < wide; i++) { q[i] = p[i] >= t ? 255 : 0; } } }
OTSU算法對不均勻光照的圖片不能產生很好的效果,但計算簡單,適用性強。
圖像二值化2:Kittle
//kittler算法 for (i=1;i<high-1;i++) { plineadd=src->imageData+i*wide; pNextLine=src->imageData+(i+1)*wide; pPreLine=src->imageData+(i-1)*wide; for(j=1;j<wide-1;j++) { //求水平或垂直方向的最大梯度 Grads=MAX(abs((uchar)pPreLine[j]-(uchar)pNextLine[j]),abs((uchar)plineadd[j-1]-(uchar)plineadd[j+1])); //max(xGrads,yGrads) sumGrads += Grads; //梯度與當前點灰度的積 sumGrayGrads += Grads*((uchar)plineadd[j]); } } threshold=sumGrayGrads/sumGrads; // printf("%d\n",threshold); for(i=0;i<high;i++) { plineadd=src->imageData+i*wide; pTempLine=kittler->imageData+i*wide; for(j=0;j<wide;j++) { pTempLine[j]=(uchar)plineadd[j]>threshold?255:0; } }