二值化是图像处理中最为常见的处理方式,最近做完毕业设计,然后对图像中二值化处理方式进行整理和分类,主要包括:最大类间方法法(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