图像预处理之二值化全局阈值方法(OCR处理方法)

二值化

图像二值化是将像素点的灰度值设为0255,使图像呈现明显的黑白效果。

好处:
减少数据维度
排除原图中噪声带来的干扰
凸显有效区域的轮廓范围
对于OCR来说,高质量二值图像可以显著提升识别的准确率

全局阈值方法

固定阈值方法 对于输入图像中的所有像素点统一使用同一个固定阈值

在这里插入图片描述

其中的T为全局阈值。 固定阈值方法的主要缺陷:很难为不同输入的图像确定最佳阈值

Otsu算法

Otsu算法又称最大类间方差法,是一种自适应的阈值确定方法
我们将输入的图像视为L个灰度级,ni表示灰度级为i的像素个数,这里可以使用归一化的灰度直方图

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210411124208207.png

现在假设在第k个灰度级设置阈值,将图像二分为两部分,一部分是灰度级为[1,…,k]的像素点,另一部分表示[k+1,…L]的像素点,那么两类出现的概率以及类内灰度级的均值分别为:

图像预处理之二值化全局阈值方法(OCR处理方法)_第1张图片

其中的w(k)和u(k)分别为灰度级从1到k的累积出现概率和平均灰度级,而ut则是整张图像的平均灰度级。我们很容易可以验证,对于任意K值均有:

在这里插入图片描述

这两类的类内方差由以下两个公式给出:

在这里插入图片描述

为了评价阈值k的好坏,我们需要引入判别式,根据判别式的标准来进行测量:

在这里插入图片描述

其中,

图像预处理之二值化全局阈值方法(OCR处理方法)_第2张图片

等号左边的三个不平方的话分别就是类内方差、类间方差、灰度级的总方差。现在,我们将问题转化为一个优化问题,即找到一个k,使其能够最大化式中的目标函数。我们注意到以下关系始终存在:

在这里插入图片描述

并且前两个数都是K的函数,而它们的和却与k无关,我们还注意到第一个数是基于类方差,而第二个数是基于类均值。因此,η是判别k取值好坏的最简单的衡量标准:

在这里插入图片描述

至此,我们得到了最佳的K值选择,

在这里插入图片描述

为了更加形象地解释Otsu算法,我们下面用代码将两张输入图像的灰度图直方图以及得到的结果阈值绘制出来。

代码实现

import cv2
import matplotlib.pyplot as plt
image = cv2.imread("D:/train_data/ic15_data/test/img_0000004.jpg")
#讲输入的图像转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#绘制灰度图
plt.subplot(311), plt.imshow(gray, "gray")
plt.title("input image"), plt.xticks([]), plt.yticks([])
#对比灰度图使用Ostu算法
ret1, th1 = cv2.threshold(gray.ravel(), 256)
#绘制灰度直方图
plt.subplot(312), plt.hist(gray.ravel(), 256)
#标注Ostu阈值所在直线
plt.axvline(x=ret1, color='red', label='otsu')
plt.legend(loc='upper right')
plt.title("Histogram"), plt.xticks([]), plt.yticks([])
#绘制二值化图像
plt.subplot(313),plt.imshow(th1, "gray")
plt.title("output image"), plt.xticks([]), plt.yticks([])
plt.show()

图像预处理之二值化全局阈值方法(OCR处理方法)_第3张图片

对于灰度直方图呈现两个峰值的图像,Otsu算法所得到的阈值为峰值间的低估位置,二值化效果也比较好,然而当目标物体与背景大小比例悬殊或灰度级接近,导致直方图呈现三峰或双峰峰值差距极大时,Otsu算法往往得不到满意的结果,因为单独将灰度分布作为设置阈值的依据,不仅会让结果对于噪声极其敏感,还容易丢失重要空间结构关系。Otsu算法比较简单易懂,所以OpenCV库对其封装调用。当然在实际应用中,Otsu算法常与其他方法组合使用。

你可能感兴趣的:(PaddleOCR实战创建问题,算法,opencv,ocr,自然语言处理,机器学习)