Shawnyg
Shawnyg

Reputation: 13

OpenCV is failing to read ONNX file after Py made into EXE via Pyinstaller

I've read around and still do not know why this occurs. The below error occurs after attempting to use OpenCV for my application which detects a face in an image/live camera feed. I use pyinstaller's --onefile to put it into a single executable. Everything runs fine when it isn't an exe and I'm using python to run it.

Printing running directory parent
C:\Users\Shawn\AppData\Local\Temp\_MEI320842\mtcnn_cv2
[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "new_kiv.py", line 91, in <module>
   File "kivy\app.py", line 950, in run
   File "kivy\base.py", line 582, in runTouchApp
   File "kivy\base.py", line 347, in mainloop
   File "kivy\base.py", line 391, in idle
   File "kivy\base.py", line 342, in dispatch_input
   File "kivy\base.py", line 308, in post_dispatch_input
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "kivy\uix\behaviors\button.py", line 179, in on_touch_up
   File "kivy\_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
   File "kivy\_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx", line 1132, in kivy._event.EventObservers._dispatch
   File "kivy\lang\builder.py", line 57, in custom_callback
   File "C:\Users\Shawn\AppData\Local\Temp\_MEI320842\new_kiv.kv", line 234, in <module>
     on_release: app.runInstant([InstantID.selectedAlgorithm, InstantID.selectedImage, InstantID.outputFolder])
   File "new_kiv.py", line 27, in runInstant
   File "modes\instant.py", line 40, in runInstant
   File "algorithms\mtcnn.py", line 18, in getResult
   File "mtcnn_cv2\mtcnn_opencv.py", line 56, in __init__
 cv2.error: OpenCV(4.5.4) D:\a\opencv-python\opencv-python\opencv\modules\dnn\src\onnx\onnx_importer.cpp:198: error: (-5:Bad argument) Can't read ONNX file: C:\Users\Shawn\AppData\Local\Temp\_MEI320842\mtcnn_cv2\pnet.onnx in function 'cv::dnn::dnn4_v20211004::ONNXImporter::ONNXImporter'

[16232] Failed to execute script 'new_kiv' due to unhandled exception!

Code snippet

        pnet_path = os.path.join(os.path.dirname(__file__), "pnet.onnx")
        rnet_path = os.path.join(os.path.dirname(__file__), "rnet.onnx")
        onet_path = os.path.join(os.path.dirname(__file__), "onet.onnx")
        print("Printing running directory parent")
        print(os.path.dirname(__file__))
        self._pnet = cv2.dnn.readNetFromONNX(pnet_path) ## Errors HERE
        self._rnet = cv2.dnn.readNetFromONNX(rnet_path)
        self._onet = cv2.dnn.readNetFromONNX(onet_path)

My spec:

# -*- mode: python ; coding: utf-8 -*-

from kivy_deps import sdl2, glew
from kivymd import hooks_path as kivymd_hooks_path

block_cipher = None


a = Analysis(['new_kiv.py'],
             pathex=['C:\\Users\\Shawn\\Documents\\GitHub\\FaceDetection\\virt\\Lib\\site-packages'],
             binaries=[("C:\\Users\\Shawn\\Documents\\GitHub\\FaceDetection\\virt\\Lib\\site-packages\\cv2\\opencv_videoio_ffmpeg454_64.dll", ".")],
             datas=[('libjpeg-9.dll', '.'),('libpng16-16.dll', '.'),('new_kiv.kv', '.'),('*.kv','.'),('opencv_videoio_ffmpeg454_64.dll', '.')],
             hiddenimports=['win32timezone','plyer.platforms','plyer.platforms.win.notification', 'plyer.platforms.win.filechooser', 'onnx.onnx_cpp2py_export', 'onnx'],
             hookspath=[kivymd_hooks_path],
             hooksconfig={},
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)

exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,  
          [],
          name='new_kiv',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=True,
          disable_windowed_traceback=False,
          target_arch=None,
          codesign_identity=None,
          entitlements_file=None )

Upvotes: 0

Views: 1999

Answers (1)

Shawnyg
Shawnyg

Reputation: 13

Actually a friend of mine found a solution to this. For us, we had to bring "haarcascade_frontalface_default.xml" into the main directory (copy/paste it), include it in the datas array in our .spec, and edit the haar_cascade file to replace det with det = cv2.CascadeClassifier(sys._MEIPASS + '\\haarcascade_frontalface_default.xml') if the _MEIPASS attribute exists.

This is probably something maybe only 1 other person will stumble on, but figured to help that one person whose use-case is this specific. We were extracting face data from this.

Upvotes: 1

Related Questions