很多做文字识别需求的朋友,第一次接触 Tesseract OCR 时都会有一个错觉:官方给了 Windows 安装包,双击装完就能用,接入项目时无非是把动态库拷过去。实际上等你打开 Visual Studio 工程链接时,问题就来了——版本对不上、运行库不一致、缺训练组件、甚至找不到 Leptonica 依赖,每一步都能卡住大半天。标题里写着“Windows 10 + CMake-GUI + Visual Studio 2019下编译和使用解决方案”,正好是我反复做过多次的流程。这篇记录就把从源码编译到项目集成的完整链路走一遍,适合所有打算把 OCR 能力嵌入 C++ 项目、又不想被预编译包绑住手脚的开发者。哪怕你之前没碰过 CMake,按步骤执行也能跑通。
1. 为什么这个项目值得折腾:官方包解决不了的问题
1.1 直接下载的安装包哪里不够用
官方发布页确实提供 Windows 安装包,装完有个 tesseract.exe,命令行识别英文图片没问题。但多数人的需求不是敲命令,而是要把 OCR 引擎集成到自己的 C++ 项目里。这时候问题就来了:安装包里虽然带着 tesseract.lib 和 dll,可它跟你的 Visual Studio 版本是否匹配?我用 VS2019 编译默认是 v142 工具集、动态运行库,官方包可能是另一种构建配置,链接进去之后经常出现字符集问题或运行时报错;想打开训练工具、想改源码加日志、想确认用的 Leptonica 是哪个版本,这些官方包都给不了。
另一个现实问题是语言数据。官方 Windows 安装包通常不带中文语言包,需要另外下载 tessdata。没有自己编译经验的人,第一次接触到 traineddata 这种文件格式就已经懵了,更别说还要搞对路径。
1.2 必须自己编译的三种典型场景
我自己总结下来,以下三种场景值得从头编译:
第一,项目要用 C++ API(TessBaseAPI)动态调用。这是最常见的集成方式。官方包虽然能凑合,但头文件路径、依赖库命名、dll 运行时行为都需要自己摸索,不如自己编译一版“原生配套”的干净。
第二,要使用训练工具。Tesseract 5 的 LSTM 训练流程里,text2image、tesstrain 这些工具在 Windows 预编译包里几乎没有,只能源码编译。
第三,团队要锁版本、做分发。企业环境里,把 Tesseract 源码和 Leptonica 版本固定下来,编译成内部统一的 SDK,比让每个人各自下载安装包可控得多。我每次编译完都会把产物归档成 zip,后续想复现、想给别人复制,都非常方便。
1.3 我的编译环境一览
为了避免因为环境不一致走弯路,我先把这次编译的基准环境列出来:
| 项目 | 我的版本 | 备注 |
|---|---|---|
| 操作系统 | Windows 10 22H2 x64 | 常规版本即可 |
| Visual Studio | 2019 16.11.x | 勾选“使用 C++ 的桌面开发” |
| CMake-GUI | 3.26.x | 不要用太老的版本 |
| Tesseract 源码 | 5.3.x | 官方发布分支 |
| Leptonica | 1.83.x | 通过包管理器安装,版本必须匹配 |
| 构建平台 | x64 / Release | 建议全程 64 位 |
如果你的 VS 是 2022,流程几乎一样,只是 CMake 里选择的生成器换成 Visual Studio 17 2022。下面正式开工。
2. 编译前我把整个依赖链做了哪些功课
2.1 为什么 Tesseract 绕不开 Leptonica
Tesseract 本身专注于“把图像里的文字识别成文本”,它不负责解码 PNG、JPEG 这些常见图片格式,也不负责缩放、二值化、旋转等图像预处理。这部分工作完全交给 Leptonica。也就是说,没有 Leptonica,Tesseract 连一张普通 PNG 都读不进去。用个不太严谨但很好理解的比喻:Tesseract 是发动机,Leptonica 是变速箱,CMake 是装配流水线。你只盯发动机,不把变速箱装好,车子照样没法开。因此编译 Tesseract 时,CMake 必须在配置阶段找到 Leptonica 的目录和构建产物,否则 Configure 直接失败。
2.2 获取 Leptonica 的三种方式与我的选择
三条路我都试过,各有利弊。
一是在本机源码编译 Leptonica。最可控,但 Leptonica 本身也有依赖,比如 libjpeg、libpng、zlib。想把这些都弄齐,花的时间比编译 Tesseract 还长,适合对构建有洁癖、或者需要定制图像功能的场景。
二是用包管理器安装。Windows 上比较省事的就是 vcpkg,装完 Leptonica 后,CMake 可以借助 vcpkg 的机制找到依赖。我用的是这个方案,省去自己编译 Leptonica 的麻烦。
三是直接下载某个预构建包。速度快,但你必须确认包里的头文件和库与你正在编译的 Tesseract 版本兼容。很多网上分享的依赖包是几个版本混在一起,装上去之后 Configure 全绿,Compile 到一半就报结构体定义不一致。
我最终的做法是:用 vcpkg 安装 leptonica,并指定 x64-windows 目标,然后在 CMake-GUI 里手动把 Leptonica_DIR 指向 vcpkg 安装目录下的 share\leptonica。这样 CMake 能通过 LeptonicaConfig.cmake 自动解析头文件和库路径,不用我手工填一串 include 和 lib 路径。
2.3 VS2019 工作负载和 CMake-GUI 版本
安装 VS2019 时最容易忽略的是工作负载。记住只需要两样:使用 C++ 的桌面开发,以及 Windows 10 SDK 组件。这两个是 MSVC 编译器和系统头文件的基础。如果装的时候漏了 C++ 模块,后面要么提示找不到 cl.exe,要么编译时误入其他工具链。
CMake-GUI 要注意版本。CMake 的“Visual Studio 16 2019”生成器是 3.15 以后才支持的,版本太旧的 CMake 只显示“Visual Studio 15 2017”,甚至认不出 VS2019。所以我建议直接下载 3.26 以上的 Windows x64 installer,安装时选“将 CMake 加入系统 PATH”,后面写脚本也方便。
2.4 源码目录和构建目录为什么要分离
这是第一次用 CMake 的人最容易犯的错:直接在源码文件夹里建 build 子目录,或者更糟,直接在源码根目录点 Configure。CMake 会在构建目录里生成大量中间文件,包括 CMakeCache.txt、.vcxproj、.sln,这些东西和源码混在一起,后面想升级源码版本、换 VS 版本重新构建,清理起来非常痛苦。
我的习惯是在工作目录下建两个平级文件夹:
D:\work\ocr\tesseract-5.3.4 # 源码,保持干净 D:\work\ocr\build-tesseract # 构建目录,可以随时删除重建在 CMake-GUI 里,第一个框 Source code 填源码目录,第二个框 Build binaries 填构建目录。这一步虽然不起眼,但能省掉后续很多“缓存污染”问题。某次 Configure 选项改乱了,直接把 build 目录删掉重新来一遍,比在 GUI 里逐个排查红色变量快得多。
3. CMake-GUI 里的每一个选项:勾选与不勾选的决策记录
3.1 Configure 阶段的第一步:生成器选择
打开 CMake-GUI,填入源码和构建目录后,点击 Configure。第一次会弹出对话框,需要选择代码生成器。我这里选 Visual Studio 16 2019,右侧 Architecture 选 x64。选好之后点击 Finish,CMake 会做一轮快速检测,紧接着是一段漫长的配置过程。
此时界面会弹出大面积的红色变量,这非常正常——红色表示 CMake 还没有把对应的值“固化”下来,不代表出错。但如果不理解这些变量的含义就瞎点 Generate,后面编译十有八九会出问题。下面逐个说重点。
3.2 核心 CMake 变量逐项解读
以下变量以 Tesseract 5.3 的 CMake 配置为参考,默认值不一定符合实际需求。我的选择如下:
| 变量名 | 我设置的值 | 原因 |
|---|---|---|
| BUILD_TRAINING_TOOLS | OFF | 纯使用场景不需要训练工具,开着会引入额外依赖,编译时间翻倍 |
| BUILD_SHARED_LIBS | ON | 生成动态库,方便其他项目按 dll 方式引用,也避免多个 exe 都静态塞进 Tesseract 导致镜像膨胀 |
| BUILD_TESTS | OFF | 关闭测试项目,省时省力。测试代码需要额外下载图片资源和测试框架,日常编译根本没必要 |
| BUILD_TOOLS | ON | 保留 tesseract.exe 命令行工具,这是验证识别链路最方便的方式 |
| BUILD_ABI_HEADERS | ON | 生成稳定 ABI 头文件,保持默认即可 |
| MULTI_THREADING_ENABLED | ON | 多线程支持,识别时能利用多核,默认开启就好 |
| GRAPHICS_BUILD | OFF | 控制台工具不需要图形菜单,默认关闭 |
| Leptonica_DIR | D:\vcpkg\installed\x64-windows\share\leptonica | 最关键的一项,指向包含 LeptonicaConfig.cmake 的目录 |
关于 Leptonica_DIR 再强调一次:它指向的不是 include 文件夹,也不是 lib 文件夹,而是能找到“LeptonicaConfig.cmake”那个目录。CMake 靠这个配置文件来定位头文件和库文件。如果 Leptonica 不是 vcpkg 装的,路径可能长得不一样,但原则一样——找到 Config 文件所在的目录填进去。
这里有一个非常容易踩的坑:BUILD_TRAINING_TOOLS 如果打开,CMake 还需要找 ICU、pango 等组件,Windows 下这些依赖几乎只有 vcpkg 能一次装齐。如果只是拿来做识别,别开它。我见过不少人一到 Configure 阶段就疯狂报 pango 找不到,一查就是手滑勾了训练工具。
3.3 Configure 阶段高频报错的排查
Configure 全绿当然最好,但实际过程中问得最多的还是那几类报错。整理成一张对照表:
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| 红色报错提示找不到 Leptonica | Leptonica_DIR 填错,或 vcpkg 没装成功 | 重新执行 vcpkg install leptonica,并把路径指向 share\leptonica |
| 提示找不到 ICU 或 pango | 开了训练相关选项 | 关掉 BUILD_TRAINING_TOOLS;确认确实需要再装依赖 |
| 提示 Windows SDK 版本不存在 | VS 安装时没有勾选 Windows 10 SDK | 运行 VS 安装器补装组件,重试 Configure |
| 卡在“Downloading”很久 | CMake 尝试在线拉取测试图片 | 关 BUILD_TESTS,或配置本地图片目录 |
| CMake 错误:找不到 Ninja | 选择了 Ninja 生成器但环境没装 | 统一用 Visual Studio 生成器,不要混合使用 |
这些报错里最坑的是“Downloading”卡住。Tesseract 的 CMake 脚本在开启测试选项时,会在 Configure 阶段尝试访问外网拉取测试图片;网络一旦不通,整个界面就停在那里,看起来像死机,实际上是在等超时。遇到这种情况,直接把 BUILD_TESTS 关掉,立刻恢复流畅。
3.4 Generate 阶段的最后一个坑
Configure 全部变成白色之后,点击 Generate。多数情况下几秒就结束。如果 Generate 阶段报错,最常见的是“某个目标找不到”。这一步我踩过一个具体案例:因为 Leptonica 是 vcpkg 装的,CMake 自动找到了 Debug 和 Release 两套库配置,但我之前配置过一次别的版本,缓存里残留了旧路径,导致 Generate 时变量冲突。
解决办法很粗暴:在 CMake-GUI 左上角 File -> Delete Cache,然后重新 Configure。记住,缓存变量问题不要试图在 GUI 里一项一项改,删缓存重来往往更快。
Generate 成功后,构建目录里会出现一个 Tesseract.sln 文件。到这里,CMake 图形界面的工作全部完成,接下来进入真正耗时间的编译环节。
4. 从 Generate 到 Release 编译:整个过程与问题记录
4.1 打开解决方案后的第一件事
双击 Tesseract.sln,Visual Studio 会先弹出目标框架和平台相关提示,直接确定。然后顺手把解决方案配置切换成 Release,平台切换成 x64。为什么用 Release?因为 Debug 版 Tesseract 的性能和识别速度都明显下降,而且 Debug 版携带的大量调试信息会让 dll 膨胀;除非你要深入断点调试库本身,否则普通集成使用 Release 就够了。
切换好之后不要急着点“生成解决方案”。先看一下解决方案资源管理器里到底有哪些项目。我这次关闭了训练工具和测试,项目数量少了很多,核心就是 tesseract(动态库)和 tesseract_main(命令行入口)。如果你开了 BUILD_TRAINING_TOOLS,还会看到 text2image、tesstrain 等项目,那些不常用,编译也费时间。
4.2 先编译哪个项目更省时间
第一次编译,我强烈建议先右键 tesseract 项目,选择“仅生成项目”。原因很简单:这个项目就是 Tesseract 的核心动态库,它编译通过,你就等于拿到了最重要的东西。而且先单独编一个小目标,能快速暴露头文件和链接错误,不会让整个解决方案的错误信息淹没在几百条输出里。
等 tesseract 项目编译成功,再右键 tesseract_main,生成命令行工具。最后再“生成解决方案”把剩余项目扫一遍。这套顺序对排查问题非常友好。如果一上来就生成整个解决方案,几十个项目同时编译,错误信息刷得飞快,新手很容易被吓住。
编译耗时方面,Tesseract 5 的核心库在普通配置的电脑上大约需要十到二十分钟。如果开了训练工具,可能要四十分钟以上。所以如果不是要训练字库,就把训练工具关掉,等待期间甚至可以干点别的。
4.3 高频编译错误对照表
编译过程中最常见的几个错误,我在多个环境里都遇到过:
| 错误信息 | 原因 | 处理办法 |
|---|---|---|
| fatal error C1083: 无法打开包括文件 allheaders.h | Leptonica 头文件路径没找到 | 回到 CMake 检查 Leptonica_DIR,或把 Leptonica 的 include 路径加进项目附加包含目录 |
| LNK2019 无法解析的外部符号 | 链接时找不到 Leptonica 库或 Tesseract 导入库 | 检查附加依赖项是否正确填写 tesseract50.lib,并确认 lib 路径是 Release 版本 |
| MSB8020 无法找到 v140/v142 工具集 | 工具集版本和 CMake 生成配置不一致 | 在 VS 菜单里重定解决方案目标,选择当前 VS 对应的 v142 |
| error C2065 未声明的标识符 | 不同 Tesseract 版本宏定义差异 | 检查是否把 5.x 的代码拿到 4.x 的头文件下编译 |
| 无法打开文件 tesseract50.lib | 附加库目录没填对 | 先用绝对路径验证,再改成相对路径 |
其中 LNK2019 是最多的。原因通常是:CMake 配置阶段找到了 Leptonica,但自己的项目在“链接器 -> 输入 -> 附加依赖项”里只填了 tesseract50.lib,没有告诉链接器 Leptonica 的路径。如果你的 Leptonica 是 vcpkg 装且按共享库编译,会生成一个 leptonica.lib 导入库,链接时需要一并加上。我的经验是:在附加依赖项里把 tesseract50.lib 和 leptonica.lib 都填上,别含糊。
4.4 Debug 和 Release 两套产物的管理
还有一个隐藏坑是 Debug 和 Release 库混用。有的项目平时用 Debug 编译,但链接的是 Release 版 tesseract50.lib,运行时容易出现各种诡异问题。因为 VS 默认的 Debug 模式使用的运行库是 /MTd 或 /MDd,而 Release 库是 /MT 或 /MD,二者对内存堆的分配方式不一样,跨模式链接轻则警告、重则崩溃,而且这种崩溃很难排查。
我的做法是把两套产物分别放到带后缀的文件夹:build\bin\Release 和 build\bin\Debug。编译完一个配置后再切换另一个配置生成一遍。这样后续自己项目要用哪个版本,直接复制对应目录里的 dll 和 lib。
5. 编译产物怎么接到自己的 C++ 项目里:使用方案
5.1 需要留下来的四个部分
编译完成之后,bin 目录里会多出不少文件。对集成来说,只需要保留四样。
一是头文件。Tesseract 的 include 目录下有 tesseract 和 leptonica 两个子目录,其中 tesseract\baseapi.h 是最主要的入口。Leptonica 的 allheaders.h 也不能丢,因为调用 pixRead 和 pixDestroy 都要它。
二是导入库。Release 目录下一般能看到 tesseract50.lib(版本不同尾号可能不同)。如果用的是共享库,这个 lib 只是链接时用,运行时不负责带入代码。
三是动态库。通常包括 tesseract50.dll,以及 Leptonica 的 dll(名称类似 leptonica-1.83.0.dll)。
四是语言数据 tessdata,这个单独放,不用跟 dll 放一起,后面专门讲。
我会在自己的项目里创建一个统一的第三方目录:
thirdparty\ include\ tesseract\ leptonica\ lib\ x64\Release\ bin\这样做的好处是,所有项目通过相对路径引用,换电脑或多人协同时只要同步这一个第三方目录。
5.2 VS 工程属性配置步骤
拿到第三方目录后,配置你自己的项目属性。
- 打开项目属性(右键项目 -> 属性),配置选 Release,平台选 x64。
- C/C++ -> 常规 -> 附加包含目录,填 thirdparty\include。
- 链接器 -> 常规 -> 附加库目录,填 thirdparty\lib\x64\Release。
- 链接器 -> 输入 -> 附加依赖项,填 tesseract50.lib; leptonica.lib。
- 生成事件 -> 后期生成事件 -> 命令行,可以加一条复制命令,把 dll 从 thirdparty\bin 复制到目标输出目录,或者把 thirdparty\bin 加入系统 PATH。
我最喜欢的是最后一种的变体,不是改全局 PATH,而是在“调试 -> 环境”里对当前工程单独设置:
PATH=$(ProjectDir)..\thirdparty\bin;%PATH%这样按 F5 调试时,系统会自动到 thirdparty\bin 里找 dll,不用每次手动复制,也不会影响其他项目。等到发布时,再把必要的 dll 和 exe 放进同一个发布目录。
5.3 最小可用的 C++ 识别示例
参考下面的代码,这是一个完整可编译的 OCR 识别 Demo:
#include <tesseract/baseapi.h> #include <leptonica/allheaders.h> #include <iostream> int main() { Pix* image = pixRead("sample.png"); if (image == nullptr) { std::cerr << "read image failed" << std::endl; return 1; } tesseract::TessBaseAPI api; // 第一个参数是 tessdata 父目录,nullptr 表示用环境变量 TESSDATA_PREFIX if (api.Init(nullptr, "eng+chi_sim") != 0) { std::cerr << "init tesseract failed" << std::endl; pixDestroy(&image); return 1; } api.SetImage(image); api.SetPageSegMode(tesseract::PSM_AUTO); char* outText = api.GetUTF8Text(); if (outText != nullptr) { std::cout << outText << std::endl; delete[] outText; } api.Clear(); pixDestroy(&image); return 0; }这段代码有两个容易出错的地方。第一,pixRead 的图片路径是相对当前工作目录的。调试时 VS 的默认工作目录往往是项目根目录,而不是 exe 所在目录,图片很容易找不到,先用绝对路径跑通再改。第二,api.Init 的第一个参数为空时,必须在系统环境变量里设置 TESSDATA_PREFIX,否则 Init 可能显示成功,GetUTF8Text 却什么都识别不出来。这两个点我都踩过,先记下来。
5.4 命令行工具快速验证
代码写了一大堆,如果不确定是代码问题还是环境问题,最快的验证方式是用编译好的 tesseract.exe:
tesseract sample.png out -l eng+chi_sim --psm 6这条命令会读取 sample.png,输出 out.txt。如果这一步能正确产出中文文本,说明核心库和语言数据都没问题,剩下就是 C++ 工程配置的事。反过来,如果命令行都识别失败,就不要纠结项目属性了,回到语言数据路径或图片本身去排查。
6. 语言数据与中文识别的坑:tessdata 的完整处理
6.1 TESSDATA_PREFIX 到底指到哪里
tessdata 是 Tesseract 的语言数据总称,里面放着 eng.traineddata、chi_sim.traineddata 这类文件。编译产物本身不包含任何语言包,所以必须单独准备。而 Tesseract 查找语言数据的方式,很多新手第一次都会搞错。
TESSDATA_PREFIX 这个环境变量设置的目录,并不是 tessdata 文件夹本身,而是它的父目录。举例来说,如果你把语言数据放在:
D:\work\ocr\data\tessdata\那么 TESSDATA_PREFIX 应该设成:
D:\work\ocr\dataTesseract 的内部逻辑是:拿到 datapath 之后,自动在后面拼接一个 tessdata 子目录。这个设计我至少踩了两次。解决方法是打开系统设置,新建环境变量 TESSDATA_PREFIX,填 D:\work\ocr\data,然后重启 Visual Studio 让新环境变量生效。注意,环境变量改了之后,已经打开的 VS 不会自动刷新,必须关掉重开。
另一个替代方案是直接用 api.Init("D:/work/ocr/data", "eng"),绕过环境变量。但字符串里的斜杠建议统一用正斜杠,我这里碰到过反斜杠在某些环境下解析异常的情况。
6.2 三类语言包的选型对比
同一个语言有多个版本的语言数据,第一次接触的朋友容易看懵。整理成表格:
| 数据集 | 单个语言包大小 | 识别速度 | 精度 | 适合场景 |
|---|---|---|---|---|
| tessdata_fast | 约 4MB | 最快 | 一般 | 移动端、实时要求高、批量吞吐 |
| tessdata | 约 10MB | 较快 | 较好 | 大多数通用场景,我日常选这个 |
| tessdata_best | 约 20MB 以上 | 最慢 | 最高 | 离线高精度文档识别 |
中文场景特别提醒:不要一上来就用 tessdata_best,它在文本密集的图片上会慢到让人怀疑人生。先用标准 tessdata 跑通流程,如果精度确实不达标,再换 best 对比。另外,语言包版本要和 Tesseract 大版本匹配,4.x 的语言包用在 5.x 的核心库上,轻则日志出现警告,重则识别结果为空。我遇到过旧版 chi_sim.traineddata 导致不输出中文的情况,换成配套版本立竿见影。
6.3 中文识别的参数调整与预处理
中文识别和英文识别有两点明显差异:一是字符集大小,中文常用字就有几千个,候选字搜索空间大,速度自然慢;二是排版结构,中文文档经常混合中西文、数字、标点,段落分析容易出错。实际运行中,我常用的参数调整如下:
api.SetPageSegMode(tesseract::PSM_AUTO); api.SetVariable("preserve_interword_spaces", "1");第一个是把页面分割模式设为自动,适合大部分截图和扫描件。第二个是保留字间空格,对英文单词之间是否需要留空间的判断更保守,方便后续按空格分词。
对于分辨率较低的截图,比如聊天记录、表格截图,直接识别效果很差。我的经验是先用 OpenCV 把图片放大 2 倍再交给 Tesseract,中文小字的识别率能明显提升。原因很简单,Tesseract 对字符高度一般要求在 20 像素以上,低分辨率下汉字笔画糊成一片,识别器再强也无力回天。预处理代码大致是:
cv::Mat src = cv::imread(srcPath, cv::IMREAD_GRAYSCALE); cv::Mat big; cv::resize(src, big, cv::Size(src.cols * 2, src.rows * 2), 0, 0, cv::INTER_CUBIC);然后把 big 转成 Leptonica 的 Pix 类型交给 Tesseract。此外,尽量保证图片背景干净、字迹清晰,这比调整任何参数都重要。
6.4 识别结果为空白的排查顺序
使用过程中最让人崩溃的是 Init 不报错、图片也读进去了,但 GetUTF8Text 返回空字符串。我总结了一条排查顺序:
- 确认语言包的目录结构。TESSDATA_PREFIX 是否指向正确的父目录,tessdata 文件夹下有没有对应的 traineddata 文件。
- 确认图片是否被正确读取。可以先 pixWrite 到另一个文件名,查看图像内容是否正常。
- 确认语言代码。中文是 chi_sim,不是 zh-CN,也不是 chinese。写错语言代码时 Init 可能不报错,但不会有任何输出。
- 改用 PSM_SINGLE_LINE 试试。如果单行文本识别有输出,说明是版式分析阶段出了问题,可以回到 PSM_AUTO 并调整图片预处理。
这套顺序基本覆盖了 90% 的空白结果问题。我在项目里按这个顺序排查,几乎每次都能在十分钟内定位。
7. 把这套方案固化下来:脚本化与后续扩展
7.1 把 CMake 步骤固化成命令行脚本
图形界面适合第一次理解流程,但如果要在多台机器上重复配置,我强烈建议把 CMake 步骤写成脚本。下面是等价于前面所有 GUI 操作的命令:
cmake -S D:\work\ocr\tesseract-5.3.4 ^ -B D:\work\ocr\build-tesseract ^ -G "Visual Studio 16 2019" -A x64 ^ -DLeptonica_DIR=D:\vcpkg\installed\x64-windows\share\leptonica ^ -DBUILD_TRAINING_TOOLS=OFF ^ -DBUILD_TESTS=OFF cmake --build D:\work\ocr\build-tesseract --config Release第二行命令执行后,CMake 会自动加载配置好的工程并编译 Release。以后想换 VS2022,把 -G 参数改成 Visual Studio 17 2022 即可,其他逻辑不变。
7.2 批量识别与性能优化经验
当你从“识别一张图”走向“识别几千张图”时,有几个优化点值得关注。
第一,不要每张图都创建一个 TessBaseAPI 对象。初始化非常昂贵,建议在程序生命周期里复用同一个对象,每张图只调用 SetImage 和 GetUTF8Text。
第二,大量小图时尽量用内存数据加载,减少磁盘 IO。Leptonica 支持从内存 buffer 创建 Pix,不需要先落盘。
第三,Tesseract 的线程安全限制较多。多线程识别时,最好不要让多个线程共享同一个 TessBaseAPI 对象,而是每个线程各持一个实例。如果想提高吞吐,用固定线程池按图片队列取任务,比盲目开几百个线程有效得多。
我自己做过一个简单测试,同样一批 200 张截图,复用对象加双线程处理,比“每张新建对象 + 单线程”快了将近四倍。如果你的场景也追求吞吐,这些点值得实际验证。
7.3 归档产物的习惯
最后分享一个工作习惯:每次编译成功之后,我会把 build 目录里的 include、bin、CMakeCache.txt 一起打包成 zip,并在文件名上标注 Tesseract 版本、Leptonica 版本、VS 版本。
例如:tesseract-5.3.4-leptonica-1.83-vs2019-x64-release.zip。
这样做的价值在于,过了半年再回来接这个项目,直接解压覆盖 thirdparty 目录,不需要重新编译,也不需要重新回忆 CMake 里填了什么。CMakeCache.txt 就像一个快照,很多当时排了半天的问题,答案其实早就写在里面。
最后说句实在话,这套 Windows 下编译 Tesseract 的事,真不复杂,但它拼的是版本匹配和细节耐心。只要把依赖关系想清楚、把选项含义弄明白,一次跑通之后,后续基本是复制粘贴的过程。希望这篇记录能让你少走我已经走过的弯路。