打包为一个exe完成后,在执行exe时,报错:
ImportError: ERROR: recursion is detected during loading of “cv2” binary extensions. Check OpenCV installation.
如下图所示:
pyinstaller和cv2版本存在兼容问题,卸载已有的opencv-python,安装opencv-python=4.5.3.56
本人安装的为python3.7,pyinstaller5.1,opencv版本高了.
可参见这里:https://blog.csdn.net/weixin_50850903/article/details/125231985
打包为一个exe完成后,在执行exe时,报错:缺少general.pyc和coco128.yaml。如下图所示。
yolov5中应该是用到这两个,但是没包含。
(1)general.pyc为二进制文件,为general.py编译后的格式,在VSCode中,运行工程文件,python中运行general.py时,自动生成了这个pyc文件,这个文件位于文件夹下面。
但这里生成的是general.cpython-37.pyc,不是general.pyc,这也可能是找不到的原因。
将其进行重命名为general.pyc即可。
然后把他放在了utils下面。
(2)coco128.yaml为文本格式文件。工程中就有,在data\下面。直接用即可。
解决方法,在spec中包含这两个文件即可。
spec定义如下:
a = Analysis(['D:XXX\\detect.py'],
pathex=[],
binaries=[(r'D:\XXX\XX\utils\general.pyc', r'.\utils' ) #进行拷贝,注意拷贝的目的文件夹需要与上面缺少的路径一致。
],
datas=[(r'D:\XXX\data\coco128.yaml', r'.\data' )], #进行拷贝,注意拷贝的目的文件夹需要与上面缺少的路径一致。
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
运行exe时,可以运行,但是有报警:
WARNING: file already exists but should not: C:\Users\workAI\AppData\Local\Temp_MEI132522\torch_C.cp37-win_amd64.pyd。
这个在命令行运行时,提示倒没什么。因为我做了一个界面程序,每次启动时,有弹窗提示,如下图所示,让人很不爽。
不知道是不是pytorch本身的问题。这是说,在文本文件中多了一个文件,本来不应该有的,但是有了。
解决方法:在spec文件中,加一个搜索,从二进制引用的文件中,去掉这个。如下:
a = Analysis(['D:\XXX\detect.py'],
pathex=[],
binaries=[(r'D:XXX\utils\general.pyc', r'.\utils' )
],
datas=[(r'D:\XXX\data\coco128.yaml', r'.\data' )],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
for d in a.datas: #这样遍历一遍,删除本不应该包含的即可。spec文件其实就是可以执行的python代码
if '_C.cp37-win_amd64.pyd' in d[0]:
a.datas.remove(d)
break
补充说明:spec文件其实就是可以执行的python代码!!!
点击打包的exe时,先出现命令行界面,且一直有,然后再有界面。此时有个这很让人感觉不爽。
在spec文件中,配置如下,即可不弹出命令行界面了:
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='XXX',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=".",
console=False, #此定义为False,则不弹出命令窗口了
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
打包exe程序,这个pytorch的框架中,把其相关的包都打包进去了,有3.9个G大小,启动exe,解压缩到界面弹出来,时间非常长,又没有了命令行提示,用户都不知道情况。
为此,pyinstaller有闪屏功能,就是先加载一个提示窗口,可以显示进度。
ps:这个界面也是用tinker库实现的。
方法,在spec文件中增加splash对象,进行定义即可:
a = Analysis(['D:\CNG_Work\LostDistrictIdentify\\detect.py'],
pathex=[],
binaries=[(r'D:\CNG_Work\LostDistrictIdentify\utils\general.pyc', r'.\utils' )
],
datas=[(r'D:\CNG_Work\LostDistrictIdentify\data\coco128.yaml', r'.\data' )],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
for d in a.datas:
if '_C.cp37-win_amd64.pyd' in d[0]:
a.datas.remove(d)
break
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
splash = Splash(r'D:XXXX\Assets\CompanyLogo.gif', #只支持PNG格式。其他格式的话,如果装了PIL则会自动转换
#如果设置了最大尺寸max_img_size,且装了PIL,则尺寸大时,则自动进行转换缩放
binaries=a.binaries, #这里的a就是前面定义的,这里指向了他的二进制文件,
datas=a.datas
text_pos= (1240,405) #文本提示,提示上面的加载的二进制文件名称 #None不显示,或者显示的位置(10, 50),
text_default = 'Initializing' #默认提示
text_size=12, #字体大小
text_color='black'
exe = EXE(pyz,
a.scripts,
splash, # <-- both, splash target,引用splash对象
splash.binaries, # <-- and splash binaries,显示加载的文件内容
a.binaries,
a.zipfiles,
a.datas,
[],
name='XXX',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=".",
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
更多关于splash介绍,可参见pyinstaller官方介绍。https://pyinstaller.org/en/stable/usage.html?highlight=Splash#splash-screen-experimental
里面有多个章节,可以搜索下,都看看。