win7 vs2015 下编译 tesseract 4.1.1

此文章为 汉学@博客园 原创作品,转载请保留版权信息

原文链接:https://www.cnblogs.com/c2soft/articles/13194981.html

 

一、总体思路

各库之间的依赖关系及使用的工具如下:

之前在 win7 64位 + VS2017 + VCPKG 的环境下很顺利地编译了 tesseract 4.1.1,可是当我想对 tesseract 的源码做下改动时,发现编译过程完全被 VCPKG 所接管,没法重新编译 tesseract 库(C语言门外汉,惭愧),于是产生了自己手工编译 tesseract 的想法。

按照网上的教程,直接使用 cppan 、 cmake 编译 tesseract 时,总出现找不到 endianness.h 的问题,经多次尝试,总结出使用 cppan、cmake 生成 leptonica 解决方案,然后使用 cmake-gui 手动生成 tesseract 解决方案的编译方式。

二、环境准备

编译环境:Win7 32位,VS2015

将cmake-3.17.3-win32-x86 解压到 C 盘,cppan.exe 放到 cmake 的 bin 文件夹中,将C:\cmake-3.17.3-win32-x86\bin 添加到 Path 变量中。

三、编译leptonica

1、  在 c 盘创建storage 文件夹,leptonica的所有依赖库都将下载到此文件夹中。编辑C:\Users\用户名\.cppan\cppan.yml,修改storage_dir,使其指向 c:\storage

 

2、  执行 cppan –V 初始化,将在c:\storage 中创建所需的文件夹结构。

3、  下载leptonica-1.78.0.tar (有网友建议使用1.76版本,说 1.79 版本编译时只生成 dll,没有lib。经验证,1.76, 1.78版本都可以正常编译。根据leptonica官网上的文档,偶数版本为稳定版本,因此直接下载1.78,1.79是否有问题未去尝试),将leptonica-1.78.0 文件夹解压到 C 盘根目录下。

4、  在C:\leptonica-1.78.0 下创建 build 文件夹,CMD窗口中执行:

cd C:\leptonica-1.78.0
cppan
cd build
cmake ..  (在build 文件夹中执行 cmake,别少了两个点点)

C:\leptonica-1.78.0\build 下顺利生成 leptonica.sln 解决方案,使用 VS2015 打开它,VS2015->生成->配置管理器->release,先编译生成cppan-d-b-d,将在C:\storage\bin\020a56a6\Release 下生成pvt.cppan.demo.jpeg-9.2.0.dll 等7个leptonica所需的DLL文件。

5、 再编译生成 leptonica,结果生成:

C:/leptonica-1.78.0/build/src/Release/leptonica-1.78.0.lib

C:/leptonica-1.78.0/build/src/Release/leptonica-1.78.0.exp

C:\leptonica-1.78.0\build\bin\Release\leptonica-1.78.0.dll

6、  如果想生成兼容XP的文件,需要分别对 cppan-d-b-d 和leptonica 项目设置:常规->平台工具集:v140xp,有链接器选项的,还要设置:链接器->系统->所需最低版本:5.01

7、  此时C:\leptonica-1.78.0\build\src 下已经生成endianness.h 文件(网上很多编译的方法都缺少此文件)。

 

四、编译tesseract

1、  下载 tesseract ,注意选择 4.1.1 稳定分支,不要下载 master 版本,master 代码更新后可能出现其它编译问题。将tesseract-4.1.1文件夹解压到C盘根目录,在tesseract-4.1.1下创建build文件夹。

2、  运行cmake-gui,指定source文件夹到C:\tesseract-4.1.1(必须指定到CMakeLists.txt所在的文件夹),指定 build 文件夹到C:\tesseract-4.1.1\build,点“configure”,将显示红色的错误信息,需要指定leptonica 文件夹。

 

3、  根据上面的提示,leptonica 文件夹需要定位到包含 LeptonicaConfig.cmake 或 leptonica-config.cmake 的文件夹,在 leptonica 的文件夹中搜索这两个文件,找到C:\leptonica-1.78.0\build\LeptonicaConfig.cmake,因此将Leptonica_DIR 指向C:\leptonica-1.78.0\build\,再次 configure 。

4、  又出现新的错误,根据提示,是因为下载下来的icu32.zip 的 hash 值与预期的不同,打开C:\tesseract-4.1.1\src\training\CMakeLists.txt,第39行中可以发现下载的网址,到该网站手工下载icu4c-56_1-Win32-msvc10.zip,计算它的MD5值,与期待的一致。

 

在tesseract文件夹中搜索 icu32.zip(就是MD5值错误的文件),将下载的 icu4c-56_1-Win32-msvc10.zip 更名为 icu32.zip 替换刚才搜索到的 icu32.zip,再次configure。

 5、  点configure后,结果提示“Configuring incomplete, errors occurred!”,查看提示信息,前后有两处红色的错误,先解决前面的。

 

