使用OpenCV的Tesseract OCR的预处理图像
image-processing
ocr
opencv
5
0

我正在尝试开发一个使用Tesseract来识别手机摄像头拍摄的文档中的文本的应用程序。我正在使用OpenCV对图像进行预处理以获得更好的识别效果,并应用了高斯模糊和Threshold方法进行二值化,但是结果非常糟糕。

是我用于测试的图像: 在此处输入图片说明

是经过预处理的图像: 在此处输入图片说明

我可以使用其他哪些滤镜使Tesseract更具可读性?

参考资料:
Stack Overflow
收藏
评论
共 3 个回答
高赞 时间 活跃

我在这里介绍了一些为Tesseract准备图像的技巧: 使用tesseract识别车牌

在您的示例中,发生了几件事...

您需要使文本为黑色,图像的其余部分为白色( 而不是相反)。这就是调整字符识别的方式。只要背景多为全白,文本多为全黑,则灰度就可以 。文字的边缘可能是灰色的(抗锯齿), 可能有助于识别(但不一定-您必须进行实验)

您所看到的问题之一是,在图像的某些部分中,文本确实“很细”(阈值后显示字母中的空白),而在其他部分中,文本确实很“粗”(字母开头合并)。 Tesseract不会喜欢:)之所以会这样,是因为输入图像的照明不均匀,所以单个阈值不适用于任何地方。解决方案是执行“局部自适应阈值化”,其中为图像的每个邻域计算一个不同的阈值。有很多方法可以做到这一点,但请查看以下示例:

您遇到的另一个问题是直线不是直线。以我的经验,Tesseract可以处理非常有限程度的非直线(透视变形,倾斜或偏斜的百分之几),但它不适用于波浪线。如果可以,请确保源图像具有直线:)不幸的是,对此没有简单的现成答案;请参见图5。您必须研究一下研究文献并自己实现一种最先进的算法(并在可能的情况下将其开源-确实需要为此提供开源解决方案)。使用Google学术搜索搜索“ 曲线OCR提取 ”将使您入门,例如:

最后:我认为使用python生态系统(ndimage,skimage)比使用C ++中的OpenCV要好得多。 OpenCV python包装器适合简单的东西,但是对于您尝试做的事情,它们将无法完成工作,您将需要抓取许多OpenCV中没有的部分(当然,您可以混合使用)。在C ++中实现诸如曲线检测之类的操作所需的时间要比python长一个数量级(*即使您不了解python,也是如此)。

祝好运!

收藏
评论
  1. 正式地,以300 dpi(每英寸的点数)进行扫描并不是OCR(光学字符识别)的标准,但它被认为是金标准。

  2. 通常,将图像转换为灰度可以提高阅读文本的准确性。

我编写了一个模块,该模块读取Image中的文本,然后再从OCR, Image Text Reader中处理图像以获得最佳结果。

import tempfile

import cv2
import numpy as np
from PIL import Image

IMAGE_SIZE = 1800
BINARY_THREHOLD = 180

def process_image_for_ocr(file_path):
    # TODO : Implement using opencv
    temp_filename = set_image_dpi(file_path)
    im_new = remove_noise_and_smooth(temp_filename)
    return im_new

def set_image_dpi(file_path):
    im = Image.open(file_path)
    length_x, width_y = im.size
    factor = max(1, int(IMAGE_SIZE / length_x))
    size = factor * length_x, factor * width_y
    # size = (1800, 1800)
    im_resized = im.resize(size, Image.ANTIALIAS)
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.jpg')
    temp_filename = temp_file.name
    im_resized.save(temp_filename, dpi=(300, 300))
    return temp_filename

def image_smoothening(img):
    ret1, th1 = cv2.threshold(img, BINARY_THREHOLD, 255, cv2.THRESH_BINARY)
    ret2, th2 = cv2.threshold(th1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    blur = cv2.GaussianBlur(th2, (1, 1), 0)
    ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return th3

def remove_noise_and_smooth(file_name):
    img = cv2.imread(file_name, 0)
    filtered = cv2.adaptiveThreshold(img.astype(np.uint8), 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 41,
                                     3)
    kernel = np.ones((1, 1), np.uint8)
    opening = cv2.morphologyEx(filtered, cv2.MORPH_OPEN, kernel)
    closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
    img = image_smoothening(img)
    or_image = cv2.bitwise_or(img, closing)
    return or_image
收藏
评论

注意:这应该是我回答的Alex的评论,但这太长了,因此我将其作为回答。

摘自“ Google公司Ray Smith的Tesseract OCR引擎概述”。在https://github.com/tesseract-ocr/docs/blob/master/tesseracticdar2007.pdf

“处理过程遵循传统的循序渐进的流程,但是某些阶段在当时是不寻常的,甚至到现在仍可能如此。第一步是连接组件分析,其中存储了组件的轮廓。这是一个当时在计算上需要昂贵的设计决策,但具有显着的优势:通过检查轮廓的嵌套以及子轮廓和孙轮廓的数量,可以很容易地检测出反向文本并将其识别为黑白文本一样容易Tesseract可能是第一个能够如此轻松地处理黑白文本的OCR引擎。”

因此,似乎不需要在白色背景上显示黑色文本,并且也应该相反。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号