使用OpenCV预处理Tesseract OCR的图像

Mau*_*cio 23 ocr opencv tesseract image-processing

我正在尝试开发一个应用程序,它使用Tesseract识别手机摄像头拍摄的文档中的文本.我正在使用OpenCV预处理图像以便更好地识别,应用高斯模糊和阈值方法进行二值化,但结果非常糟糕.

是我用于测试的图像: 在此输入图像描述

这里的预处理图像: 在此输入图像描述

我可以使用其他过滤器来使Tesseract的图像更具可读性吗?

Ale*_*x I 45

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

在你的例子中,有几件事正在发生......

您需要将文本设置为黑色,将图像的其余部分设置为白色(而不是相反).这就是字符识别的基础.灰度是可以的,只要背景大部分是全白的,文字大多是全黑的; 文本的边缘可能是灰色的(抗锯齿),这可能有助于识别(但不一定 - 你必须进行实验)

你看到的一个问题是,在图像的某些部分,文本真的很"薄"(字母中的间隙出现在阈值处),而在其他部分它真的是"厚"(并且字母开始合并).Tesseract不会那样:)它发生的原因是输入图像不均匀点亮,因此单个阈值无处不在.解决方案是进行"局部自适应阈值处理",其中针对图像的每个邻居计算不同的阈值.有很多方法可以做到这一点,但请查看以下内容:

你遇到的另一个问题是线条不直.根据我的经验,Tesseract可以处理非常有限的非直线(透视变形,倾斜或倾斜的百分之几),但它并不适用于波浪线.如果可以,请确保源图像有直线:)不幸的是,没有简单的现成答案; 你必须研究一下研究文献并自己实现一种最先进的算法(如果可能的话,开源它 - 真正需要一种开源解决方案).Google学术搜索" 曲线OCR提取 "将帮助您入门,例如:

最后:我认为使用python生态系统(ndimage,skimage)比使用C++中的OpenCV更好.OpenCV python包装器对于简单的东西是可以的,但是对于你想要做的事情,他们将无法完成这项工作,你将需要抓取许多不在OpenCV中的部分(当然你可以混合搭配).在C++中实现像曲线检测这样的东西比在python中实现要长一个数量级(*即使你不懂python也是如此).

祝好运!

  • 更新链接:[OpenCV 中的自适应高斯阈值](http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html)、[Local Otsu's method](http://sharky93. github.io/docs/dev/auto_examples/plot_local_otsu.html), [局部自适应直方图均衡](http://sharky93.github.io/docs/dev/auto_examples/plot_local_equalize.html) 一个简单的google inurl搜索就可以解决很多断开的链接 (3认同)
  • 您可以更新答案中的外部链接吗?谢谢! (2认同)

Ami*_*aha 18

  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
Run Code Online (Sandbox Code Playgroud)


And*_*oom 5

注意:这应该是对Alex我的回答的评论,但它太长了所以我把它作为答案.

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

"处理遵循传统的逐步管道,但有些阶段在当时是不寻常的,甚至可能在现在仍然如此.第一步是连接组件分析,其中存储组件的轮廓.这是一个当时计算成本高昂的设计决策,但具有显着的优势:通过检查轮廓的嵌套,以及子孙轮廓的数量,检测逆文本并像黑白文本一样容易识别Tesseract可能是第一款能够轻松处理黑白文字的OCR引擎."

因此,似乎不需要在白色背景上使用黑色文本,并且也应该正好相反.