Win10+VS2017编译opencv3.2.0和opencv_contrib3.2.0来调用text模块

前言

最近做一些字符识别的事情,想试一下opencv_contrib里的Text(自然场景图像中的文本检测与识别)模块。

我参照了网上的一些教程去编译opencv+opencv_contrib,但是最后去跑样例程序(比如end_to_end_recognition.cpp ),在运行生成的exe文件时会提示OCRTesseract(33): Tesseract not found.类似的错误。

其原因 [1] 是Text模块中的字符识别部分使用的是Tesseract OCR,因此在使用CMake编译生成OpenCV项目文件时,应该确保它能找到Tesseract.
也就是需要先编译好Tesseract,接着告诉CMake你的Tesseract在哪(包括它的头文件.h以及lib文件),然后再编译OpenCV.

最终运行样例程序得到的端到端字符识别效果图如下:
End to End Scene Text样例程序识别结果


目录结构:

  • 安装依赖
  • 编译Tesseract
    • 使用CPPAN下载依赖包
    • 使用cmake-gui进行编译
    • 用VS编译生成debug和release库
  • 编译opencv+opencv_contrib
  • 测试end_to_end_recognition
    • 把OpenCV库文件配置到到项目中
    • 运行样例程序

以下是我的具体步骤:(下面的方法是我自己试过可行的,不保证方法一定很简洁,应该说确实有些繁琐,因为我对编译源码经验也一般,我想肯定有更加简洁的方法可以办到)

事实上,我已经找到了更加简洁的方法,对手动编译没兴趣的同学,可以直接移步


安装依赖

注意在安装VS2017的时候需要勾选使用C++的桌面开发这个选项,否则后面用CMake编译的时候可能会提示找不到C++编译器。(估计应该就是需要右边小红框里的那个东西,但是保险起见我还是全装了=-=)

install_vs


编译Tesseract

下载完源代码之后,我习惯先创建3个文件夹sources, buildinstall 分别用来存放解压出来的源代码、以及之后会编译输出的工程文件和安装文件。

3-folders

使用CPPAN下载依赖包

在用CMake(cmake-gui)编译tesseract源代码之前,需要先用CPPAN下载依赖项,首先打开命令行提示工具(cmd):

1
2
3
d:
cd path_to_tesseract //比如我的是 D:\Tesseract\sources
cppan //下载依赖的软件包,如leptonica等

CPPAN感觉就是一个C++的包管理器,类似于Java的Maven、JavaScript的npm. 我也是第一次接触,看了tesseract的官方编译文档才知道有这么个神奇的东西。
当在tesseract根目录下运行cppan时,它会读取cppan.yml文件中所规定的项目的依赖项(如下图所示),帮你下载好需要的依赖包和初始化编译器配置。具体可以参考CPPAN官方文档

dependencies

使用cmake-gui进行编译

打开cmake-gui进行编译:

  1. where is the source code中选择tesseract的源码路径,比如我的是D:/Tesseract/sources
  2. where to build the binaries里面选择你要编译到的路径,例如D:/Tesseract/build
  3. 点击Configure,这时会弹出一个对话框,让你设置生成器,选择Visual Studio 15 2017 Win64,点击Finish,这个时候CMake会开始在build目录下生成一些配置文件,如 CMakeCache.txt 等。
  4. 完成之后会在屏幕中间出现一堆Name和Value的参数,找到CMAKE_INSTALL_PREFIX 将其设置成你想要的安装路径,例如 D:/Tesseract/install
  5. 再次点击Configure,然后点击Generate,这时你可以看到在build目录下已经生成了名为tesseract.sln的VS工程(就是这么神奇^-^)。

配置cmake

选择生成器

用VS编译生成debug和release库

  1. 打开build目录下的tesseract.sln的VS工程(直接在cmake-gui中点开Open Project是一样的)
  2. 编译生成Debug版本库:首先选择Debug生成模式, 找到CMakeTargets中的ALL_BUILD,点击右键–>生成解决方案。这一步会需要一些时间,之后你会在build/bin/Debug目录下看到新生成了很多文件,其实这时候tesseract已经可以用了(前提是在此目录下面下载好训练数据文件)。
  3. 生成安装文件:找到CMakeTargets中的INSTALL,然后右键选择仅限于项目–>仅生成INSTALL,然后在D:\Tesseract\install中就会看到生成好生成头文件和可执行文件等。
  4. Release版本的方法相同,选择Release模式,重复2、3即可。
  5. 编译错误解决: 在编译生成过程中可能会遇到因为文件编码问题而产生的错误,一个出错的地方是pango-language-sample-table.h ,需要改成UTF-8 编码;另一个是equationdetect.cpp,需要改成ANSI/OEM-简体中文 GBK编码。