cmake 试图在 C:/leptonica-1.78.0/build/ 查找 cppan.cmake 文件,可是没有找到。到 C:/leptonica-1.78.0 中搜索一下 cppan.cmake,在C:\leptonica-1.78.0\build\exports 下发现了这个文件,将其复制到C:/leptonica-1.78.0/build/,再次 configure。

Configuring done!刚才后面还有一处错误,现在没有了。点 generate,Generating done!

C:\tesseract-4.1.1\build下已经生成了tesseract.sln。

6、  用 VS2015 打开tesseract.sln,设置好编译选项后先生成 libtesseract,出现以下错误信息:

 

 

查找 allheaders.h,位于C:\leptonica-1.78.0\src下,将C:\leptonica-1.78.0\src加入项目的包含目录即可。

 

7、  再次生成,提示“错误C1083       无法打开包括文件: endianness.h”,经查找,endianness.h保存在C:\leptonica-1.78.0\build\src 下,该文件夹下面只有config_auto.h、endianness.h两个头文件,因为刚才已经把C:\leptonica-1.78.0\src加入了包含目录,这次不再另添加包含目录了,将两个头文件直接复制到C:\leptonica-1.78.0\src下。

8、  再次生成,提示“错误 LNK1181  无法打开输入文件 pvt.cppan.demo.gif.lib”,因为前面编译leptonica时生成的lib文件名为C:\storage\lib\020a56a6\Release\pvt.cppan.demo.gif-5.1.4.lib,所以导致这里无法打开输入文件,在VS中点击项目的 VC++目录->库目录->编辑,将C:\storage\lib\020a56a6\Release\加入到库搜索目录中:

 

 

9、  点项目的 链接->输入->依赖附加项->编辑,将pvt.cppan.demo.gif.lib、pvt.cppan.demo.jpeg.lib、pvt.cppan.demo.png.lib、pvt.cppan.demo.tiff.lib、pvt.cppan.demo.webmproject.webp.lib、pvt.cppan.demo.openjpeg.openjp2.lib几个项目逐一加入leptonica编译结果的版本号:

 

 再次生成,顺利生成

C:/tesseract-4.1.1/build/Release/tesseract41.lib

C:/tesseract-4.1.1/build/Release/tesseract41.exp

C:\tesseract-4.1.1\build\bin\Release\tesseract41.dll

10、编译生成tesseract,会遇到以上步骤7、8、9的问题,照上面的方法即可解决。也可以跳过第8步,在第9步中加入库文件的全路径也可以。

 

五、改进与提高

1、编译完 tesseract.exe 后,突然心血来潮,想把全部的 TrainTools 编译出来,编译时又遇到了上面步骤 8、9 的问题,需要手工对附加依赖项加入版本号,每编译一个 traintool 都要修改 6 处,一共 10 多个工具呢!有没有一劳永逸的方法呢?猜测是因为在编译 leptonica 时生成的lib文件名为C:\storage\lib\020a56a6\Release\pvt.cppan.demo.gif-5.1.4.lib,而在 tesseract 项目中需要导入的库为 pvt.cppan.demo.gif.lib,导致二者不一致,那么只要在编译 leptonica 时生成的 pvt.cppan.demo.gif-5.1.4.lib 不带版本号,就可以与 tesseract 无缝结合了。

在 leptonica 的文件夹中搜索包含 “pvt.cppan.demo.gif” 的文件,在 C:\leptonica-1.78.0\.cppan\CMakeLists.txt 中找到了线索:

if (CPPAN_USE_CACHE)
    # pvt.cppan.demo.webmproject.webp-1.0.0
    cppan_include("C:/storage/obj/33/8b/7ef3/generate.cmake")
    # pvt.cppan.demo.jpeg-9.2.0
    cppan_include("C:/storage/obj/97/2a/155a/generate.cmake")
    # pvt.cppan.demo.gif-5.1.4
    cppan_include("C:/storage/obj/d6/de/c13d/generate.cmake")
    # pvt.cppan.demo.tiff-4.0.9
    cppan_include("C:/storage/obj/1f/16/f783/generate.cmake")
    # pvt.cppan.demo.png-1.6.35
    cppan_include("C:/storage/obj/44/f1/4690/generate.cmake")
    # pvt.cppan.demo.openjpeg.openjp2-2.3.0
    cppan_include("C:/storage/obj/71/a6/8bbe/generate.cmake")
