1 otsu方法參考我的另一篇博文: OTSU算法學習 OTSU公式證明
2 sauvola方法, 參考我的另一篇博文: sauvola二值化算法研究
3 Bersen方法
Bersen方法感覺有些粗糙, 只是考慮目標點附近區域的像素灰度值的最大值和最小值, 閾值是最大值和最小值的均值.下面是它的matlab實現,出自這篇博文【二值化】Bernsen算法.如果用C語言實現要用積分圖的方法.
%局部閾值操作Bersen算法 clc clear
I = imread('card8.bmp');
w =1;%矩陣大小為2*w+1 T =0;%閾值大小 max =0; min =0; [m,n]= size(I); T = zeros(m -2*w,n -2*w);
%根據bersen算法計算每個像素點的閾值 for i =(w +1):(m - w) for j =(w +1):(n - w) max = uint8(I(i,j)); min = uint8(I(i,j)); for k =-w:w for l =-w:w if max < uint8(I(i + k,j + l)) max = uint8(I(i + k,j + l)); end if min > uint8(I(i + k,j + l)) min = uint8(I(i + k,j + l)); end end end T(i,j)=0.5*(max + min); end end for i =(w +1):(m - w) for j =(w +1):(n - w) if I(i,j)> T(i,j) I(i,j)= uint8(255); else I(i,j)= uint8(0); end end end imshow(I);
|
下圖是這個方法的效果
上圖中對於圖像右側的效果很差.
4 niblack算法
Niblack二值化算法是比較簡單的局部閾值方法,閾值的計算公式是T = m + k*v,其中m為以該像素點為中心的區域的平均灰度值,v是該區域的標准差,k是一個系數. sauvola二值化算法的計算公式是T = mean*(1 + k*((std / 128) - 1)). Niblack和sauvola方法類似.下面貼matlab實現的代碼和效果圖.不做進一步分析了.
I = imread('2.bmp'); %I = rgb2gray(I);
w = 2;% max =0; min =0; [m,n]= size(I); T = zeros(m ,n );
% for i =(w +1):(m - w) for j =(w +1):(n - w) sum =0; for k =-w:w for l =-w:w sum = sum + uint32(I(i + k,j + l)); end end average = double(sum)/((2*w+1)*(2*w+1)); s =0; for k =-w:w for l =-w:w s = s + (uint32(I(i + k,j + l))- average)*(uint32(I(i + k,j + l))- average); end end s= sqrt(double(s)/((2*w+1)*(2*w+1)));
T(i,j)= average +0.2*s; end end for i = 1:m for j =1:n if I(i,j)> T(i,j) I(i,j)= uint8(255); else I(i,j)= uint8(0); end end end imshow(I);
|
5 循環閾值算法
代碼的實現和k均值聚類算法類似,但是累積值在循環中沒有清空,具體原因不知道.只是把代碼貼和效果到下面.
clc clear I = imread('2.bmp'); %I = rgb2gray(G); %l = rgb2gray(h);%轉換成灰度圖像,得到灰度值 %imhist(img);%得到灰度直方圖 %disp(img);%顯示各像素的灰度值
%循環閾值選擇方法 gray1 =0;%一部分圖像的灰度值之和 gray2 =0;%另一部分圖像的灰度值之和 u1 =0;%一部分圖像的平均灰度值 u2 =0;%另一部分的平均灰度值 k =0;%一部分圖像的像素個數 r =0;%另一部分圖像的像素個數 x =0;%閾值和 T =0;%圖像的閾值 [m,n]= size(I)%獲取圖像大小
%獲取平均閾值 for i =1:m for j =1:n x = x + uint32(I(i,j)); end end T = x/(m*n);%初始閾值
T1 =0; while T ~= T1 T1 = T; for i =1:m for j =1:n if I(i,j)< T gray1 = gray1 + uint32(I(i,j)); k = k +1; else gray2 = gray2 + uint32(I(i,j)); r = r +1; end end end u1 = gray1/k; u2 = gray2/r; T =(u1 + u2)/2;%新的閾值 end %BW = im2bw(g,T);%轉換成二值圖像 T %輸出最后選擇的閾值 %顯示區域,把不在閾值范圍內的點的灰度值置為255 for i =1:m for j =1:n if I(i,j)> T I(i,j)= uint32(255); else I(i,j)= uint32(0); end end end %se = strel('disk',1); %h = imclose(I,se); %h = imdilate(I,se); %y = imerode(h,se);
%h = medfilt2(I,[3,3]; %imshow(y); imshow(I);
|
總結: 實際應用中實現上首先要用積分圖技術來實現提速,其次要綜合考慮全局閾值方法和局部閾值方法,以全局閾值為基礎,考慮局部均值,二值化等.這個局部不能太小,太小了就會有噪點.
本文參考了博文圖像二值化算法總結,這里感謝cxf7394373.