Ostu假设图像是由前景区域和背景区域两部分组成的,通过遍历计算不同阈值(通常为[0
255]区间范围内)下分割结果中前景区域和背景区域的灰度直方图,然后比较两者之间的方差,使得方差最大化的那个灰度阈值即为所求二值化阈值。
matlab程序如下所示:
close all;
clear all;
clc;
G = imread('D:\test.bmp');
figure;
imshow(G);
title('原图');
%I = rgb2gray(G);
I=G;
[m,n] = size(I);
Hist = zeros(256);%直方图
dHist = zeros(256);%各像素值所占比例
variance = zeros(256);%方差
PXD = 0;%阈值初始化
for i = 1:m
for j = 1:n
Hist(uint8(I(i,j))+1) = Hist(uint8(I(i,j))+1) +
1;%由于matlab矩阵下标最小为1,所以这里稍微变换一下取下标为uint8(I(i,j))+1代表灰度值uint8(I(i,j))对应的直方图下标
end
end
for i = 1:256
dHist(i) =
Hist(i)/(m*n);
end
for PXD = 1:256
w0 = 0;
w1 = 0;
g0 = 0;
g1 = 0;
for i = 1:PXD
g0 = g0 + (i-1)*dHist(i);
w0 = w0 + dHist(i);
end
for i = PXD+1 : 256
g1 = g1 + (i-1)*dHist(i);
w1 = w1 + dHist(i);
end
variance(PXD) = w0*w1*(g0
- g1)*(g0 - g1);%考虑到速度问题,此处用了一个等价算法,其效果等同于最大化类间方差
end
PXD = 1;
for i = 1:256
if variance(PXD)
< variance(i)
PXD = i;
end
end
for i = 1:m
for j = 1:n
if I(i,j) > PXD
I(i,j) =
255;
else
I(i,j) = 0;
end
end
end
imageBW = I;
figure;
imshow(imageBW);
title('Ostu二值化');
此外,matlab中还有现成的Ostu阈值分割函数,用法如下:
I =
imread('D:\test.bmp');
level =
graythresh(I);%也就是原理中循环查找使得类间方差最大化的阈值步骤
BW = im2bw(I,level);%找到阈值二值化即可
figure, imshow(BW)