前面完成了利用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文件中去即可。