为不均匀照明的扫描页选择局部二值化方法

来源:scikit-image team 维护的 Niblack and Sauvola Thresholding 官方示例。原页没有可确认的个人作者署名与发布日期;本文按 scikit-image 0.26.0 完整翻译整理,并补充参数与结果边界说明。核验日期:2026 年 10 月 5 日。

扫描页的背景并不总是同样明亮:光照变化、纸张阴影或拍摄条件可能使一侧更暗。此时,用一个全局阈值处理整张图,容易把阴影和文字一起划进暗色区域。

Niblack 和 Sauvola 是两种局部阈值方法,适用于背景不均匀的图像,特别是文字图像的预处理。它们不会只为整张图计算一个阈值,而是以每个像素为中心,取一定范围的邻域,利用局部均值和标准差计算该位置的阈值。

官方示例使用同一张扫描页,将这两种方法与常见的全局 Otsu 阈值作比较。window_size 决定局部统计包含的邻域大小。这个任务到二值图为止,没有进行字符识别、版面恢复或 OCR 准确率评估。

输入与三个对照

代码通过 skimage.data.page() 读取内置示例。v0.26.0 的数据加载源码将它标为用于演示不均匀背景照明的扫描页,返回形状为 (191, 384)、类型为 uint8 的二维灰度数组,对应 data/page.png。

三个对照分别是:

  • Otsu:从整张灰度图计算一个阈值,对所有像素使用相同界限。
  • Niblack:使用局部阈值,原示例设定 window_size=25、k=0.8。
  • Sauvola:同样使用 window_size=25,其余参数使用 0.26.0 的默认值,即 k=0.2、r=None。

这是一组方法和参数组合的示例比较,不是同一参数下的受控基准,也不能由此认定某个数值适用于所有扫描页。

完整示例代码

下面保留官方 v0.26.0 示例的完整可执行部分,包括字体设置、阈值计算与四宫格绘图。标题保留英文,与附图一致;没有改动算法参数或判断方向。

import matplotlib
import matplotlib.pyplot as plt

from skimage.data import page
from skimage.filters import threshold_otsu, threshold_niblack, threshold_sauvola


matplotlib.rcParams['font.size'] = 9


image = page()
binary_global = image > threshold_otsu(image)

window_size = 25
thresh_niblack = threshold_niblack(image, window_size=window_size, k=0.8)
thresh_sauvola = threshold_sauvola(image, window_size=window_size)

binary_niblack = image > thresh_niblack
binary_sauvola = image > thresh_sauvola
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 7))

axes[0, 0] = plt.subplot(2, 2, 1)
axes[0, 0].imshow(image, cmap=plt.cm.gray)
axes[0, 0].set_title('Original')
axes[0, 0].axis('off')

axes[0, 1] = plt.subplot(2, 2, 2)
axes[0, 1].imshow(binary_global, cmap=plt.cm.gray)
axes[0, 1].set_title('Global Threshold')
axes[0, 1].axis('off')

axes[1, 0] = plt.subplot(2, 2, 3)
axes[1, 0].imshow(binary_niblack, cmap=plt.cm.gray)
axes[1, 0].set_title('Niblack Threshold')
axes[1, 0].axis('off')
axes[1, 1] = plt.subplot(2, 2, 4)
axes[1, 1].imshow(binary_sauvola, cmap=plt.cm.gray)
axes[1, 1].set_title('Sauvola Threshold')
axes[1, 1].axis('off')

plt.show()

代码审查说明:以上代码只做静态检查,未在本任务中导入 scikit-image、计算阈值或调用 plt.show()。原文先创建子图数组,再逐项调用 plt.subplot 赋回对应位置,这里为保留原示例结构而照录;这些重复赋值不是算法必需步骤。

怎样读这张图

官方示例四宫格:原始扫描页、全局Otsu、Niblack和Sauvola二值化结果
scikit-image 0.26.0 官方示例图,直接下载自原站,未重新运行生成。左上为原图,右上为全局阈值,左下为 Niblack,右下为 Sauvola。未把底层 page.png 另行声称为公共领域素材。

在这张官方结果图中,原扫描页左侧较暗。全局阈值把左侧大片背景也变成黑色,遮住了部分文字;Niblack 结果能更好地分离文字与背景,但仍出现散点和线状痕迹;Sauvola 在这组输入与参数下得到较干净的背景。

这只是对该图可见现象的描述。图像“看起来更清楚”不能直接换算成字符识别率,也不能证明 Sauvola 总是优于 Niblack。实际选择仍需观察目标扫描件的细字笔画、阴影区域与背景噪声。

还要注意二值图的方向。原代码使用 image > threshold,所以较亮的像素得到 True,按灰度显示为白色;暗文字通常为 False,显示为黑色。因此,数组中的 True 并不等于“文字像素”。如果下游系统要求文字为真,需要明确转换掩膜约定,而不是仅凭图像外观推断。

窗口和 k 分别控制什么

以下是依据 0.26.0 阈值 API 文档添加的参数解释,属于编辑补充。

以像素邻域的均值为 m、标准差为 s,该实现的 Niblack 形式为 T = m - k × s;Sauvola 为 T = m × [1 + k × (s / R - 1)]。k 控制标准差项的影响;Sauvola 的 R 是标准差动态范围,r=None 时按图像数据类型取值范围的一半设置。

