菜单

OCR 管道

相关源文件

本文档描述了 Tesseract 中的 OCR(光学字符识别)管道,从图像输入到文本输出。它涵盖了识别图像中的文本时发生的关键处理步骤,包括预处理、页面分割、识别和后处理。

有关特定识别引擎的更多详细信息,请参阅 识别引擎。有关输出渲染的详细信息,请参阅 输出渲染器

OCR 管道概述

上图显示了 Tesseract OCR 管道的高级步骤。该过程以输入图像开始,经过各种分析和识别阶段,最终生成文本输出。

来源: src/api/baseapi.cpp759-842 src/ccmain/tesseractclass.h179-390

图像输入与预处理

OCR 管道的第一步是图像采集和预处理。

图像采集

Tesseract 可以通过 TessBaseAPI::SetImage 方法接受各种格式的图像

  • 直接像素数据,使用 SetImage(const unsigned char*, int, int, int, int)
  • PIX 格式,使用 SetImage(Pix*)

图像可以是灰度(每像素 8 位)、彩色(每像素 24 或 32 位)或二值(每像素 1 位)。

阈值处理

ImageThresholder 类负责将图像转换为二值格式,这对 OCR 至关重要。Tesseract 提供了三种阈值处理方法:

  1. Otsu - 传统的全局阈值处理算法
  2. LeptonicaOtsu - Leptonica 对 Otsu 的实现,并附带其他选项
  3. Sauvola - 自适应阈值处理方法,在背景光照变化较大的情况下效果更好

阈值处理过程会生成一个二值图像,将文本像素与背景分离。此图像成为所有后续处理的基础。

来源: src/ccmain/thresholder.cpp181-274 src/ccstruct/otsuthr.cpp27-35

页面分割

预处理完成后,Tesseract 会分析图像的布局以识别文本区域。

页面分割过程由 tessedit_pageseg_mode 参数控制,该参数可以设置为不同的值:

模式描述
PSM_OSD_ONLY仅进行方向和脚本检测
PSM_AUTO_OSD自动页面分割,包含方向和脚本检测
PSM_AUTO自动页面分割,但不进行 OSD 或 OCR
PSM_SINGLE_COLUMN将图像视为单栏文本
PSM_SINGLE_BLOCK将图像视为单个文本块
PSM_SINGLE_LINE将图像视为单行文本
PSM_SINGLE_WORD将图像视为单个单词
PSM_SINGLE_CHAR将图像视为单个字符
PSM_SPARSE_TEXT尽可能多地查找文本,不考虑顺序
PSM_RAW_LINE将图像视为单行文本,绕过 Tesseract 特定的 hack

页面分割过程会生成一个 BLOCK_LIST,其中包含已识别的文本和其他内容的区域。然后对这些块进行进一步处理以查找行、单词和字符。

FindLines() 方法将块分割成行,创建一个包含分割和文本识别结果的 PAGE_RES 对象。

来源: src/ccmain/pagesegmain.cpp101-402 src/api/baseapi.cpp436-441

文本识别

分割完成后,Tesseract 会继续识别每个片段中的文本。

识别引擎

Tesseract 有两个主要的识别引擎:

  1. LSTM 神经网络引擎 - 基于现代神经网络的识别,通常能提供更高的准确性
  2. 旧版 Tesseract 引擎 - 传统的基于特征的识别系统

使用的引擎由 tessedit_ocr_engine_mode 参数决定。

模式描述
OEM_TESSERACT_ONLY仅使用旧版 Tesseract 引擎
OEM_LSTM_ONLY仅使用 LSTM 神经网络
OEM_TESSERACT_LSTM_COMBINED同时使用两种引擎并合并结果
OEM_DEFAULT基于可用情况的默认设置

LSTM 识别过程

在使用 LSTM 引擎时:

  1. 对图像行进行预处理并输入神经网络。
  2. 调用 LSTMRecognizer::RecognizeLine() 来处理图像。
  3. 网络生成字符概率。
  4. RecodeBeamSearch 寻找最可能的字符序列。
  5. 结果转换为带有置信度的文本。

旧版引擎识别过程

在使用旧版引擎时:

  1. 调用 classify_word_pass1() 来处理单词。
  2. 从图像中提取特征。
  3. 自适应分类器将特征与字符原型匹配。
  4. 单词识别将字符组合成单词。
  5. 计算置信度。

来源: src/api/baseapi.cpp825-842 src/lstm/lstmrecognizer.cpp245-267

词典与后处理

在初步识别后,Tesseract 会应用基于词典的校正和其他后处理步骤。

词典校正

Tesseract 中的词典系统通过以下方式帮助提高识别准确性:

  1. 在词典中查找单词
  2. 纠正常见的字符混淆
  3. 应用特定于语言的规则

词典过程由以下参数控制:

  • tessedit_enable_dict_correction
  • tessedit_enable_bigram_correction

置信度和拒绝

每个识别出的单词都会分配一个置信度值。低置信度的单词可能会被

  1. 完全拒绝
  2. 标记为不确定
  3. 从词典中替换为备选词

Tesseract 使用以下步骤来处理置信度:

  1. make_reject_map() - 为每个单词创建拒绝映射
  2. rejection_passes() - 应用各种拒绝策略
  3. quality_based_rejection() - 使用质量指标接受或拒绝单词

结果访问

识别和后处理完成后,可以通过以下方式访问结果:

  1. ResultIterator - 提供对所有已识别元素的访问
  2. TessBaseAPI::GetUTF8Text() - 获取完整的识别文本
  3. 各种输出格式方法(HOCR、PDF、ALTO 等)

来源: src/api/baseapi.cpp393-402 src/ccmain/tesseractclass.h480-643

API 集成

整个 OCR 管道可以通过 TessBaseAPI 类访问,该类提供了处理每个阶段的方法。

典型的用法流程是:

  1. 使用 TessBaseAPI::Init() 初始化。
  2. 使用 TessBaseAPI::SetImage() 设置图像。
  3. 可选地设置参数或区域。
  4. 使用 TessBaseAPI::Recognize() 识别文本。
  5. 使用 TessBaseAPI::GetUTF8Text() 等方法检索结果。
  6. 使用 TessBaseAPI::End() 进行清理。

关键数据结构

在整个管道中,使用了几个关键数据结构:

数据结构描述
Image/Pix图像表示。
BLOCK_LIST页面中已识别块的列表。
PAGE_RES页面分割和识别的结果。
WERD_RES特定单词的结果。
UNICHARSET字符集及相关信息。
ETEXT_DESC进度监视器和控制接口。
ResultIterator用于访问识别结果的迭代器。

来源: src/api/baseapi.cpp161-865 src/ccmain/tesseractclass.h179-182

扩展管道

Tesseract 提供了几种扩展或自定义 OCR 管道的方法:

  1. 阈值处理:通过继承 ImageThresholder 来实现自定义阈值处理。
  2. 识别:为专门的识别训练自定义 LSTM 模型。
  3. 词典:添加自定义词典以用于领域特定词汇。
  4. 后处理:通过 API 实现自定义后处理。

训练数据流

对于训练新模型,Tesseract 使用相似但修改过的管道。

训练管道:

  1. 加载训练图像和真实文本。
  2. 从图像中提取特征。
  3. 在这些特征上训练 LSTM 网络。
  4. 生成用于识别的 traineddata 文件。

来源: src/ccstruct/imagedata.cpp216-267 src/ccmain/linerec.cpp37-130