如何在黑白页面上将文本与纸张分开?

计算科学 Python 离散化 图像处理
2021-12-14 00:18:38

我试图将图像离散化为黑白并遇到一些困难。字母和纸之间的区别在我们眼中非常清楚:

在此处输入图像描述

然而,一个简单的阈值技巧不起作用。在这里,我们将强度低于 0.4 的所有内容移至 0,将强度高于 0.4 的所有内容移至 1:

在此处输入图像描述

现在让我们尝试将阈值移动到 0.5 并且会出现一些令人讨厌的伪影:

在此处输入图像描述

我希望我可以采用试验 1 或试验 2 的“两全其美”。这是我使用的 Python 代码......基本上是介绍性教程,但有一些变化:

from skimage import io
from skimage import color
import numpy as np

import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['figure.figsize'] = 7,7

poem = io.imread('IMG_20151120_113157.jpg')
io.imshow(poem)
io.show()

poem_gray = color.rgb2gray(poem)

t = 0.5
poem_gray[poem_gray < t] = 0
poem_gray[poem_gray > t] = 1
io.imshow(poem_gray)
io.show()

这是我图像中黑白的直方图,以证明我的阈值约为0.45 我的眼睛在欺骗我!一些“白色部分”与文字一样暗。有没有更标准的方法来分离灰度图像?

在此处输入图像描述

2个回答

我相信这里最好的方法是使用基于图像局部平均亮度的阈值。将阈值设置为围绕每个像素的 11x11 网格的平均值的 90% 可以得到与您对这种低分辨率图像的预期一样好的结果。

阈值黑白图像

对于每个像素,您只需要计算它附近像素的平均亮度。然后,如果像素的亮度小于 0.9(或您选择的某个阈值)乘以平均值,则将其设置为黑色,否则将其设置为白色。

@DougLipinski 的回答是绝对正确的。

当您说这个问题“对我们来说非常清楚”时,您发现了一个关键线索:了解人类视觉是学习计算机视觉的好途径。在这种情况下,知道人类视觉擅长处理局部对比度意味着如果“除局部对比度之外的所有内容”被删除,计算机可能会做得更好。

但是,让我们从一个简单的问题开始考虑解决此类问题的一般方法:当已知方法不能令人满意时,如何为特定情况找到好的图像处理算法?

一个很好的方法是找到一种工具,可以轻松地以交互方式尝试一堆算法。我最喜欢的是ImageJ,它的工具范围从优雅的简单到令人费解的复杂。许多是内置的,还有更多可作为插件使用。

在这种特定情况下,半径为 5 的均值偏移滤波器应该可以做得很好。

找到满足您特定需求的算法后,您可以查看其 ImageJ 源代码,或搜索算法名称以找到您选择的语言的实现。

对我来说,该语言通常是 Python,通过 OpenCV 或 PIL(Python 成像库),或 SciKit-Image,或 Pillow,或者有时是 ImageMagick 的 Python 绑定,具体取决于哪个包最能处理特定的工作流程(提供图像,以及接下来需要发生的事情)。