else()
    # pvt.cppan.demo.webmproject.webp-1.0.0
    cppan_include("C:/storage/src/33/8b/7ef3/include.cmake")
    # pvt.cppan.demo.jpeg-9.2.0
    cppan_include("C:/storage/src/97/2a/155a/include.cmake")
    # pvt.cppan.demo.gif-5.1.4
    cppan_include("C:/storage/src/d6/de/c13d/include.cmake")
    # pvt.cppan.demo.tiff-4.0.9
    cppan_include("C:/storage/src/1f/16/f783/include.cmake")
    # pvt.cppan.demo.png-1.6.35
    cppan_include("C:/storage/src/44/f1/4690/include.cmake")
    # pvt.cppan.demo.openjpeg.openjp2-2.3.0
    cppan_include("C:/storage/src/71/a6/8bbe/include.cmake")
endif()

原来 gif、png 这些  leptonica 的依赖库的配置在 c:\storage\src 下,到  c:\storage\src 中搜索包含 “pvt.cppan.demo.gif” 的文件,找到了 C:\storage\src\d6\de\c13d\CMakeLists.txt,其中包含以下代码:

if (CPPAN_SHORT_LOCAL_NAMES)
    set_target_properties(${this} PROPERTIES OUTPUT_NAME gif-5.1.4)
else()
    set_target_properties(${this} PROPERTIES OUTPUT_NAME pvt.cppan.demo.gif-5.1.4)  // 去掉“-5.1.4”后,只生成 pvt.cppan.demo.gif.lib
endif()

试了一下,只要将 OUTPUT_NAME 中的版本号去掉,编译时生成的 lib 就是没有版本号了。

在编译 leptonica 时, 在执行完 cppan 命令,下载好全部依赖库的源代码后,先不要执行 cmake,到c:\storage\src 下搜索 “CMakeLists.txt”,一共找到 10 个,在每个文件中查找 “OUTPUT_NAME”,将 OUTPUT_NAME 后面的版本号去掉,然后再执行 cmake,这样生成的解决方案编译后就会得到不带版本号的 lib 文件了,编译 tesseract 时的步骤 8、9 就可以免去了。

2、在编译 TrainTools 时还遇到一个问题:就是每编译一个项目,就要设置包含目录和库目录,能否设置成全局属性,不再一一设置呢?后来找到了方法:在 VS 中打开 视图->其他窗口->属性管理器,在任一项目下找到 Microsoft.Cpp.Win32.user 打开,

对其设置包含目录和库目录后,就是全局性质的设置了,其它项目就不用再逐一设置了。

六、小结

以上记录的是解决问题的过程,实际在编译时可以把步骤再优化一些,简要记录如下:

  • cppan 下载 leptonica 依赖库的源代码
  • 在 c:\storage\src 下搜索 CMakeLists.txt(一共10个),将其中  OUTPUT_NAME 后面的版本号去掉
  • cmake 生成 leptonica 解决方案,VS 编译之
  • 将 C:\leptonica-1.78.0\build\src 中的 config_auto.h、endianness.h 复制到 C:\leptonica-1.78.0\src 中,将 C:\leptonica-1.78.0\build\exports\cppan.cmake 复制到 C:\leptonica-1.78.0\build
  • 在 cmake-gui 中设置  leptonica 路径为 C:\leptonica-1.78.0\build\ ,替换 icu32.zip,生成 tesseract 解决方案
  • VS 打开 tesseract 解决方案,全局包含目录添加 C:\leptonica-1.78.0\src ,全局库目录添加 C:\storage\lib\020a56a6\Release,然后就可以逐一编译了

七、后记

 这种编译方式的优点在于,tesseract 所依赖的其它库使用 cppan 和 cmake 自动下载源代码,生成解决方案,全程自动化;而 tesseract 使用手工编译,如果需要改动其源代码,可以随时重新编译它,比较灵活。将自己编译的全过程记录下来,希望对大家有所帮助。

下载 traineddata 的页面是 https://tesseract-ocr.github.io/tessdoc/Data-Files,不知道为什么下载不下来。

 

BTW:

我使用 tesseract 对下面的验证码图片

进行识别时遇到了很诡异的问题,本以为这个图片很清晰,而且没有做变形处理,tesseract 应该可以轻松识别。可是 tesseract 将其识别为 ZING。开始我以为是 tesseract 使用词库对识别结果做了纠正,可是在源代码中禁用词库后,结果仍然是 ZING。

将原图放大之后观察,4个字母之间的间隔是1个像素,在 PhotoShop 中将字符间距拉至2像素,tesseract 识别为 Z2NG;将字符间距拉到3像素,又识别为 ZING;当间距拉大到4像素以上时,就完全可以正确识别了。

使用 Tesseract 的multilang_debug_level 参数分别对间距为2像素、3像素的图片测试,结果如下:

猜想与字符间距有关,可是在参数表里没找到哪个参数可用,如果哪位网友有办法解决,欢迎在下方留言指教或者给我发邮件 731805810@qq.com 。

 

posted @ 2020-06-26 14:43  汉学  阅读(1331)  评论(6编辑  收藏  举报