窗口需要采用奇数尺寸,使像素有明确的中心;示例中的 25 即表示二维图像上的 25×25 邻域。调整窗口会改变局部统计覆盖的范围。比较新参数时,应保持输入、数据类型和二值图方向一致,再观察细笔画与背景是否被错误合并或分离。

这里的减号对应 scikit-image 的具体 Niblack 参数约定,不能在照搬其他资料时忽略符号。将 uint8 数据改成浮点图像时,也要同时核对数值缩放和 Sauvola 的 r,不能假定只换类型就与原例等价。

复现范围与许可

研究页给出的建议复现基线为 CPython 3.11、scikit-image 0.26.0、NumPy 2.2.6、SciPy 1.15.3、Matplotlib 3.10.3。它是已有的依赖约束静态核查记录,不代表本次完成了环境锁定、二进制安装或运行验证。本文进一步核对了 0.26.0 官方示例、API 参数和数据入口。

示例只读取演示数据、计算数组并绘图,没有删除文件、修改数据库、上传图像、发送请求内容或使用凭据。处理自己的扫描件时,输入仍需是符合方法要求的灰度数据;这段教程没有提供颜色转换、去倾斜、识字或质量评估的完整流程。

scikit-image v0.26.0 仓库许可文件以 BSD-3-Clause 为总许可,并列出个别文件的例外;完整文本已随稿保存为 LICENSE-scikit-image.txt。代码许可不能自动代替第三方图片许可。底层扫描页在所核查的 page() 说明中没有单独注明作者与许可;本稿保留官方示例图来源,不虚构个人署名。

原文参考文献

  1. W. Niblack,An Introduction to Digital Image Processing,Prentice-Hall,1986。
  2. J. Sauvola、M. Pietikainen,Adaptive document image binarization,Pattern Recognition 33(2),225–236,2000。DOI:10.1016/S0031-3203(99)00055-2。

本文覆盖原示例全部说明、代码和参考文献,并将编辑解释单独标识;配图为官方已有结果,不是本任务实测。没有声称发现全部代码风险或获得 OCR 性能提升。

原始版权与许可全文

Files: *
Copyright: 2009-2022 the scikit-image team
License: BSD-3-Clause

Files: doc/source/themes/scikit-image/layout.html
Copyright: 2007-2010 the Sphinx team
License: BSD-3-Clause
Files: skimage/feature/_canny.py
       skimage/filters/edges.py
       skimage/filters/_rank_order.py
       skimage/morphology/_skeletonize.py
       skimage/morphology/tests/test_watershed.py
       skimage/morphology/watershed.py
       skimage/segmentation/heap_general.pxi
       skimage/segmentation/heap_watershed.pxi
       skimage/segmentation/_watershed.py
       skimage/segmentation/_watershed_cy.pyx
Copyright: 2003-2009 Massachusetts Institute of Technology
           2009-2011 Broad Institute
           2003 Lee Kamentsky
           2003-2005 Peter J. Verveer
License: BSD-3-Clause
Files: skimage/filters/thresholding.py
       skimage/graph/_mcp.pyx
       skimage/graph/heap.pyx
Copyright: 2009-2015 Board of Regents of the University of
           Wisconsin-Madison, Broad Institute of MIT and Harvard,
           and Max Planck Institute of Molecular Cell Biology and
           Genetics
           2009 Zachary Pincus
           2009 Almar Klein
License: BSD-2-Clause
File: skimage/morphology/grayreconstruct.py
      skimage/morphology/tests/test_reconstruction.py
Copyright: 2003-2009 Massachusetts Institute of Technology
           2009-2011 Broad Institute
           2003 Lee Kamentsky
License: BSD-3-Clause
File: skimage/morphology/_grayreconstruct.pyx
Copyright: 2003-2009 Massachusetts Institute of Technology
           2009-2011 Broad Institute
           2003 Lee Kamentsky
           2022 Gregory Lee (added a 64-bit integer variant for large images)
License: BSD-3-Clause

File: skimage/segmentation/_expand_labels.py
Copyright: 2020 Broad Institute
           2020 CellProfiler team
License: BSD-3-Clause

File: skimage/exposure/_adapthist.py
Copyright: 1994 Karel Zuiderveld
License: BSD-3-Clause
Function: skimage/morphology/_skeletonize_various_cy.pyx:_skeletonize_loop
Copyright: 2003-2009 Massachusetts Institute of Technology
           2009-2011 Broad Institute
           2003 Lee Kamentsky
License: BSD-3-Clause

Function: skimage/_shared/version_requirements.py:_check_version
Copyright: 2013 The IPython Development Team
License: BSD-3-Clause

Function: skimage/_shared/version_requirements.py:is_installed
Copyright: 2009-2011 Pierre Raybaut
License: MIT
File: skimage/feature/_fisher_vector.py
Copyright: 2014 2014 Dan Oneata
License: MIT

File: skimage/_vendored/numpy_lookfor.py
Copyright: 2005-2023, NumPy Developers
License: BSD-3-Clause

File: skimage/transform/_thin_plate_splines.py
Copyright: 2007 Zachary Pincus
License: BSD-3-Clause

License: BSD-2-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: BSD-3-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE HOLDERS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License: MIT

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容