I am working on face recognition following this link and I would like to build a standalone application using Python. My main.py
script looks like the following.
# main.py
# Import packages and other scripts
import tkinter as tk
...
# Some functions
def initialization():
# OpenCV and sklearn are used here
...
def registration():
# OpenCV, and sklearn are used here
...
def face_recognition():
# OpenCV and sklearn are used here
...
# Start the Tkinter GUI
window = tk.Tk()
# Initialize the face recognition model
initialization()
# Input name for registration
tk.Label(window, text = "Name").grid(...)
entry1 = tk.Entry(window)
entry1.grid(row=0, column=1)
# When the button is clicked, different command is executed
tk.Button(window, text='Registration', command=registeration).grid(...)
tk.Button(window, text='Face Recognition', command=face_recognition).grid(...)
window.mainloop()
Using python interpret to run the script (python main.py
), everything works fine.
I use Pyinstaller to convert the scripts to a single exe with this command:
pyinstaller --onefile \
--windowed \
--hidden-import sklearn.neighbors.typedefs \
main.py
Then, I have two exe generated. The first one is in dist/main
and the second one is in dist/main.app/Contents/MacOS/main
When running the exe, the exe keeps duplicate itself. I display the running process and found this result
$ ps
PID TTY TIME CMD
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(8)
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(8)
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(7)
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(7)
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(8)
I have no idea what happens to the exe since I do not import multiprocessing packages in my scripts. Any idea how to fix this problem? Thanks
Update 1
I added a --log-level ERROR
when using Pyinstaller
and gives this result. Not sure if it is related to my problem.
Traceback (most recent call last):
File "<string>", line 2, in <module>
ModuleNotFoundError: No module named 'Crypto.Math'
174598 INFO: MKL libraries found when importing numpy. Adding MKL to binaries
176282 ERROR: Can not find path ./libtbb.dylib (needed by /Users/user/anaconda3/lib/libmkl_tbb_thread.dylib)
Update 2
I found out that one of the packages that I am using -- imultis
VideoStream involves threading
. I guess it is the reason for observing from multiprocessing.semaphore_tracker
as shown above even though I do not import multiprocessing
explicitly.
Then I come across with this post, suggesting to add multiprocessing.freeze_support()
. It can suppress the GUI window from keep duplicating, but the background processes as shown using $ ps
still keep duplicating. The problem has not fixed yet.
Update 3 (Issue located but not fix)
After debugging the code for quite a while, it turns out that the causes of this infinite looping is NOT due to the threading
of imultis
VideoStream (I write another script to test imultis
and it is completely OK). But the problem comes from importing sklearn
!!! This problem has been reported in GitHub in this link.
This GitHub link also suggest to include multiprocessing.freeze_support()
. Moreover one of the responses suggests to import sklearn
after multiprocessing.freeze_support()
is called. I try it with a simple script but the problem is still here.
Conclusion: sklearn
causes the executable keeps opening. But I have no idea why it is the case, and I do not know how to solve it. Any help would be appreciated. Thanks.
This answer does a good job explaining why this happens: https://stackoverflow.com/a/55382641/109525
First try setting this before starting your program:
export JOBLIB_MULTIPROCESSING=0
If it works, you can add a runtime hook to your program to set the environment variable automatically. See: https://pythonhosted.org/PyInstaller/when-things-go-wrong.html#changing-runtime-behavior
Starting my main entry point with:
from multiprocessing import freeze_support
freeze_support()
Worked for me!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With