有同学可能想说,那我直接点击仅生成INSTALL行不行? 你可以自己尝试一下,答案是不行的😂

其实感觉这一套流程,和在Linux系统上用命令打./configure, make, make install...之类的应该是对应的,只是这里改成了在Windows上用CMake、VS等图形化界面地去完成了这些事情。

有些尬尴的是,这个时候tesseract还不能用,主要是要解决两个问题

  1. 如果你在命令行中install/bin目录下输入tesseract phototest.tif stdout (phototest是一张待识别的字符图片,stdout表示将识别结果输出到标准输出即在命令行中直接显示), 会提示丢失pvt.cppan.demo.danbloomberg.leptonica-1.74.4.dll等一系列dll的错误。
    这里我的解决办法比较笨(感觉应该可以通过一些配置,让VS自己拷贝过去),就是直接把build/bin下的dll全部拷贝过去,放到install/bin路径下。
    tesseract_error
    phototest
    copy_dlls.gif

  2. 再次执行tesseract phototest.tif stdout,会提示如下所示的另一个问题,找不到训练数据文件\Tesseract\install\bin\tessdata/eng.traineddata.

    1
    2
    3
    4
    5
    6
    D:\Tesseract\install\bin>tesseract phototest.tif stdout
    Error opening data file \Tesseract\install\bin\tessdata/eng.traineddata
    Please make sure the TESSDATA_PREFIX environment variable is set to the parent directory of your "tessdata" directory.
    Failed loading language 'eng'
    Tesseract couldn't load any languages!
    Could not initialize tesseract.

    解决办法就是到tesseract官网的数据下载页面下载Tesseract 3.05 对应的训练数据 eng.traineddata, 然后在install/bin目录下新建tessdata文件夹,并放入下载好的数据文件eng.traineddata,这样tesseract就可以用了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    D:\Tesseract\install\bin>tesseract phototest.tif stdout
    Page 1
    This is a lot of 12 point text to test the
    cor code and see if it works on all types
    of file format.
    The quick brown dog jumped over the
    lazy fox. The quick brown dog jumped
    over the lazy fox. The quick brown dog
    jumped over the lazy fox. The quick
    brown dog jumped over the lazy fox.

(注:这里可以先将tesseract的bin路径(如:D:\Tesseract\install\bin)加入到环境变量PATH中,因为后面跑样例程序的时候会用到,否则会报错。)


编译opencv+opencv_contrib

编译方法和上面tesseract的步骤非常类似,同样是先用cmake-gui编译,然后用VS生成库文件(先ALL_BUILD,再INSTALL),基本就是照着上面的流程再来一遍。

只是在cmake编译时的一些配置项不同,尤其重要的是你要告诉CMake你的opencv_contrib和tesseract在哪,具体见下表。

Name Value(根据你自己的路径修改) 备注
OPENCV_EXTRA_MODULES_PATH D:/OpenCV/sources/modules/contrib/modules opencv_contrib的路径
CMAKE_INSTALL_PREFIX D:/OpenCV/install 目标安装路径
Tesseract_INCLUDE_DIR D:/Tesseract/install/include tesseract头文件路径
Tesseract_LIBRARY D:/Tesseract/install/lib/tesseract305.lib tesseract lib路径

注:

  1. 在使用cmake-gui的时候可能需要多点几次Configure,因为有些配置项一开始可能找不到。
  2. 在用VS生成OpenCV库文件时,根据不同的编译模式需要指定对应的tesseract的 lib 文件,tesseract305.lib表示release版本,后面加d的tesseract305d.lib为debug版本。
  3. opencv_contrib解压出来的文件名是opencv_contrib_3.2.0,我改成了contrib.

完成之后同样将OpenCV的bin路径(例如D:\OpenCV\install\x64\vc15\bin)加入环境变量PATH,否则运行生成的exe时,会提示找不到相关的 dll 文件。因为你需要把路径写入到PATH,操作系统才知道要去哪里加载它们 [2]

