I have issues compiling a project with mediapipe via pyinstaller on macos
so far I tried:
pyinstaller --windowed --noconsole pose_edge.py pyinstaller --onefile --windowed --noconsole pose_edge.py pyinstaller --noconsole pose_edge.py
The .app does not open, and if I try the unix exec, I get
Traceback (most recent call last): File "pose_edge.py", line 26, in <module> File "mediapipe/python/solutions/selfie_segmentation.py", line 54, in __init__ File "mediapipe/python/solution_base.py", line 229, in __init__ FileNotFoundError: The path does not exist. [36342] Failed to execute script pose_edge
I work with conda, my env is in python 3.8, mediapipe 0.8.5 and OSX 10.15.7
Thanks in advance
Advertisement
Answer
I ran into this issue too and just figured it out a few minutes ago — so far, I’m getting around it the manual way, but I’m sure there’s an idiomatic way to do it in pyinstaller using the spec file and the data imports. For this answer, I’m assuming you’re not using the --onefile
option for pyinstaller, but rather creating the binary in a single folder.
That said, the answer is to cp -r
the modules directory from your mediapipe installed in the virtual environment (or wherever you installed the initial mediapipe package, e.g. /virtualenvs/pose_record-2bkqEH7-/lib/python3.9/site-packages/mediapipe/modules) into your dist/main/mediapipe
directory. This will enable your bundled mediapipe library to access the binarypb files which I believe contain the graphs and weights for the pose detection algorithm.
UPDATE: I have figured out a more idiomatic pyinstaller way of getting it to run. In the .spec
file generated by pyinstaller, you’re able to automatically add files in the following way:
At the top of the file, under the block_cipher = None
, add the following function:
def get_mediapipe_path(): import mediapipe mediapipe_path = mediapipe.__path__[0] return mediapipe_path
Then, after the following lines:
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
add the following lines which utilize the native Tree class to create a TOC for the binary:
mediapipe_tree = Tree(get_mediapipe_path(), prefix='mediapipe', excludes=["*.pyc"]) a.datas += mediapipe_tree a.binaries = filter(lambda x: 'mediapipe' not in x[0], a.binaries)
Once added, you can run the compile command from the CLI, e.g.:
pipenv run pyinstaller --debug=all main.spec --windowed --onefile
This allowed me to build an executable that functioned for mediapipe.