我正在尝试在文档图像上实现 Otsu 二值化技术,例如所示:
有人可以告诉我如何在 MATLAB 中实现代码吗?
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 Desired threshold 对应 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)
由于graythresh
Matlab 中的函数实现了 Otsu 方法,因此您要做的就是将图像转换为灰度,然后使用该im2bw
函数使用 graythresh
.
要将图像转换I
为灰度,您可以使用以下代码:
I = im2uint8(I);
if size(I,3) ~= 1
I = rgb2gray(I);
end;
要使用 Otsu 的方法获取二进制图像Ib
,请使用以下代码:
Ib = im2bw(I, graythresh(I));
您应该得到以下结果:
从您最初的问题是实现 OTSU 开始,确定 MATLAB 的graythresh
函数基于该方法的真实性 OTSU 的方法将阈值视为两个峰之间的谷值,即前景像素之一和背景像素中的另一个
与您的看起来像历史手稿的图像有关,发现这篇论文比较了可用于对文档图像进行阈值处理的所有方法
您还可以从此处下载并阅读 suvola thresholding
祝它的实施好运=)
更正了 MATLAB 实现(用于 2d 矩阵)
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));