对于图片中包含文字文本时的检测,这里采用 OpenCV 和开源 OCR 工具 - Tesseract 进行实现.

文本识别(text recognition),也叫作光学字符识别(Optical Character Recognition, OCR).

1. Tesseract OCR 库

Github - tesseract-ocr/tesseract

Tesseract 4 新增了基于 LSTM 网络的 OCR 引擎,其主要关注于字符行识别(line recogniton). 但仍支持 Tesseract 3 的 OCR 引擎,其工作原理是采用识别字符模式(character patterns).

Tesseract 4 与 Tesseract 3 的兼容,可以采用 Legacy OCR Engine 模式(--oem 0).

Tesseract 库的特点:

[1] - 支持 unicode(UTF-8),可识别超过 100 中语言.

[2] - 支持多种不同的输出格式:plain text, hOCR (HTML), PDF, invisible-text-only PDF, TSV,以及 ALTO (XML) (测试中).

[3] - 为了更好的得到 OCR 结果,可以提升输入到 Tesseract 的图片的质量 - improve the quality of the image.

[4] - 暂不支持 GUI 应用,需要结合第三方库.

1.1. Tesseract 安装

主要包括:

[1] - Tesseract 库 (libtesseract)

[2] - Tesseract 命令行工具 (tesseract-ocr)

[3] - Tesseract Python 封装接口 (pytesseract)

# Ubuntu16.04 默认是 3.04 版本
# 添加 tesseract 4.0 版本的源
sudo add-apt-repository ppa:alex-p/tesseract-ocr
sudo apt-get update
sudo apt-get install tesseract-ocr
sudo apt-get install libtesseract-dev
sudo pip install pytesseract # pip3 

查看 tensseract 版本:

# tesseract --help
tesseract --version
tesseract 4.1.0-rc1-95-g3baf
 leptonica-1.76.0
  libgif 5.1.4 : libjpeg 8d (libjpeg-turbo 1.4.2) : libpng 1.2.54 : libtiff 4.0.6 : zlib 1.2.8 : libwebp 0.4.4 : libopenjp2 2.1.2
 Found AVX2
 Found AVX
 Found SSE

2. Tesseract 基本使用

Tesseract 提供了命令行工具,或者将 Tesseract Python API.

https://github.com/tesseract-ocr/tesseract/wiki/Command-Line-Usage#simplest-invocation-to-ocr-an-image

最基本的使用需要指定的参数有:

[1] - 输入图片路径,如/path/to/test_image.jpg.

[2] - OCR 识别的语言

# 查看支持的语言:
tesseract --list-langs
# 输出:
#     List of available languages (2):
#     eng
#     osd

[3] - OCR Engine Mode(oem),OCR 引擎模式.

Tesseract 4 支持两种 OCR 引擎:

--oem 0 for Legacy Tesseract;

--oem 1 for LSTM;

--oem 2 for Legacy + LSTM engines.

--oem 3 for Default, based on what is available.

[4] - Page Segmentation Mode (psm)

tesseract --help-psm

输出:

Page segmentation modes:
  0    Orientation and script detection (OSD) only.
  1    Automatic page segmentation with OSD.
  2    Automatic page segmentation, but no OSD, or OCR. (not implemented)
  3    Fully automatic page segmentation, but no OSD. (Default)
  4    Assume a single column of text of variable sizes.
  5    Assume a single uniform block of vertically aligned text.
  6    Assume a single uniform block of text.
  7    Treat the image as a single text line.
  8    Treat the image as a single word.
  9    Treat the image as a single word in a circle.
 10    Treat the image as a single character.
 11    Sparse text. Find as much text as possible in no particular order.
 12    Sparse text with OSD.
 13    Raw line. Treat the image as a single text line,
       bypassing hacks that are Tesseract-specific.

当已知文本结构的其它信息时,PSM 参数会非常有用.

:当未指定 PSM 参数时,在命令行和 Python 接口的使用中默认是 3,但在 C++ 接口中默认是 6.

2.1. 命令行使用

如:

测试图片:

image

# 在终端打印文本识别结果
tesseract image.jpg stdout -l eng --oem 1 --psm 3
# 将文本识别结果保存到 output.txt 文件。 
tesseract image.jpg output -l eng --oem 1 --psm 3

终端打印的输出:

THE

RECOMMENDED

VOGUE

2.2. Python中使用

如:

#!/usr/bin/python3
#!--*-- coding:utf-8 --*--
import cv2
import pytesseract
from PIL import Image, ImageDraw
import numpy as np
import matplotlib.pyplot as plt

 
if __name__ == '__main__':
    img_file = "/path/image.jpg"
    
    # 配置参数
    # '-l eng'  for using the English language
    # '--oem 1' for using LSTM OCR Engine
    config = ('-l eng --oem 1 --psm 3')
    
    # 读取图片文件
    img_cv2 = cv2.imread(img_file, cv2.IMREAD_COLOR)
    
    # tesseract OCR 识别图片中的英文字符;
    # 并打印结果
    text = pytesseract.image_to_string(img_cv2, config=config)
    print(text)
    
    # tesseract OCR 识别图片中的英文字符,同时给出各字符的框;
    # 并打印结果
    text_with_bbox = pytesseract.image_to_boxes(img_cv2, config=config)
    print(text_with_bbox)
    
    # 图片上显示字符框
    text_with_bbox = []
    text_with_bbox_split = text_with_bbox_str.split("\n")
    draw = ImageDraw.Draw(img_pil)
    height, width = img_pil.height, img_pil.width
    for tmp_split_str in text_with_bbox_split:
        text_char = tmp_split_str.split(" ")[0]
        if text_char.isalpha():
            left, top, right, bottom, _ = 
                list(map(int, tmp_split_str.split(" ")[1:]))
            print(left, top, right, bottom)
            draw.rectangle(
                (left, height-top, right, height-bottom), 
                None, 
                "blue", 
                1)

    plt.figure(figsize=(12, 8))
    plt.imshow(img_pil)
    plt.axis('off')
    plt.show()

输出如下:

# 文本识别结果:
THE

RECOMMENDED

VOGUE

# 文本及字符框识别结果:
T 565 664 575 675 0
H 592 664 600 675 0
E 617 664 624 675 0
R 257 664 265 675 0
E 282 664 289 675 0
C 306 664 316 675 0
O 333 664 344 675 0
M 361 664 371 674 0
M 389 664 400 675 0
E 417 664 424 675 0
N 442 664 452 675 0
D 437 664 484 675 0
E 469 664 478 675 0
D 495 664 528 675 0
V 104 665 113 675 0
O 129 664 140 675 0
G 157 664 168 675 0
U 156 664 198 675 0
E 185 664 219 675 0

image

3. 参考资料

[1] - Deep Learning based Text Recognition (OCR) using Tesseract and OpenCV - 2018.06.06

[2] - Github - spmallick/learnopencv

[3] - Github - tesseract-ocr/tesseract

[4] - Tesseract-OCR识别中文与训练字库实例

Last modification:April 23rd, 2019 at 09:00 pm