二值化是圖像處理中最為常見的處理方式,最近做完畢業設計,然后對圖像中二值化處理方式進行整理和分類,主要包括:最大類間方法法(OSTU),迭代閾值法,P分位法,基於最小誤差的全局閾值法,局部閾值法,全局閾值與局部閾值相結合的方法;以下使用matlab編寫的算法。
1、最大類間方差法:
%二值化方法
%OSTU方法:最大類間方差法
function Img = OstuFun(I)
%二值化處理
level = graythresh(I);
Img = im2bw(I,level);
2、迭代閾值法:
%該函數采用迭代法求取閾值
function Out_img = IterateThresh(I)
I = double(I);
%求出圖像的大小
[M,N] = size(I);
%選擇初始閾值T
Z0 = max(max(I));
Z1 = min(min(I));
T = (Z0+Z1)/2;
%新的閾值初始賦值為零
TT = 0;
%預先指定范圍
allow = 5;
d = abs(T-TT);
%計算大於閾值的灰度總值和小於閾值的灰度總值
S0 = 0;N0 = 0;
S1 = 0;N1 = 0;
%閾值迭代
while(d >= allow)
for i=1:M
for j=1:N
if(I(i,j) >= T)
S0 = S0+I(i,j);
N0 = N0+1;
else
S1 = S1+I(i,j);
N1 = N1+1;
end
end
end
%計算新的閾值
T0 = S0/N0;
T1 = S1/N1;
TT = (T0+T1)/2;
d = abs(T-TT);
T = TT;
end
%對圖像二值化處理
for i=1:M
for j=1:N
if(I(i,j)>=T)
Out_img(i,j) = 255;
else
Out_img(i,j) = 0;
end
end
end
3、P分位法
%該函數采用P分位法對圖像進行二值化處理
function Out_img = PFenWei(I)
I1 = double(I);
%獲取圖像的高度和寬度
[M,N] = size(I1);
%對圖像進行分塊處理,對每一塊采用P分位法處理
block = 64;
m = M/block;
n = N/block;
for i = 1:m
for j = 1:n
%得到每一小塊圖像矩陣
temp = I1((i-1)*block+1:i*block,(j-1)*block+1:j*block);
%求取每小塊的直方圖
hist = imhist(uint8(real(temp)));
%求取每一小塊的最佳閾值
for tt = 1:256
if(1/block^2 * sum(hist(1:tt)) <= 0.85 && 1/block^2*sum(hist(1:tt+1)) > 0.85 )
Thresh = tt;
end
end
%對圖像每一小塊二值化處理
for x = 1:block
for y = 1:block
if(temp(x,y) > Thresh)
temp(x,y) = 255;
else
temp(x,y) = 0;
end
end
end
%將取出的每一小塊放入到原始圖像中
Out_img((i-1)*block+1:i*block,(j-1)*block+1:j*block) = temp;
end
end
Out_img = uint8(real(Out_img));
4、基於最小誤差的全局閾值法
%圖像二值化方法
%方法:采用最小誤差的閾值分割方法
function out_im = minimumError(im)
out_im=im;
threshold = 0;
%得到圖像中最大像素值
MAX=double(max(im(:)));
%得到圖像的高度和寬度
[M,N]=size(im);
%定義數組,初始化為零
tab(1:MAX+1)=0;
%得到圖像的直方圖
h=imhist(im);
%歸一化直方圖數據
h=h/(M*N);
p=0.0;u=0.0;
%直方圖累加
for i=0:MAX
p=p+h(i+1);
u=u+h(i+1)*i;
end
for t=0:MAX
p1=0.0;u1=0.0;
k1=0.0;k2=0.0;
pp1=0.0;pp2=0.0;
kk1=0.0;kk2=0.0;
%計算1階統計矩u1,u2
for i=0:t
p1=p1+h(i+1);
u1=u1+h(i+1)*i;
end
if((p-p1)~=0)
u2=(u-u1)/(p-p1);
else
u2=0;
end
if(p1~=0)
u1=u1/p1;
else
u1=0;
end
%計算2階統計矩K1,K2
for j=0:t
k1=k1+(j-u1)*(j-u1)*h(j+1);
end
for m=t+1:MAX
k2=k2+(m-u2)*(m-u2)*h(m+1);
end
if(p1~=0)
k1=sqrt(k1/p1);
pp1=p1*log(p1);
end
if((p-p1)~=0)
k2=sqrt(k2/(p-p1));
pp2=(p-p1)*log(p-p1);
end
if(k1~=0)
kk1=p1*log(k1);
end
if((k2)~=0)
kk2=(p-p1)*log(k2);
end
%判別函數
tab(t+1)=1+2*(kk1+kk2)-2*(pp1+pp2);
end
%求出最小值
Min=min(tab);
th=find(tab==Min);
temp1 = size(th);
if(temp1(2)==1)
threshold = th;
else
threshold = fix(average(th));
end
for i=1:M
for j=1:N
if (out_im(i,j)>threshold)
out_im(i,j)=255;
else
out_im(i,j)=0;
end
end
end
5、局部閾值法
%采用局部閾值進行二值化處理
function image = DynamicThresh(I)
%對圖像分塊:64*64,對每塊采用最小誤差求的每塊的灰度值
I2 = blkproc(I,[64 64],'Minmum');
I2 = medfilt2(I2,'symmetric');
%還原為1024*1024
rec = imresize(I2,[1024 1024],'bilinear');
%采用動態閾值算法
image = zeros(1024,1024);
for i=1:1024
for j=1:1024
if(rec(i,j)>I(i,j))
image(i,j) = 0;
else
image(i,j) = 255;
end
end
end
6、全局閾值與局部閾值相結合的方法
%該函數采用全局閾值和局部閾值相結合
function Out_img = MinAndDyThresh(I)
%求取最小誤差法得到的閾值
MinThresh = Minmum(I);
%對圖像分塊:64*64,對每塊采用最小誤差求的每塊的灰度值
blkImg = blkproc(I,[64 64],'Minmum');
I1 = medfilt2(blkImg,'symmetric');
%還原為1024*1024,采用雙線性插值法
rec = imresize(I1,[1024 1024],'bilinear');
%動態閾值和極小值誤差相結和
Out_img = zeros(1024,1024);
for i = 1:1024
for j=1:1024
temp = 0.7*rec(i,j)+0.3*MinThresh;
if(I(i,j) > temp)
Out_img(i,j) = 255;
else
Out_img(i,j) = 0;
end
end
end
%Minmum函數
function threshold=Minmum(im)
tt=cputime;
out_im=im;
MAX=double(max(im(:)));
[M,N]=size(im);
tab(1:MAX+1)=0;
h=imhist(im);
h=h/(M*N); %歸一化直方圖數據
p=0.0;u=0.0;
for i=0:MAX
p=p+h(i+1);
u=u+h(i+1)*i;
end
for t=0:MAX
p1=0.0;u1=0.0;
k1=0.0;k2=0.0;
pp1=0.0;pp2=0.0;
kk1=0.0;kk2=0.0;
for i=0:t %計算1階統計矩u1,u2
p1=p1+h(i+1);
u1=u1+h(i+1)*i;
end
if((p-p1)~=0)
u2=(u-u1)/(p-p1);
else
u2=0;
end
if(p1~=0)
u1=u1/p1;
else
u1=0;
end
for j=0:t %計算2階統計矩K1,K2
k1=k1+(j-u1)*(j-u1)*h(j+1);
end
for m=t+1:MAX
k2=k2+(m-u2)*(m-u2)*h(m+1);
end
if(p1~=0)
k1=sqrt(k1/p1);
pp1=p1*log(p1);
end
if((p-p1)~=0)
k2=sqrt(k2/(p-p1));
pp2=(p-p1)*log(p-p1);
end
if(k1~=0)
kk1=p1*log(k1);
end
if((k2)~=0)
kk2=(p-p1)*log(k2);
end
tab(t+1)=1+2*(kk1+kk2)-2*(pp1+pp2); %判別函數
end
Min=min(tab);
th=find(tab==Min);
temp1 = size(th);
if(temp1(2)==1)
threshold = th;
else
threshold = fix(average(th));
end