故事进行到这里所有的编译工作就已经结束了,下面就可以开启新篇章,开始在vs中跑样例程序了😁


测试end_to_end_recognition

首先新建一个VS工程(例如叫 textCV ),空项目就行。新建一个源文件,例如source.cpp,把end_to_end_recognition.cpp 里的代码拷贝进去。

把OpenCV库文件配置到到项目中

这步的目的大概就是告诉VS你的opencv头文件和lib库在哪,否则没法编译生成EXE可执行文件 [3]

我是通过添加本地项目属性表来实现的,首先点击视图 –>属性管理器,接着点开属性管理器页面,找到Release|x64 右键添加新项目属性表,然后在新建的属性表上右键–>属性, 在弹出的属性配置页面(见下面的示意图),做如下配置:

  1. C/C++目录–>通用–>附加包含目录,添加opencv头文件目录(共3个),例如:

    1
    2
    3
    D:\OpenCV\install\include
    D:\OpenCV\install\include\opencv
    D:\OpenCV\install\include\opencv2
  2. 链接器–>常规–>附加库目录,添加opencv lib库目录,例如:D:\OpenCV\install\x64\vc15\lib

  3. 链接器–>输入–>附加依赖项,添加opencv库文件:
    Release生成模式为例,命令行输入dir /b *0.lib得到一个完整的列表如下(Debug版的文件名为opencv_*d.lib):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    opencv_aruco320.lib
    opencv_bgsegm320.lib
    opencv_bioinspired320.lib
    opencv_calib3d320.lib
    opencv_ccalib320.lib
    opencv_core320.lib
    opencv_datasets320.lib
    opencv_dnn320.lib
    opencv_dpm320.lib
    opencv_face320.lib
    opencv_features2d320.lib
    opencv_flann320.lib
    opencv_fuzzy320.lib
    opencv_highgui320.lib
    opencv_imgcodecs320.lib
    opencv_imgproc320.lib
    opencv_line_descriptor320.lib
    opencv_ml320.lib
    opencv_objdetect320.lib
    opencv_optflow320.lib
    opencv_phase_unwrapping320.lib
    opencv_photo320.lib
    opencv_plot320.lib
    opencv_reg320.lib
    opencv_rgbd320.lib
    opencv_saliency320.lib
    opencv_shape320.lib
    opencv_stereo320.lib
    opencv_stitching320.lib
    opencv_structured_light320.lib
    opencv_superres320.lib
    opencv_surface_matching320.lib
    opencv_text320.lib
    opencv_tracking320.lib
    opencv_video320.lib
    opencv_videoio320.lib
    opencv_videostab320.lib
    opencv_xfeatures2d320.lib
    opencv_ximgproc320.lib
    opencv_xobjdetect320.lib
    opencv_xphoto320.lib

P.S. 可以在Windows命令行中用tree /f或者是dir /b得到一个文件夹下的所有文件名 [4]

tree

property_sheet

运行样例程序

配置完成后点击生成–>生成解决方案,VS会在项目文件夹的x64/Release目录下生成textCV.exe

此时还需要做最后两件事就是,就是拷贝以下文件到textCV.exe所在文件目录:

  1. 在你的opencv_contrib的text模块的samples文件夹中(如D:\OpenCV\sources\modules\contrib\modules\text\samples)找到以下三个文件trained_classifierNM2.xmltrained_classifierNM1.xmlscenetext01.jpg,并拷贝到项目的x64/Release目录(或是在D:\OpenCV\build\testdata\contrib\text目录中也可以找到)
  2. x64/Release目录中新建tessdata文件夹,然后将eng.traineddata放进去。

最后在命令行窗口中x64/Release目录下运行 testCV scenetext01.jpg,就大功告成了🎉~

test success!

参考

  1. https://www.polarxiong.com/archives/Tesseract-3-05%E5%8F%8A%E4%B9%8B%E5%90%8E%E7%89%88%E6%9C%AC%E7%BC%96%E8%AF%91%E7%94%9F%E6%88%90%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93DLL.html
  2. https://segmentfault.com/a/1190000003496009
  3. http://docs.opencv.org/master/d6/d8a/tutorial_windows_visual_studio_Opencv.html