前面完成了利用easyOCR包进行离线OCR识别的img2txt.py程序,使得在centOS系统上布设好python环境、安装easyOCR包后,即可利用命令行的方式实现图像文件的ocr识别。
但是,上面的方式需要一台安装好python环境和安装好easyocr包的centos机器,显得稍微麻烦些!利用pyinstaller打包程序,可以将img2txt.py程序打包为一个img2txt可执行程序,并赋予其x也即可执行的权限(windows环境下就是img2txt.exe程序),是不是就可以直接拷贝到一台单纯的centos机器上了?答案是肯定的!
但是,先提前说结论吧?由于easyOCR包中用到了庞大的pytorch包,所以利用pyinstaller -F 选项打包生成的单独的可执行文件img2txt特别的大,有1.8G之大,运行起来由于好像是需要将深度学习的一堆.so文件拷贝到home文件夹(Windows系统中就是C盘下的某个临时文件夹),所以速度特别的慢。。。据说不使用-F选项、生成一个文件夹会好些,后面我就没有再用这个pyinstaller打包了,还是直接使用的python环境、生成docker的方式来使用离线ocr。。。
但是,还是记录一下pyinstaller对前述img2txt.py打包时容易出错的地方,以及应对的方法:
首先就是需要在pyinstaller安装后的程序site-packages/pyinstaller/hooks文件夹里面新建补充一个文件hook-easyocr.py,内容如下所示:
- #新建该文件后放入site-packages/pyinstaller/hooks文件夹里面。
- from PyInstaller.utils.hooks import collect_submodules,collect_data_files
-
- hiddenimports = collect_submodules('easyocr')
-
- datas = collect_data_files('easyocr')
不然,就会出现诸如 No such file or directory:'_MExx\xx\xx' 之类的错误。其实,hooks文件夹中包含了很多安装包的hook-***.py文件,但是由于easyOCR安装包没有生成对应的hooks文件,所以会出现找不到临时文件的错误,而从上面的内容可以看出,hook-easyocr.py文件的作用就是告诉pyinstaller打包程序,在打包时“记得”将easyocr包的模块和数据一并打包进去。。。
再一个就是,当打包后出现诸如no module found name xxxx错误的情况,该错误表示pyinstaller没有找到xxxx库,此时可以打开对应的例如img2txt.spec文件,将所缺少的库添加到其中的hiddenimports中,如下所示:
- ...
- datas=[]
- hiddenimports=['numpy.random.common','numpy.random.entropy'],
- ...
保存该文件后,不用再对py源文件进行编译,只对该spec文件进行编译即可:
pyinstaller -F xxxx.spec
最后,如果出现诸如
ImportError:/usr/lib64/libstdc++.so.6:version `GLIBCXX_3.4.21` not found(required by home/miniconda3/envs/ocrenv/lib/python3.9/site-packages/...)
之类的错误,则可以执行下面的命令修改环境变量:
首先,用 find / -name "libstdc++.so*" 命令查找包含“libstdc++.so”的所有文件;
然后,假定找到的其中一个在/home/super/miniconda3/envs/ocrenv/lib/libstdc++.so 路径下,用命令
strings /home/super/miniconda3/envs/ocrenv/lib/libstdc++.so | grep GLIBCXX
查看 GLIBC 是否高于或等于GLIBCXX_3.4.21;
最后,找到以后用:
export LD_LIBRARY_PATH=/home/super/miniconda3/envs/ocrenv/lib/:$LD_LIBRARY_PATH
修改环境变量,这个语句是临时修改环境变量并生效,关机后失效,如果需要永久修改环境变量可以将其添加到~/.bashrc文件中去即可。