【OCR 学习笔记】二值化——全局阈值方法

二值化------全局阈值方法

图像二值化(Image Binarization)是指将像素点的灰度值设为0或255,使图像呈现明显的黑白效果。二值化一方面减少了数据维度,另一方面通过排除原图中噪声带来的干扰,可以凸显有效区域的轮廓结构。OCR效果很大程度上取决于该步骤,高质量的二值图像可以显著提升识别的准确率。目前,二值化的方法主要分为全局阈值方法(Global Binarization)、局部阈值方法(Local Binarization)、基于深度学习的方法和其他方法。

固定阈值方法

该方法对输入图像中的所有像素点统一使用同一个固定阈值。其算法如下:
g ( x , y ) = { 255 , 若 f ( x , y ) ≥ T 0 , 否则 g(x,y)=\begin{cases} 255, & 若f(x,y)\geq T \\ 0, & 否则 \end{cases} g(x,y)={255,0,若f(x,y)≥T否则

  • T T T为全局阈值

不同的阈值 T T T会产生不同的二值化效果。对于不同的输入图像,最佳的阈值 T T T也不一样,这也是固定阈值方法的主要缺陷。

于是,解决这一缺陷的相应算法也随之而出现;下面的几种方法均采用了根据输入图像计算最佳阈值的思想。

Otsu算法

Ostu算法[1](#1)又称最大类间方差法,由日本学者Nobuyuki Ostu于1979年提出,是一种在自适应的阈值确定方法。

Ostu算法将输入图像分为 L L L个灰度级, n i n_i ni表示灰度级为 i i i的像素个数,则像素总数 N = n 1 + n 2 + ⋯ + n L N=n_1+n_2+ \cdots +n_L N=n1+n2+⋯+nL。为了简化讨论,这里使用归一化的灰度直方图,并将其视为输入图像的概率分布:
p i = n i / N , p i > 0 , ∑ i = 1 L p i = 1 p_i=n_i/N, p_i>0, \sum_{i=1}^{L}p_i=1 pi=ni/N,pi>0,i=1∑Lpi=1

现假设在第 k k k个灰度级设置阈值,将图像分为 C 0 C_0 C0和 C 1 C_1 C1(背景和目标物体), C 0 C_0 C0表示灰度级为 1 , ⋯   , k 1, \\cdots, k 1,⋯,k的像素点, C 1 C_1 C1表示灰度级为 k + 1 , ⋯   , L k+1, \\cdots, L k+1,⋯,L的像素点,那么两类出现的概率以及类内灰度级的均值分别为:
ω 0 = P r ( C 0 ) = ∑ i = 1 k p i = ω ( k ) ω 1 = P r ( C 1 ) = ∑ i = k + 1 L p i = 1 − ω ( k ) μ 0 = ∑ i = 1 k i P r ( i ∣ C 0 ) = ∑ i = 1 k i p i / ω 0 = μ ( k ) / ω ( k ) μ 1 = ∑ i = k + 1 L i P r ( i ∣ C 1 ) = ∑ i = k + 1 k i p i / ω 1 = μ T − μ ( k ) 1 − ω ( k ) \omega_0=Pr(C_0)=\sum_{i=1}^{k}p_i=\omega(k) \\ \omega_1=Pr(C_1)=\sum_{i=k+1}^{L}p_i=1-\omega(k) \\ \mu_0=\sum_{i=1}^{k}i Pr(i|C_0)=\sum_{i=1}^{k}ip_i/\omega_0=\mu(k)/\omega(k) \\ \mu_1=\sum_{i=k+1}^{L}i Pr(i|C_1)=\sum_{i=k+1}^{k}ip_i/\omega_1=\frac{\mu_T-\mu(k)}{1-\omega(k)} ω0=Pr(C0)=i=1∑kpi=ω(k)ω1=Pr(C1)=i=k+1∑Lpi=1−ω(k)μ0=i=1∑kiPr(i∣C0)=i=1∑kipi/ω0=μ(k)/ω(k)μ1=i=k+1∑LiPr(i∣C1)=i=k+1∑kipi/ω1=1−ω(k)μT−μ(k)

  • ω ( k ) \omega(k) ω(k)和 μ ( k ) \mu(k) μ(k)分别为灰度级从1到 k k k的累计出现概率和平均灰度级;
  • μ T \mu_T μT为整张图像的平均灰度级。

容易证得,对于任意 k k k值均有:
ω 0 μ 0 + ω 1 μ 1 = μ T , ω 0 + ω 1 = 1 \omega_0\mu_0+\omega_1\mu_1=\mu_T, \omega_0+\omega_1=1 ω0μ0+ω1μ1=μT,ω0+ω1=1

这两类得类内方差也可以算得:
σ 0 2 = ∑ i = 1 k ( i − μ 0 ) 2 P r ( i ∣ C 0 ) = ∑ i = 1 k ( i − μ 0 ) 2 p i / ω 0 σ 1 2 = ∑ i = k + 1 L ( i − μ 1 ) 2 P r ( i ∣ C 0 ) = ∑ i = k + 1 L ( i − μ 1 ) 2 p i / ω 1 \sigma_0^2=\sum_{i=1}^{k}(i-\mu_0)^2Pr(i|C_0)=\sum_{i=1}^{k}(i-\mu_0)^2p_i/\omega_0 \\ \sigma_1^2=\sum_{i=k+1}^{L}(i-\mu_1)^2Pr(i|C_0)=\sum_{i=k+1}^{L}(i-\mu_1)^2p_i/\omega_1 σ02=i=1∑k(i−μ0)2Pr(i∣C0)=i=1∑k(i−μ0)2pi/ω0σ12=i=k+1∑L(i−μ1)2Pr(i∣C0)=i=k+1∑L(i−μ1)2pi/ω1

为了评价阈值 k k k的好坏,需要引入判别式:
λ = σ B 2 / σ W 2 , κ = σ T 2 / σ W 2 , η = σ B 2 / σ T 2 ( 1 ) \lambda=\sigma_B^2/\sigma_W^2, \kappa=\sigma_T^2/\sigma_W^2, \eta=\sigma_B^2/\sigma_T^2 \qquad (1) λ=σB2/σW2,κ=σT2/σW2,η=σB2/σT2(1)

其中

  • σ W 2 = ω 0 σ 0 2 + ω 1 σ 1 2 \sigma_W^2=\omega_0\sigma_0^2+\omega_1\sigma_1^2 σW2=ω0σ02+ω1σ12,即类内方差
  • σ B 2 = ω 0 ( μ 0 − μ T ) 2 + ω ( μ 1 − μ T ) 2 = ω 0 ω 1 ( μ 1 − μ 0 ) 2 \sigma_B^2=\omega_0(\mu_0-\mu_T)^2+\omega(\mu_1-\mu_T)^2=\omega_0\omega_1(\mu_1-\mu_0)^2 σB2=ω0(μ0−μT)2+ω(μ1−μT)2=ω0ω1(μ1−μ0)2,即类间方差
  • σ T 2 = ∑ i = 1 L ( i − μ T ) 2 p i \sigma_T^2=\sum_{i=1}^{L}(i-\mu_T)^2p_i σT2=∑i=1L(i−μT)2pi,即灰度级的总方差

由于 σ W 2 + σ B 2 = σ T 2 \sigma_W^2+\sigma_B^2=\sigma_T^2 σW2+σB2=σT2始终成立,而对同一张图片来说 σ T 2 \sigma_T^2 σT2是确定的,所以 σ W 2 \sigma_W^2 σW2和 σ B 2 \sigma_B^2 σB2,一个越大,另一个就会越小。这样的话,(1)式中的三个目标值 λ , κ , η \lambda, \kappa, \eta λ,κ,η就总是同向运动的。

但是从计算简单程度上来说,因为 σ T 2 \sigma_T^2 σT2与 k k k无关,且 σ B 2 \sigma_B^2 σB2只涉及均值的运算。因此, η \eta η是判别 k k k取值好坏的最简单的衡量标准:
η = σ B 2 ( k ) / σ T 2 \eta = \sigma_B^2(k)/\sigma_T^2 η=σB2(k)/σT2

因此,最佳的 k k k值选择( k ∗ k^* k∗)满足:
σ B 2 ( k ∗ ) = max ⁡ 1 ≤ k ≤ L σ B 2 ( k ) \sigma_B^2(k^*)=\max_{1\leq k \leq L}\sigma_B^2(k) σB2(k∗)=1≤k≤LmaxσB2(k)

在OpenCV中的实现

固定阈值

固定阈值可以在OpenCV中用adptiveThreshold()函数来实现,其函数原型如下:

cpp 复制代码
void cv::adptiveThreshold(	InputArray	src,
							OutputArray	dst,
							double		maxValue,
							int			adaptiveMethod,
							int			thresholdType,
							int			blockSize,
							double		C)

将其中的第5个参数thresholdType指定为THRESH_BINARY就是固定阈值方法。

Otsu算法

Otsu算法可以在OpenCV中用threshold()函数来实现,其函数原型如下:

cpp 复制代码
double cv::threshold(	InputArray	src,
						OutputArray	dst,
						double		thresh,
						double		maxval,
						int			type)

将其中的第5个参数type指定为THRESH_OTSU就是Otsu算法。

这个函数也可以用来通过将该参数指定为THRESH_BINARY来使用固定阈值的方法。

以下是Otsu算法的一个结果示例(上:原图,中:直方图,下:二值化后的结果):

直方图中的红色竖线为Otsu算法找出的最佳阈值。


  1. Otsu N. A Threshold Selection Method From Gray-Level Histogram. IEEE Transactions On Systems Man Cybernetics , 1979, 9(1): 62-66. ↩︎
相关推荐
Zhao-Jichao2 小时前
AI Prompting for Everyone 课程笔记 - P21 总结 Conclusion
人工智能·笔记
欢欢李2 小时前
【LTE L3 笔记 05】LTE同步信号
笔记·无线通信·物理层·lte·空口协议
La Pulga4 小时前
【FreeRTOS源码学习笔记】空闲任务与阻塞延时
笔记·mcu·学习·嵌入式·freertos·实时操作系统
蒸蒸yyyyzwd4 小时前
秋招学习笔记 day106
笔记·学习
小李不想当小白5 小时前
WDG看门狗(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
欢欢李6 小时前
【LTE L3 笔记 04】LTE帧结构
笔记·无线通信·物理层·lte·空口协议
Zhao-Jichao8 小时前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记
lisw059 小时前
作为人类代理的大语言模型及其角色分类!
人工智能·学习·语言模型
Z21-X9 小时前
云原生运维实战笔记:企业网站综合上云部署与云运维服务全景解析
运维·笔记·学习·云原生
坤坤子吖9 小时前
Linux网络编程:UDP进阶,从字典服务器到简单聊天室
linux·服务器·网络·c++·笔记·学习