使用PyInstaller打包Python手部追踪程序遇索引错误及路径问题
问题描述
使用OpenCV、MediaPipe和time模块开发的手部追踪程序在IDE中运行正常,但执行打包命令 pyinstaller -w -F HandTrackingProgram.py 时出现 IndexError: tuple index out of range 错误;后续打包成功后,运行生成的exe文件触发以下错误:
Traceback (most recent call last): File "nauru.py", line 7, in File "mediapipe\python\solutions\hands.py", line 114, in __init__ File "mediapipe\python\solution_base.py", line 264, in __init__ FileNotFoundError: The path does not exist.
此前因Python 3.11无法安装MediaPipe,已切换至Python 3.10完成库安装,但仍存在上述打包及运行问题。程序代码如下:
import cv2 import mediapipe as mp import time cap = cv2.VideoCapture(0) mpHands = mp.solutions.hands hands = mpHands.Hands() mpDraw = mp.solutions.drawing_utils pTime = 0 cTime = 0 while True: success, img = cap.read() imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) results = hands.process(imgRGB) if results.multi_hand_landmarks: for handLms in results.multi_hand_landmarks: for id, lm in enumerate(handLms.landmark): h, w, c = img.shape cx, cy = int(lm.x*w), int(lm.y*h) mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS) cTime = time.time() fps = 1/(cTime-pTime) pTime = cTime cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3) cv2.imshow("Image", img) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
解决方案
1. 修复打包时的IndexError: tuple index out of range
该错误源于PyInstaller与MediaPipe的资源路径适配问题,先升级PyInstaller到最新版本:
pip install --upgrade pyinstaller
2. 解决运行exe时的FileNotFoundError
MediaPipe运行依赖预训练模型文件,PyInstaller默认不会自动打包这些资源,需手动指定:
方法一:打包时添加资源路径
找到Python 3.10环境中MediaPipe的安装目录(通常为Lib\site-packages\mediapipe),修改打包命令,用--add-data参数指定资源:
pyinstaller -F --add-data "Lib\site-packages\mediapipe;mediapipe" HandTrackingProgram.py
注:Windows系统用分号分隔源路径和目标路径,Linux/macOS用冒号。先去掉
-w参数,通过控制台输出排查问题,确认正常后再添加-w。
方法二:代码中指定模型路径
修改代码,适配打包后的资源路径,并手动指定模型文件位置:
import cv2 import mediapipe as mp import time import os import sys # 获取资源路径,兼容IDE运行和打包后环境 def get_resource_path(relative_path): if hasattr(sys, '_MEIPASS'): return os.path.join(sys._MEIPASS, relative_path) return os.path.join(os.path.abspath("."), relative_path) cap = cv2.VideoCapture(0) mpHands = mp.solutions.hands # 手动指定模型路径 hands = mpHands.Hands( model_path=get_resource_path("mediapipe/modules/hand_landmark/hand_landmark.tflite") ) mpDraw = mp.solutions.drawing_utils pTime = 0 cTime = 0 while True: success, img = cap.read() imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) results = hands.process(imgRGB) if results.multi_hand_landmarks: for handLms in results.multi_hand_landmarks: for id, lm in enumerate(handLms.landmark): h, w, c = img.shape cx, cy = int(lm.x*w), int(lm.y*h) mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS) cTime = time.time() fps = 1/(cTime-pTime) pTime = cTime cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3) cv2.imshow("Image", img) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
然后执行打包命令,指定模型文件的打包路径:
pyinstaller -F --add-data "Lib\site-packages\mediapipe\modules\hand_landmark\hand_landmark.tflite;mediapipe/modules/hand_landmark/" HandTrackingProgram.py
3. 额外建议
- 安装兼容Python3.10的MediaPipe版本,推荐
0.9.0.1:
pip install mediapipe==0.9.0.1
- 测试阶段不要用
-w参数,控制台输出能帮你快速定位剩余问题。
内容的提问来源于stack exchange,提问作者for overflow
相关产品推荐
相关产品推荐

