是否有更好的方法将文字与背景分开?

时间:2018-10-31 21:34:12

标签: python opencv ocr image-thresholding

我正在一个项目上进行申请,并在一些文档上进行了OCR。
第一步是对图像进行阈值处理,只允许书写(使背景变白)。

输入图像的示例:出于GDPR和隐私原因,该图像来自互联网

enter image description here 这是我的代码:

import cv2
import numpy as np


image = cv2.imread('b.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
h = image.shape[0]
w = image.shape[1]
for y in range(0, h):
    for x in range(0, w):
        if image[y, x] >= 120:
            image[y, x] = 255
        else:
            image[y, x] = 0
cv2.imwrite('output.jpg', image)

这是我得到的结果:

enter image description here

当我将 pytesseract 应用于输出图像时,结果并不令人满意(我知道OCR并不完美)。尽管我尝试调整阈值(在此代码中为120),但结果并没有达到我想要的清晰。

是否有一种方法可以使阈值更好,以便仅使其余部分保持黑色和白色?

2 个答案:

答案 0 :(得分:2)

深入研究Stack Overflow 问题后,我发现this answer与使用opencv删除水印有关。 我根据自己的需要修改了代码,这就是我得到的:

import numpy as np
import cv2


image = cv2.imread('a.png')
img = image.copy()

alpha =2.75
beta = -160.0

denoised = alpha * img + beta
denoised = np.clip(denoised, 0, 255).astype(np.uint8)

#denoised = cv2.fastNlMeansDenoising(denoised, None, 31, 7, 21)

img = cv2.cvtColor(denoised, cv2.COLOR_BGR2GRAY)

h = img.shape[0]
w = img.shape[1]

for y in range(0, h):
    for x in range(0, w):
        if img[y, x] >= 220:
            img[y, x] = 255
        else:
            img[y, x] = 0

cv2.imwrite('outpu.jpg', img)

这是输出图像:

enter image description here

此代码的优点是,它不仅对这张图片,而且对我测试过的所有图片都给出了很好的结果。

我希望它可以帮助遇到相同问题的任何人。

答案 1 :(得分:1)

您可以使用adaptive thresholding。从文档中:

  

在这种情况下,算法会为图像的一小部分计算阈值。因此,对于同一图像的不同区域,我们获得了不同的阈值,对于光照度不同的图像,它可以提供更好的结果。

import numpy as np
import cv2



image = cv2.imread('b.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.medianBlur(image ,5)

th1 = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY,11,2)
th2 = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv2.THRESH_BINARY,11,2)
cv2.imwrite('output1.jpg', th1 )
cv2.imwrite('output2.jpg', th2 )