Otsu 算法
本文目录% 已读
一、Otsu 的基本思想(类间方差最大)
假设一幅灰度图中只有两类像素:
- 前景:目标(如文字、物体)
- 背景:不是目标的部分
我们要找一个灰度阈值 ,把图像分成两类:
- 类 0(背景):灰度
- 类 1(前景):灰度 ,其中 是灰度级数(一般为 256)
Otsu 的思想:找到使类间方差(两类之间差异)最大的阈值。
二、数学公式(单阈值 Otsu)
设灰度级为 ,直方图为 ,总像素数为 。
-
概率分布:
-
给定阈值 ,两类像素的概率(权重):
-
两类的平均灰度:
-
图像整体平均灰度:
-
类间方差(between-class variance)定义为:
常用等价形式:
算法目标:
三、Otsu 算法实现步骤(单阈值)
-
计算图像灰度直方图 ,并归一化得到 。
-
利用前缀和快速计算 、、、 与 。
-
对每一个可能的阈值 (0 到 )计算类间方差 。
-
取类间方差最大的 作为 Otsu 阈值。
-
按此阈值对图像进行二值化:
四、Matlab 示例代码
1. 使用 Matlab 自带 Otsu(graythresh + imbinarize)
% 读入图像(灰度图)I = imread('input.png');if size(I, 3) == 3 I = rgb2gray(I); % 若为彩色图像,转为灰度end
% Matlab 的 Otsu 阈值:graythresh 返回的是 [0,1] 之间的归一化阈值level = graythresh(I);
% 二值化BW = imbinarize(I, level);
% 显示结果figure;subplot(1,2,1); imshow(I); title('Original');subplot(1,2,2); imshow(BW); title(['Otsu (graythresh) level = ', num2str(level)]);graythresh 的实现就是 Otsu 单阈值算法。注意它返回的是归一化阈值(相对于 0–1),实际灰度阈值为 T = level * 255。
2. 手写 Otsu 算法(示例实现)
下面这段代码不依赖 graythresh,按公式自己算一遍阈值。
% 读入图像I = imread('input.png');if size(I,3) == 3 I = rgb2gray(I);end
% 转 double 方便计算(也可以不转)I = double(I);
% 参数L = 256; % 灰度级数 0~255N = numel(I); % 像素总数
% 1. 计算直方图 h(i)[counts, ~] = imhist(uint8(I), L); % counts: 256x1p = counts / N; % 概率分布 p_i
% 2. 累计概率 ω(k) 和 累计均值 μ(k)omega = cumsum(p); % ω_kmu_k = cumsum((0:L-1)' .* p); % μ_k 的分子部分mu_T = mu_k(end); % 总均值 μ_T
% 3. 计算每个可能阈值 t 的类间方差 σ_B^2(t)sigma_b2 = zeros(L, 1);for t = 1:L if omega(t) == 0 || omega(t) == 1 sigma_b2(t) = 0; else sigma_b2(t) = (mu_T * omega(t) - mu_k(t))^2 / (omega(t) * (1 - omega(t))); endend
% 4. 找到最大类间方差对应的阈值 t*[~, idx] = max(sigma_b2);T = idx - 1; % Matlab 索引从 1 开始,对应灰度 0~255,所以减 1
fprintf('Otsu threshold = %d\n', T);
% 5. 按 T 进行二值化BW_manual = I > T;
% 显示结果figure;subplot(1,3,1); imshow(uint8(I)); title('Original');subplot(1,3,2); imshow(BW_manual); title(['Manual Otsu, T = ', num2str(T)]);subplot(1,3,3); imhist(uint8(I)); hold on;line([T T], ylim, 'LineWidth', 2); title('Histogram with Otsu T');五、Otsu 算法的特点
优点
-
无参数:不需要手工指定阈值,自动从数据中估计;
-
实现简单:只涉及直方图、累积和,计算高效;
-
对于前景和背景灰度分布差异较明显、近似双峰的图像效果很好;
-
被广泛集成到 OpenCV、Matlab 等库中,工程实践非常常见。
局限性
-
默认是单阈值二类分割,如果图像存在多类(多峰直方图)会不够理想;
-
假设背景和前景在直方图上区分明显,如果图像对比度很低或噪声很多,效果会下降;
-
标准 Otsu 是全局阈值,对光照不均匀的图像效果一般(可用局部/自适应方法改进)。
六、常见扩展与变体
-
多阈值 Otsu(Multi-level Otsu)
不只找一个阈值,而是找多个阈值 ,将灰度分成多类,每个类之间的类间方差总和最大。
计算复杂度会显著增加(阈值组合数量多),常配合搜索优化或启发式算法。 -
二维 Otsu(2D Otsu)
不只考虑像素本身的灰度,还加入邻域平均、梯度等信息,用二维直方图计算最佳阈值,能更好对抗噪声,但运算量更大。 -
局部/块级 Otsu
将图像分成小块,对每块单独使用 Otsu 得到局部阈值,适用于光照不均、阴影较重的场景。 -
与其它方法组合
如先做滤波、直方图均衡或对数变换,再用 Otsu;或 Otsu 与形态学处理一起使用,提高分割质量。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
