Tesseract OCR with Python

pytesseract openCV

Posted by Surflyan on 2017-08-05

本博客介绍了python 语言下tesseract的使用以及使用openCV对图片进行简单的预处理。


1. 安装pytesseract

首先安装Pillow,一个对python更加友好的PIL端口,pytesseract对其有依赖。

$ pip install pillow
$ pip install pytesseract

注意 : 在pytesseract的github项目, 可以发现 pytesseract 并不是一个真正的 python 绑定,只是一个tesseract.exe 的简单调用。


2. 使用openCV 预处理

以如下数字验证码为例:

首先直接使用 tesseract 识别

>tesseract test2.png stdout
Warning. Invalid resolution 0 dpi. Using 70 instead.
Detected 32 diacritics
" Tess茅ra鈥榗't Will
Fail With Noisy
Backgrounds

可以发现,识别效果并不理想。

观察验证码,彩色图像,噪点很多,采用如下措施预先处理:

from PIL import Image
import pytesseract
import cv2

img=cv2.imread('test1.png')
img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_blur=cv2.medianBlur(img_gray,3)
ret,img_thresh=cv2.threshold(img_blur,100,255,cv2.THRESH_BINARY)
cv2.imshow('img_thresh',img_thresh)
cv2.waitKey()
cv2.destroyAllWindows()

预处理过后:

此时测试

>tesseract img_thresh.png stdout
Warning. Invalid resolution 0 dpi. Using 70 instead.
Tesseract Will
Fail With Noisy
Backgrounds

预处理效果显著,准确识别。


3. 使用pytesseract

pytesseract 主要通过image_to_string 函数进行识别,函数原型为:

 image_to_string(image, lang=none, boxes=false, config=none):
 # image,lang="language",config="-psm PageMode"

注意 :参数image需要传入RGB协议打开的图片,Image.open()是以RGB协议打开的,而cv2.imread()是以BGR协议打开的。
这里一般有两种处理方法:

  1. 使用如下语句转换:
    #o convert the color.
    img = cv2.imread("path/to/img.png")
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    im_pil = Image.fromarray(img)
    
  2. 使用opencv打开并处理之后再保存图片后,以Image.open()打开。
    img=cv2.imread("path/to/img.png")
    # After processed
    cv2.imwrite(filename,pic)
    img=Image.open("path/to/finename")
    

4. 一点经验

  1. 若要识别特定数字或者字母,可建立对应的字符白名单。

    若待识别字母只有 “123abc”,我们可建立相应的白名单 letters

  • 选择目录 /usr/share/tesseract-ocr/tessdata/configs
  • 建立空白文件 letters,添加 tessedit_char_whitelist 123abc
  • 执行:> tesseract input_file_name stdout letters

    此时会以letters里的字符去识别,大大提高识别准确率。
    如果还要以pytesseract处理,可在pytesseract.py原码里的run_tesseract函数中语句做如下替换:

      if lang is not None:
          command += ('-l', lang)
      #替换为
        if lang is not None:
          command += (lang)
    
    # 稍作观察原码,就能知道这么做的原因。
    

    在python代码中,做如下调用即可:
    text=pytesseract.image_to_string(img,lang="letters")

  1. 建立替换表,在实际应用中能发挥很大的作用。

    如在应用中常常将“2”识别为”Z”,而原材料中又不会出现”Z”时,可将”Z”替换为”2”。

    def text2string(img):
     rep={'Z':'2',
            'A':'8'}
    text=image_to_string(img)
    for c in rep:
        text=text.replace(c,rep[c])
    return text
    

Reference

  1. http://www.pyimagesearch.com/2017/07/10/using-tesseract-ocr-python/

  2. http://wrfly.kfd.me/%E6%95%B0%E5%AD%97%E9%AA%8C%E8%AF%81%E7%A0%81%E8%AF%86%E5%88%AB/

请多多指教!