【发布时间】:2012-04-02 17:50:58
【问题描述】:
我正在尝试在文档图像上实现 Otsu 二值化技术,例如所示:
谁能告诉我如何在 MATLAB 中实现代码?
【问题讨论】:
-
Matlab 默认存在,见
graythresh -
Image Processing Toolbox 中的函数
graythresh计算 Otsu 的阈值。
我正在尝试在文档图像上实现 Otsu 二值化技术,例如所示:
谁能告诉我如何在 MATLAB 中实现代码?
【问题讨论】:
graythresh
graythresh 计算 Otsu 的阈值。
I = imread('cameraman.tif');
第 1 步。计算每个强度级别的直方图和概率。
nbins = 256; % Number of bins
counts = imhist(I,nbins); % Each intensity increments the histogram from 0 to 255
p = counts / sum(counts); % Probabilities
第 2 步。 设置初始 omega_i(0) 和 mu_i(0)
omega1 = 0;
omega2 = 1;
mu1 = 0;
mu2 = mean(I(:));
第 3 步。逐步完成从 0 到最大强度 (255) 的所有可能阈值
步骤 3.1 更新 omega_i 和 mu_i
步骤 3.2 计算 sigma_b_squared
for t = 1:nbins
omega1(t) = sum(p(1:t));
omega2(t) = sum(p(t+1:end));
mu1(t) = sum(p(1:t).*(1:t)');
mu2(t) = sum(p(t+1:end).*(t+1:nbins)');
end
sigma_b_squared_wiki = omega1 .* omega2 .* (mu2-mu1).^2; % Eq. (14)
sigma_b_squared_otsu = (mu1(end) .* omega1-mu1) .^2 ./(omega1 .* (1-omega1)); % Eq. (18)
Step 4 所需阈值对应 sigma_b_squared 最大值的位置
[~,thres_level_wiki] = max(sigma_b_squared_wiki);
[~,thres_level_otsu] = max(sigma_b_squared_otsu);
wiki-version eq 之间存在一些差异。 (14) 在大津和等式。 (18),我不知道为什么。但是thres_level_otsu对应MATLAB的实现graythresh(I)
【讨论】:
由于Matlab中的函数graythresh实现了Otsu方法,你要做的就是将你的图像转换为灰度,然后使用im2bw函数使用graythresh返回的阈值水平对图像进行二值化。
要将您的图像I 转换为灰度,您可以使用以下代码:
I = im2uint8(I);
if size(I,3) ~= 1
I = rgb2gray(I);
end;
要使用Otsu的方法获取二进制图像Ib,请使用以下代码:
Ib = im2bw(I, graythresh(I));
你应该得到以下结果:
【讨论】:
更正的 MATLAB 实现(用于二维矩阵)
function [T] = myotsu(I,N);
% create histogram
nbins = N;
[x,h] = hist(I(:),nbins);
% calculate probabilities
p = x./sum(x);
% initialisation
om1 = 0;
om2 = 1;
mu1 = 0;
mu2 = mode(I(:));
for t = 1:nbins,
om1(t) = sum(p(1:t));
om2(t) = sum(p(t+1:nbins));
mu1(t) = sum(p(1:t).*[1:t]);
mu2(t) = sum(p(t+1:nbins).*[t+1:nbins]);
end
sigma = (mu1(nbins).*om1-mu1).^2./(om1.*(1-om1));
idx = find(sigma == max(sigma));
T = h(idx(1));
【讨论】: