高级功能

控制 unpaper

OCRmyPDF 使用 unpaper 来实现 --clean--clean-final 参数。unpaper 提供了多种图像处理过滤器来改进图像。

默认情况下,OCRmyPDF 仅使用那些被认为对几乎所有文件都安全、无需事后检查每一页的 unpaper 参数。当仅使用 --clean 时尤其如此,因为这指示 OCRmyPDF 只在 OCR 之前清洁图像,而不是最终图像。

然而,如果你希望使用 unpaper 中更激进的选项,可以使用 --unpaper-args '...' 来覆盖 OCRmyPDF 的默认设置,并将其他参数传递给 unpaper。此选项会将参数传递给 unpaper,而不会了解该程序认为哪些参数是有效的。参数字符串必须加引号,如下例所示。不能包含文件名参数。OCRmyPDF 将假定它可以将中间图像的输入和输出文件名附加到 --unpaper-args 字符串。

在此示例中,我们告诉 unpaper 期望一张纸(图像)上有两页文本,例如扫描书的两面时发生的情况。unpaper 使用此信息独立地矫正倾斜并清理两者的边距。

ocrmypdf --clean --clean-final --unpaper-args '--layout double' input.pdf output.pdf
ocrmypdf --clean --clean-final --unpaper-args '--layout double --no-noisefilter' input.pdf output.pdf

警告

一些 unpaper 功能会重新定位图像中的文本。建议使用 --clean-final 来避免此问题。

警告

一些 unpaper 功能会导致使用或生成多个输入或输出文件。OCRmyPDF 要求 unpaper 使用一个文件并生成一个文件;如果不满足此假设,将会出现错误。

注意

unpaper 使用未压缩的 PBM/PGM/PPM 文件作为其中间文件。对于大型图像或文档,这可能会占用大量临时磁盘空间。

控制 OCR 选项

OCRmyPDF 提供了许多功能来控制 OCR 引擎 Tesseract 的行为。

何时跳过 OCR

如果 PDF 中的页面似乎包含文本,默认情况下 OCRmyPDF 会在不修改 PDF 的情况下退出。这是为了确保先前已进行 OCR 或“数字原生”而非扫描的 PDF 不会被处理。

如果指定了 --skip-text,则不会对已包含文本的页面执行任何图像处理或 OCR。该页面将被复制到输出。这对于包含“数字原生”和扫描内容的文档可能很有用,或者无论其内容如何,都可以使用 OCRmyPDF 来规范化并转换为 PDF/A。

如果指定了 --redo-ocr,则会执行详细的文本分析。文本被分类为可见或不可见。不可见文本(OCR)被删除。然后创建每个页面的图像,并将可见文本遮盖掉。页面图像被发送进行 OCR,然后将任何附加文本作为 OCR 插入。如果文件包含文本和包含文本的位图图像的混合,OCRmyPDF 将在图像中找到附加文本,而不会干扰现有文本。一些 PDF OCR 解决方案将文本渲染为技术上可打印或以某种方式可见,可能是通过绘制它然后在其上绘画。OCRmyPDF 无法区分这种类型的 OCR 文本和真实文本,因此它不会被“重做”。

如果指定了 --force-ocr,则所有页面都将被栅格化为图像,丢弃任何隐藏的 OCR 文本,栅格化任何可打印文本,并将表单字段或交互式对象扁平化为其视觉表示。这对于重新进行 OCR、修复字符映射损坏的 OCR 文本(文本可选择但不可搜索)以及销毁已删减信息很有用。

时间和图像大小限制

默认情况下,OCRmyPDF 允许 Tesseract 每页运行三分钟(180 秒)。这通常足以在具有现代硬件的合理大小的页面上找到所有文本。

如果跳过页面,它将不进行 OCR 插入。如果请求了预处理,则插入预处理的图像层。

如果要调整 OCR 花费的时间量,请更改 --tesseract-timeout。您还可以使用 --skip-big 自动跳过超过特定百万像素数的图像。(300 DPI、8.5×11 英寸的页面图像是 8.4 百万像素。)

# Allow 300 seconds for OCR; skip any page larger than 50 megapixels
ocrmypdf --tesseract-timeout 300 --skip-big 50 bigfile.pdf output.pdf

处理巨大图像的 OCR

Tesseract 对其将处理的图像大小有内部限制。默认情况下,--tesseract-downsample-large-images 已启用,OCRmyPDF 将对图像进行下采样以适应 Tesseract 的限制。(通常只有扫描超大媒体(例如在任一维度上超过 110 厘米或 43 英寸的大地图或蓝图,且 DPI 较高)的图像才会遇到这些限制。)可以使用 --no-tesseract-downsample-large-images 禁用此功能。

--tesseract-downsample-above Npixels 调整下采样的阈值。默认情况下,只有超过 Tesseract 任一内部限制(任一维度上 32767 像素)的图像才会进行下采样。

您还需要将 --tesseract-timeout 设置得足够高以允许处理。

只有发送给 OCR 的图像会进行下采样。原始图像被保留。

# Allow 600 seconds for OCR on huge images
ocrmypdf --tesseract-timeout 600 \
    --tesseract-downsample-large-images \
    bigfile.pdf output.pdf

# Downsample images above 5000 pixels on the longest dimension to
# 5000 pixels
ocrmypdf --tesseract-timeout 120 \
    --tesseract-downsample-large-images \
    --tesseract-downsample-above 5000 \
    bigfile.pdf output_downsampled_ocr.pdf

覆盖默认的 Tesseract

OCRmyPDF 检查系统 PATH 中是否有 tesseract 二进制文件。

影响 Tesseract 行为的一些相关环境变量包括

TESSDATA_PREFIX

覆盖 Tesseract 数据文件的路径。这允许同时安装“最佳”和“快速”训练数据集。OCRmyPDF 不管理此环境变量。

OMP_THREAD_LIMIT

控制 Tesseract 将使用的线程数。如果此环境变量未设置,OCRmyPDF 将管理它。

例如,如果您有 Tesseract 的开发版本,并且不想使用系统安装版本,可以按如下方式启动 OCRmyPDF

env \
    PATH=/home/user/src/tesseract/api:$PATH \
    TESSDATA_PREFIX=/home/user/src/tesseract \
    ocrmypdf input.pdf output.pdf

在此示例中,TESSDATA_PREFIX 是必需的,用于将 Tesseract 重定向到其“tessdata”文件的备用文件夹。

覆盖其他支持程序

除了 Tesseract,OCRmyPDF 还使用以下外部二进制文件

  • gs (Ghostscript)

  • unpaper

  • pngquant

  • jbig2

在每种情况下,OCRmyPDF 都将在 PATH 环境变量中搜索二进制文件。通过修改 PATH 环境变量,您可以覆盖 OCRmyPDF 使用的二进制文件。

更改 Tesseract 配置变量

您可以使用配置文件覆盖 Tesseract 的默认控制参数

举个例子,此配置将禁用 Tesseract 当前语言的词典。通常词典有助于推断不清晰的单词,但如果文档不包含很多单词(例如,零件号列表),可能会干扰 OCR。

创建名为“no-dict.cfg”的文件,内容如下

load_system_dawg 0
language_model_penalty_non_dict_word 0
language_model_penalty_non_freq_dict_word 0

然后按如下方式运行 ocrmypdf(以及任何其他所需的参数)

ocrmypdf --tesseract-config no-dict.cfg input.pdf output.pdf

警告

某些控制参数的组合可能会导致 Tesseract 崩溃或破坏 OCRmyPDF 对 Tesseract 输出的假设。

更改页面分割模式

指令 --tesseract-pagesegmode Nmode 将所需的页面分割模式传递给 Tesseract OCR。默认值为 3。

当您知道 PDF 应该以特定方式进行分析时(例如,页面仅包含单行文本的 PDF),页面分割可以改善 OCR 结果。对于绝大多数用户而言,更改页面分割模式只会使事情变得更糟。

截至 2024 年 6 月,Tesseract 页面分割模式如下:

ID

描述

0

仅方向和脚本检测 (OSD)。

1

带有 OSD 的自动页面分割。

2

自动页面分割,但无 OSD 或 OCR。(未实现)

3

完全自动页面分割,但无 OSD。(默认)

4

假设可变大小的单列文本。

5

假设单一切向对齐文本块。

6

假设单一切向文本块。

7

将图像视为单行文本。

8

将图像视为单个单词。

9

将图像视为圆形中的单个单词。

10

将图像视为单个字符。

11

稀疏文本。以任意顺序查找尽可能多的文本。

12

带有 OSD 的稀疏文本。

13

原始行。将图像视为单行文本,绕过 Tesseract 特有的 hack。

模式 0、1、2 和 12(所有启用方向和脚本检测的模式)与 OCRmyPDF 不兼容,因为 OCRmyPDF 在独立于 OCR 的步骤中执行 OSD。它们的使用可能会干扰 --rotate-pages 和其他功能。

目前无法通过 OCRmyPDF 使用高级 Tesseract OCR 功能,例如创建 OCR 信息。

更改 PDF 渲染器

栅格化

: 将 PDF 转换为图像以供显示。

渲染

: 从其他数据(例如现有 PDF)创建新的 PDF。

OCRmyPDF 有这些 PDF 渲染器:sandwichhocr。可以使用 --pdf-renderer 选择渲染器。默认值为 auto,它允许 OCRmyPDF 选择要使用的渲染器。目前,auto 总是选择 hocr

hocr 渲染器

16.0.0 版本中有所更改。

在两种渲染器中,都渲染一个纯文本层,并将其叠加到原始 PDF 页面或新栅格化的原始 PDF 页面版本上(使用 --force-ocr 时)。这样,通常可以避免 PDF 信息丢失。(您可能需要禁用 PDF/A 转换和优化以消除所有有损转换。)

新的 hOCR 渲染器使用的当前方法是对 Tesseract PDF 渲染器的重新实现,使用了相同的 Glyphless 字体和一般思想,但修复了许多阻碍它的技术问题。新的 hocr 提供了更好的文本放置准确性,避免了单词分割问题,并提供了更好的倾斜文本定位。

使用实验性 API,还可以使用任何能够编辑 hOCR 文件的工具来编辑 Tesseract 的 OCR 输出。

此渲染器的旧版本不支持非拉丁语言,但现在已通用。

sandwich 渲染器

sandwich 渲染器使用 Tesseract 的纯文本 PDF 功能,该功能生成一个 PDF 页面,其中将 OCR 以不可见文本形式布局。

目前一些有问题的 PDF 查看器,如 Mozilla PDF.js 和 macOS Preview,在分割其文本输出时存在问题,可能会导致多个单词粘在一起。它也不支持从右到左的字体(阿拉伯语、希伯来语、波斯语)。此渲染器的输出无法编辑。sandwich 渲染器保留用于测试。

使用 --deskew 等图像预处理功能时,原始 PDF 将作为整页渲染,OCR 层将放置在顶部。

渲染和栅格化选项

14.3.0 版本新增。

--continue-on-soft-render-error 选项允许 OCRmyPDF 在页面无法栅格化/渲染时继续。如果您尝试从格式不规范的 PDF 中获取最佳 OCR 结果,并且愿意接受某些页面可能在视觉上与输入不符且 OCR 效果不佳,则此选项很有用。

颜色转换策略

15.0.0 版本新增。

OCRmyPDF 使用 Ghostscript 将 PDF 转换为 PDF/A。在某些情况下,此转换需要颜色转换。默认策略是使用 LeaveColorUnchanged 策略进行转换,该策略尽可能保留原始色彩空间(某些罕见的色彩空间可能仍然会被转换)。

通常文档扫描仪生成的是 sRGB 色彩空间的 PDF,无需转换,因此默认策略是合适的。

假设您有一个为专业打印而准备的文档,采用 Separation 或 CMYK 色彩空间,并且文本已转换为曲线。在这种情况下,您可能希望使用不同的颜色转换策略。--color-conversion-strategy 选项允许您选择不同的策略,例如 RGB

返回码策略

OCRmyPDF 将所有消息写入 stderrstdout 保留用于管道输出文件。stdin 保留用于管道输入文件。

OCRmyPDF 生成的返回码被认为是稳定用户界面的一部分。它们可以从 ocrmypdf.exceptions 导入。

返回码

代码

名称

解释

0

ExitCode.ok

一切按预期工作。

1

ExitCode.bad_args

参数无效,已退出并报错。

2

ExitCode.input_file

输入文件似乎不是有效的 PDF。

3

ExitCode.missing_dependency

缺少 OCRmyPDF 所需的外部程序。

4

ExitCode.invalid_output_pdf

已创建输出文件,但它似乎不是有效的 PDF。文件将可用。

5

ExitCode.file_access_error

运行 OCRmyPDF 的用户没有足够的权限读取输入文件和写入输出文件。

6

ExitCode.already_done_ocr

文件似乎已包含文本,因此可能不需要 OCR。请参阅输出消息。

7

ExitCode.child_process_error

外部程序(子进程)发生错误,OCRmyPDF 无法继续。

8

ExitCode.encrypted_pdf

输入 PDF 已加密。OCRmyPDF 不读取加密的 PDF。请使用其他程序(如 qpdf)来移除加密。

9

ExitCode.invalid_config

使用 --tesseract-config 将自定义配置文件传递给了 Tesseract,但 Tesseract 拒绝了此文件。

10

ExitCode.pdfa_conversion_failed

已创建有效的 PDF,但 PDF/A 转换失败。文件将可用。

15

ExitCode.other_error

发生了其他错误。

130

ExitCode.ctrl_c

程序被按下 Ctrl+C 中断。

更改临时存储位置

OCRmyPDF 在处理过程中会生成许多临时文件。

要更改临时文件的存储位置,请更改 ocrmypdf 环境的 TMPDIR 环境变量。(Python 的 tempfile.gettempdir() 返回存储临时文件的根目录。)例如,可以将 TMPDIR 重定向到大型内存盘,以避免 HDD/SSD 的磨损并可能提高性能。

在 Windows 上,改为使用 TEMP 环境变量。

调试中间文件

OCRmyPDF 通常将其中间结果保存到临时文件夹,并在退出时(无论成功或失败)删除此文件夹。

如果在命令行上指定了 --keep-temporary-files (-k) 参数,无论成功或失败,OCRmyPDF 都将保留临时文件夹并打印其位置。示例消息如下:

Temporary working files retained at:
/tmp/ocrmypdf.io.u20wpz07

当 OCRmyPDF 作为 snap 启动时,这对应于 snap 文件系统,例如

/tmp/snap-private-tmp/snap.ocrmypdf/tmp/ocrmypdf.io.u20wpz07

此文件夹的组织是一个实现细节,并且可能在版本之间发生变化。然而,一般的组织是按页划分的工作文件以页码作为前缀(从第 1 页开始),中间部分表示处理阶段,后缀表示文件类型。一些重要文件包括:

  • _rasterize.png - 输入页面的外观

  • _ocr.png - 发送给 Tesseract 进行 OCR 的文件;根据参数,这可能与呈现的图像不同

  • _pp_deskew.png - 纠偏后的图像

  • _pp_clean.png - 使用 unpaper 清理后的图像

  • _ocr_hocr.pdf - OCR 文件;显示为空白页面,嵌入了不可见文本

  • _ocr_hocr.txt - OCR 文本(如果页面是混合格式,不一定包含页面上的所有文本)

  • fix_docinfo.pdf - 创建用于修复 PDF DocumentInfo 数据结构的临时文件

  • graft_layers.pdf - 渲染的 PDF,已嫁接了 OCR 层

  • pdfa.pdf - 转换为 PDF/A 后的 graft_layers.pdf

  • pdfa.ps - Ghostscript 用于 PDF/A 转换的 PostScript 文件

  • optimize.pdf - 优化前生成的 PDF

  • optimize.out.pdf - 优化生成的 PDF

  • origin - 输入文件

  • origin.pdf - 输入文件或转换后的输入图像 PDF

  • images/* - 在优化过程中提取的图像;此处前缀表示 PDF 对象 ID,而非页码