有关训练基于神经网络的 LSTM Tesseract 4.00 的信息,请参阅 训练 Tesseract 4.00
如何使用提供的工具来训练 Tesseract 3.03–3.05 识别新语言。
重要提示:在您投入时间和精力训练 Tesseract 之前,强烈建议您阅读 提高质量 页面。
Tesseract 3.04 和 3.05 提供了一个 脚本,可以轻松执行 Tesseract 训练的各个阶段。有关使用它的更多信息,请参阅 tesstrain.sh 页面。
- 生成训练图像和框文件
- 运行 Tesseract 进行训练
- 生成 unicharset 文件
- font_properties 文件
- 聚类
- 词典数据(可选)
- unicharambigs 文件
- 将所有内容组合在一起
附录
有关训练过程的问题
如果您在训练过程中遇到问题,需要帮助,请使用 tesseract-ocr 邮件列表提出您的问题。
请勿 将您的问题和有关训练的问题报告为 问题!
介绍
Tesseract 3.0x 是完全可训练的。本页面描述了训练过程,提供了一些关于适用性到各种语言的指南,以及对结果的预期。
请在开始训练之前查看发布 3.04 版本中已提供 traineddata 的语言列表。
第三方训练工具 也可用于训练。
背景和限制
Tesseract 最初设计用于识别英语文本。人们一直在努力修改引擎及其训练系统,使其能够处理其他语言和 UTF-8 字符。Tesseract 3.0 可以处理任何 Unicode 字符(使用 UTF-8 编码),但它能成功识别的语言范围有限,因此,在您抱有 Tesseract 能够很好地识别您特定语言的希望之前,请先参考本部分内容!
Tesseract 3.01 添加了自上而下的语言,Tesseract 3.02 添加了希伯来语(从右到左)。
Tesseract 目前使用名为 cube 的辅助引擎处理阿拉伯语和印地语等脚本(包含在 Tesseract 3.01 及更高版本中)。请勿尝试训练低于 4.0 版本的 Tesseract 来识别阿拉伯语(波斯语、乌尔都语等同理)。这是徒劳的。 对于 4.0,请仅使用 LSTM 方法 进行训练。
Traineddata 针对其他语言,由 Google 在 3.04 版本中提供。
Tesseract 在处理大型字符集语言(如中文)时速度较慢,但似乎效果还可以。
Tesseract 需要通过显式地将不同字体分开,来了解同一字符的不同形状。字体数量限制为 64 个字体。请注意,运行时很大程度上取决于提供的字体数量,训练超过 32 个字体会导致运行速度明显降低。
所需的附加库
从 3.03 版本开始,需要额外的库才能构建训练工具。
sudo apt-get install libicu-dev
sudo apt-get install libpango1.0-dev
sudo apt-get install libcairo2-dev
构建训练工具
从 3.03 版本开始,如果您要从源代码编译 Tesseract,您需要使用单独的 make 命令来创建和安装训练工具。安装完上述附加库后,从 Tesseract 源代码目录运行以下命令
make training
sudo make training-install
所需的数据文件
要训练其他语言,您必须在 tessdata
子目录中创建一些数据文件,然后使用 combine_tessdata
将这些文件合并成一个文件。命名约定为 languagecode.file_name
。发布文件的语言代码遵循 ISO 639-3 标准,但可以使用任何字符串。用于英语(3.0x)的文件为
tessdata/eng.config
tessdata/eng.unicharset
tessdata/eng.unicharambigs
tessdata/eng.inttemp
tessdata/eng.pffmtable
tessdata/eng.normproto
tessdata/eng.punc-dawg
tessdata/eng.word-dawg
tessdata/eng.number-dawg
tessdata/eng.freq-dawg
… 最后合并的文件为
tessdata/eng.traineddata
以及
tessdata/eng.user-words
可能仍会单独提供。
traineddata 文件只是输入文件的串联,包含一个包含已知文件类型偏移量的目录表。有关当前接受的文件名的列表,请参阅源代码中的 ccutil/tessdatamanager.h。
文本输入文件的要求
文本输入文件(lang.config、lang.unicharambigs、font_properties、框文件、词典的单词列表等)需要满足以下条件
- ASCII 或 UTF-8 编码,不含 BOM
- Unix 行尾标记 (‘\n’)
- 最后一个字符必须是行尾标记 (‘\n’)。某些文本编辑器会将其显示为文件末尾的空行。如果您省略此标记,您将收到包含
last_char == '\n':Error:Assert failed...
的错误消息。
你能用多少的资源来完成训练?
您必须使用下面描述的步骤创建 unicharset
、inttemp
、normproto
、pffmtable
。如果您只是尝试识别有限范围的字体(例如单个字体),那么一个训练页面就足够了。其他文件无需提供,但很可能会提高准确率,具体取决于您的应用。
训练程序
其中一些过程不可避免地是手动的。提供了尽可能多的自动化帮助。下面提到的工具都构建在 training 子目录中。
您需要在包含输入文件的同一文件夹中运行所有命令。
生成训练图像和框文件
准备一个文本文件
第一步是确定要使用的完整字符集,并准备一个包含一组示例的文本或文字处理文件。在创建训练文件时,最需要注意的几点是
确保每个字符的样本数量最少。10 个样本很好,但对于罕见字符,5 个样本也可以。
更常见的字符应该有更多样本 - 至少 20 个。
不要将所有非字母字符归为一类。使文本更真实。
例如
The quick brown fox jumps over the lazy dog. 0123456789 !@#$%^&(),.{}<>/?
非常糟糕!更好的做法是
The (quick) brown {fox} jumps! over the $3,456.78 <lazy> #90 dog & duck/goose, as 12.5% of E-mail from [email protected] is spam?
这使文本行查找代码有更大的机会为特殊字符获得合理的基线指标。
自动化方法
3.03 版本中的新功能
根据上述规范,准备一个包含训练文本的 UTF-8 文本文件(training_text.txt
)。获取您希望识别的字体的 TrueType/OpenType 字体文件。依次为每个字体运行以下命令以创建匹配的 tif/box 文件对。
training/text2image --text=training_text.txt --outputbase=[lang].[fontname].exp0 --font='Font Name' --fonts_dir=/path/to/your/fonts
请注意,–font 的参数可能包含空格,因此必须用引号括起来。例如
training/text2image --text=training_text.txt --outputbase=eng.TimesNewRomanBold.exp0 --font='Times New Roman Bold' --fonts_dir=/usr/share/fonts
要列出系统中可以呈现训练文本的所有字体,请运行
training/text2image --text=training_text.txt --outputbase=eng --fonts_dir=/usr/share/fonts --find_fonts --min_coverage=1.0 --render_per_font=false
在本例中,training_text.txt
文件包含用英语编写的文本。将创建名为 ‘eng.fontlist.txt’ 的文件。
text2image
提供了许多其他命令行参数。运行 text2image --help
以获取更多信息。
如果您使用了 text2image
,您可以转到 运行 Tesseract 进行训练 步骤。
旧的手动方法
- 训练数据应按字体分组。理想情况下,单个字体的所有样本都应放在一个 tif 文件中,但该文件可能是多页 tif(如果您安装了 libtiff 或 leptonica),因此单个字体中的总训练数据可能包含很多页和很多万个字符,从而允许训练大型字符集语言。
- 无需使用多种大小进行训练。10 点就足够了。(对此的例外情况是非常小的文本。如果您要识别 x 高度小于约 15 像素的文本,则应专门训练它,或在尝试识别它们之前缩放图像。)
- 请勿将不同字体混合到同一个图像文件中(准确地说,在同一个 .tr 文件中)。这会导致在聚类时丢弃特征,从而导致识别错误。
- 下载页面上的示例 boxtiff 文件将有助于您了解如何格式化训练数据。
接下来,打印并扫描(或使用某种电子渲染方法)以创建训练页面的图像。最多可以使用 64 个训练文件(多页)。最好创建各种字体和样式(但放在单独的文件中),包括斜体和粗体。
您还需要将训练文本保存为 UTF-8 文本文件,以便在下一步中将代码插入另一个文件中使用。
针对大量训练数据的说明 64 个图像限制适用于字体数量。每个字体都应放在一个多页 tif 中,并且可以修改框文件以在坐标后指定每个字符的页码。因此,可以为任何给定的字体创建任意数量的训练数据,从而允许训练大型字符集语言。多页 tif 的另一种选择是为单个字体创建多个单页 tif,然后将每个字体的 tr 文件连接成几个单字体 tr 文件。无论哪种情况,输入 mftraining 的 tr 文件都必须包含单个字体。
创建框文件
请参阅单独的 创建框文件 页面。
运行 Tesseract 进行训练
对于每个训练图像-框文件对,在训练模式下运行 Tesseract
tesseract [lang].[fontname].exp[num].tif [lang].[fontname].exp[num] box.train
或者
tesseract [lang].[fontname].exp[num].tif [lang].[fontname].exp[num] box.train.stderr
注意,虽然 Tesseract 需要语言数据才能执行此步骤,但不会使用语言数据,因此您可以使用英语,无论您要训练哪种语言。
第一种形式将所有错误发送到名为 tesseract.log 的文件。第二种形式将所有错误发送到 stderr。
请注意,框文件名必须与 tif 文件名匹配,包括路径,否则 Tesseract 无法找到它。此步骤的输出是 fontfile.tr
,其中包含训练页面中每个字符的特征。还将写入 [lang].[fontname].exp[num].txt
,其中包含单个换行符,没有文本。
重要提示 检查 apply_box 的输出是否有错误。如果报告了致命错误,那么在您修复框文件之前,没有必要继续训练过程。新的 box.train.stderr 配置文件使选择输出位置变得更容易。致命错误通常表示此步骤未能找到框文件中列出的字符的任何训练样本。要么坐标错误,要么与相关字符的图像有关的问题。如果某个字符没有可用的样本,就无法识别它,生成的 inttemp 文件将与之后的 unicharset 文件不匹配,Tesseract 将中止。
另一种可能发生的也是致命的需要关注的错误是有关“框文件格式错误,位于第 n 行”。如果前面有“错误的 utf-8 字符…”,则表示 UTF-8 代码不正确,需要修复。错误“utf-8 字符串过长…” 表示您已超过字符描述的 24 字节限制。如果您需要超过 24 字节的描述,请提交问题。
无需编辑 [lang].[fontname].exp[num].tr
文件的内容。其中的字体名称无需设置。
对于好奇的人,这里提供了一些有关格式的信息。
生成 unicharset 文件
Tesseract 的 unicharset 文件包含有关 Tesseract OCR 引擎训练识别每个符号(unichar)的信息。
目前,生成 unicharset
文件需要使用以下命令分两步完成:unicharset_extractor
和 set_unicharset_properties
。
注意: 只要生成 inttemp
、normproto
和 pffmtable
,就必须重新生成 unicharset
文件(即,更改框文件时,必须重新创建所有这些文件),因为它们必须保持同步。
有关 unicharset
文件格式的更多详细信息,请参阅 本附录。
unicharset_extractor
Tesseract 需要了解它可以输出的字符集。要生成 unicharset
数据文件,请对上面生成的框文件使用 unicharset_extractor
程序
unicharset_extractor lang.fontname.exp0.box lang.fontname.exp1.box ...
set_unicharset_properties
3.03 版本中的新功能
此工具以及一组数据文件允许在 unicharset 中添加额外的属性,主要是从字体中获得的大小。
training/set_unicharset_properties -U input_unicharset -O output_unicharset --script_dir=training/langdata
--script_dir
应指向包含与训练字符集相关的 .unicharset 文件的目录。您可以从 https://github.com/tesseract-ocr/langdata 下载这些文件)。
运行完 unicharset_extractor
和 set_unicharset_properties
后,您应该获得一个 unicharset
文件,其中所有字段都设置为正确的值,就像 这个示例 中一样。
font_properties 文件
现在您需要创建一个 font_properties
文本文件。此文件的目的是提供字体样式信息,这些信息将在识别字体时显示在输出中。
font_properties
文件的每一行格式如下:fontname
italic
bold
fixed
serif
fraktur
其中 fontname
是一个命名字体的字符串(不允许出现空格),而 italic
、bold
、fixed
、serif
和 fraktur
都是简单的 0
或 1
标志,指示字体是否具有指定的属性。
示例:
timesitalic 1 0 0 1 0
font_properties
文件将被 shapeclustering
和 mftraining
命令使用。
在运行 mftraining
时,*.tr 文件 中的每个 fontname
字段必须与 font_properties
文件中的 fontname
条目匹配,否则 mftraining
将中止。
注意:langdata 存储库中有一个默认的 font_properties 文件,它涵盖了 3000 种字体(不一定准确)。
聚类
当所有训练页面的字符特征被提取后,我们需要对其进行聚类以创建原型。
可以使用 shapeclustering
、mftraining
和 cntraining
程序对字符形状特征进行聚类。
shapeclustering
shapeclustering
通常不应使用,除了印度语系。(对于拉丁字母语言,可能需要使用 shapeclustering
,其中基本字符与两个或多个非间距修饰符组合在一起,例如 ḗ、ɔ̄́、r̥̄:这包括但不限于拉丁语转写中的印度语系。如果不这样做,mftraining
将给出 Assert failed:in file unicharset.cpp
错误。)
shapeclustering -F font_properties -U unicharset lang.fontname.exp0.tr lang.fontname.exp1.tr ...
shapeclustering
通过形状聚类创建一个主形状表,并将其写入名为 shapetable
的文件。
mftraining
mftraining -F font_properties -U unicharset -O lang.unicharset lang.fontname.exp0.tr lang.fontname.exp1.tr ...
-U 文件是由上面 unicharset_extractor
生成的 unicharset,而 lang.unicharset 是将传递给 combine_tessdata
的输出 unicharset。
mftraining
将输出另外两个数据文件:inttemp
(形状原型)和 pffmtable
(每个字符的预期特征数量)。
注意:如果您没有运行 shapeclustering
,mftraining
将生成一个 shapetable
文件。无论是否使用 shapeclustering
,您都必须将此 shapetable
包含在您的训练数据文件中。
cntraining
cntraining lang.fontname.exp0.tr lang.fontname.exp1.tr ...
这将输出 normproto
数据文件(字符归一化敏感度原型)。
词典数据(可选)
Tesseract 针对每种语言使用最多 8 个字典文件。这些都是可选的,它们帮助 Tesseract 决定不同字符组合的可能性。
七个文件被编码为有向无环字图 (DAWG),另一个文件是纯 UTF-8 文本文件。
名称 | 类型 | 描述 |
---|---|---|
word-dawg | dawg | 由语言中的字典词语生成的 dawg。 |
freq-dawg | dawg | 由最常出现的词语生成的 dawg,这些词语原本应该进入 word-dawg 中。 |
punc-dawg | dawg | 由词语周围发现的标点符号模式生成的 dawg。“word” 部分被替换为单个空格。 |
number-dawg | dawg | 由最初包含数字的标记生成的 dawg。每个数字都用空格字符替换。 |
bigram-dawg | dawg | 一个由词语双字母组成的 dawg,其中词语之间用空格隔开,每个数字用 ? 替换。 |
user-words | text | 要添加到字典中的额外词语列表。通常保持为空,以便用户在需要时添加;请参阅 tesseract(1)。 |
要制作 DAWG 字典文件,您首先需要一种语言的词语列表。您可以从拼写检查器(例如 ispell、aspell 或 hunspell)中找到一个合适的字典文件用作词语列表的基础 - 请注意许可证。词语列表格式为 UTF-8 文本文件,每行一个词语。将词语列表拆分为所需的集合,例如:最常出现的词语,以及其他词语,然后使用 wordlist2dawg
制作 DAWG 文件。
wordlist2dawg frequent_words_list lang.freq-dawg lang.unicharset
wordlist2dawg words_list lang.word-dawg lang.unicharset
对于从右到左(RTL)书写的语言,如阿拉伯语和希伯来语,请在 wordlist2dawg
命令中添加 -r 1
。
其他选项可以在 wordlist2dawg 手册页 中找到。
注意:如果组合的训练数据中包含字典文件,则它必须至少包含一个条目。对于 combine_tessdata
步骤,否则为空的字典文件是不需要的。
应将拼写不寻常的词语添加到字典文件中。不寻常的拼写可能包括字母字符与标点符号或数字字符的混合。(例如 i18n、l10n、google.com、news.bbc.co.uk、io9.com、utf8、ucs2)
如果您需要字典词语列表的示例文件,请解组合(使用 combine_tessdata)现有的语言数据文件(例如 eng.traineddata),然后使用 dawg2wordlist 提取词语列表。
unicharambigs 文件
unicharambigs
文件是一个文本文件,它描述了字符或字符集之间可能的歧义,并且是手动生成的。
要了解文件格式,请查看以下示例
v1
2 ' ' 1 " 1
1 m 2 r n 0
3 i i i 1 m 0
第一行是版本标识符。
其余行是制表符分隔的字段,格式如下
<number of characters for match source> <characters for match source> <number of characters for match target> <characters for match target> <type indicator>
类型指示符 could have 具有以下值
值 | 类型 | 描述 |
---|---|---|
0 | 非强制性替换。 | 这告诉 Tesseract 将歧义视为对分段搜索的提示,即如果将 ‘source’ 替换为 ‘target’ 会从非字典词语创建字典词语,则应继续工作。可以通过歧义转换为另一个字典词语的字典词语将不会用于训练自适应分类器。 |
1 | 强制性替换。 | 这告诉 Tesseract 始终将匹配的 ‘source’ 替换为 ‘target’ 字符串。 |
示例行 | 解释 |
---|---|
2 ‘ ‘ 1 “ 1 | 双引号 (“) 应该始终在看到两个连续的单引号 (‘) 时进行替换。 |
1 m 2 r n 0 | 字符 ‘rn’ 有时可能被错误地识别为 ‘m’。 |
3 i i i 1 m 0 | 字符 ‘m’ 有时可能被错误地识别为序列 ‘iii’。 |
每个单独的字符都必须包含在 unicharset 中。也就是说,所有使用的字符都必须是正在训练的语言的一部分。
规则不是双向的,因此,如果您希望在检测到 ‘m’ 时考虑 ‘rn’,反之亦然,则需要为每个规则制定一个规则。
3.03 及更高版本支持 unicharambigs 文件的新简化格式。
v2
'' " 1
m rn 0
iii m 0
在此格式中,“error” 和 “correction” 是用空格分隔的简单 UTF-8 字符串,另一个空格后是与 v1 相同的类型说明符(0 表示可选,1 表示强制性替换)。请注意,这种更简单的格式的缺点是 Tesseract 必须将 UTF-8 字符串编码到 unicharset 的组件中。在复杂的脚本中,此编码可能不明确。在这种情况下,选择编码方式,以便为每个组件使用最少的 UTF-8 字符,即最短的 unicharset 组件将组成编码。
与训练中使用的大多数其他文件一样,unicharambigs
文件必须以 UTF-8 编码,并且必须以换行符结尾。
unicharambigs
格式也在 unicharambigs(5) 手册页 中进行了描述。
unicharambigs
文件也可能不存在。
将所有内容组合在一起
仅此而已!您现在需要做的就是将所有文件(shapetable
、normproto
、inttemp
、pffmtable
、unicharset
)收集在一起,并使用 lang.
前缀(例如 eng.
)重命名它们,然后对它们运行 combine_tessdata
,如下所示
combine_tessdata lang.
虽然您可以使用任何您喜欢的字符串作为语言代码,但我们建议您使用与 ISO 639-2 代码 中的代码之一匹配的 3 个字母代码作为您的语言代码。
生成的 lang.traineddata 将放在您的 tessdata 目录中。然后,Tesseract 就可以识别您语言中的文本(理论上),如下所示
tesseract image.tif output -l lang
combine_tessdata
的更多选项可以在其 手册页 或其 源代码 的注释中找到。
您可以在第三方在线 训练数据检查器 中检查训练数据文件的一些内部内容。
附录
*.tr 文件格式
框文件中的每个字符在 .tr 文件中都有对应的一组条目(按顺序),如下所示
<fontname> <character> <left> <top> <right> <bottom> <pagenum>
4
mf <number of features>
<x> <y> <length> <dir> 0 0
...
cn 1
<ypos> <length> <x2ndmoment> <y2ndmoment>
if <number of features>
<x> <y> <dir>
...
tb 1
<bottom> <top> <width>
微特征 (mf
) 是轮廓的多边形段,它们被归一化到第一和第二矩。mf
行将后跟由 <特征数量> 决定的行集。
x 是 x 位置 [-0.5,0.5]
y 是 y 位置 [-0.25,0.75]
length 是多边形段的长度 [0,1.0]
dir 是段的方向 [0,1.0]
字符归一化特征 (cn
) 用于校正矩归一化,以区分位置和大小(例如 c
与 C
以及 ,
与 '
)
if
- 整数特征
tb
- 地理特征
unicharset 文件格式
Tesseract 的 unicharset 文件包含有关 Tesseract OCR 引擎训练识别每个符号(unichar)的信息。
unicharset 文件的第一行包含文件中的 unichar 数量。
在此行之后,每个后续行提供单个 unichar 的信息。第一个这样的行包含一个为空格字符保留的占位符。
Tesseract 中的每个 unichar 都由其 Unichar ID 引用,它是 unicharset 文件中的行号(减 1)。因此,空格的 unichar 为 0。
unicharset 文件中的每个 unichar 行都应具有以下空格分隔的字段
character
properties
glyph_metrics
script
other_case
direction
mirror
normed_form
character
为此 unichar 生成的 UTF-8 编码字符串。properties
字符属性的整数掩码,每个位一个。从最低有效位到最高有效位,它们分别是:isalpha、islower、isupper、isdigit、ispunctuation。glyph_metrics
十个用逗号分隔的整数,表示各种标准,这些标准用于在基线归一化坐标系中找到此字形,其中 128 被归一化为 x 高度。min_bottom
,max_bottom
字符底部可能找到的范围。min_top
,max_top
字符顶部可能找到的范围。min_width
,max_width
字符的水平宽度。min_bearing
,max_bearing
字符的最左侧部分距离通常的起始位置有多远。min_advance
,max_advance
从打印机的单元格左侧前进多远才能开始下一个字符。
script
脚本的名称(Latin、Common、Greek、Cyrillic、Han、NULL)。other_case
此字符的另一个大小写版本的 Unichar ID(大写或小写)。direction
此字符的 Unicode BiDi 方向,由 ICU 的枚举 UCharDirection 定义。(0 = 从左到右,1 = 从右到左,2 = 欧洲数字……)mirror
此字符的 BiDirectional 镜像的 Unichar ID。例如,左括号的镜像是右括号,但拉丁大写 C 没有镜像,因此它仍然是拉丁大写 C。normed_form
此 unichar 的“归一化形式”的 UTF-8 表示,用于将错误归咎于给定基本事实文本的模块。例如,左单引号或右单引号可能会归一化为 ASCII 引号。
unicharset 文件的示例
110
NULL 0 NULL 0
N 5 59,68,216,255,87,236,0,27,104,227 Latin 11 0 1 N
Y 5 59,68,216,255,91,205,0,47,91,223 Latin 33 0 2 Y
1 8 59,69,203,255,45,128,0,66,74,173 Common 3 2 3 1
9 8 18,66,203,255,89,156,0,39,104,173 Common 4 2 4 9
a 3 58,65,186,198,85,164,0,26,97,185 Latin 56 0 5 a
...
有关 properties
字段的更多信息
以下是一个示例。为简单起见,此示例仅显示每行中的前两个字段。其他字段被省略。
...
; 10 ...
b 3 ...
W 5 ...
7 8 ...
= 0 ...
...
Char | Punctuation | Digit | Upper | Lower | Alpha | Binary num | Hex. |
---|---|---|---|---|---|---|---|
; | 1 | 0 | 0 | 0 | 0 | 10000 | 10 |
b | 0 | 0 | 0 | 1 | 1 | 00011 | 3 |
W | 0 | 0 | 1 | 0 | 1 | 00101 | 5 |
7 | 0 | 1 | 0 | 0 | 0 | 01000 | 8 |
= | 0 | 0 | 0 | 0 | 0 | 00000 | 0 |
在第 2-6 列中,0
表示“否”,1
表示“是”。