PyInstaller打包exe时shape_predictor_68模型未被face_recognition包含的问题
解决PyInstaller打包face_recognition脚本时缺失形状预测模型的问题
问题原因
PyInstaller默认不会自动打包face_recognition依赖的shape_predictor_68_face_landmarks.dat模型文件,导致exe运行时无法在临时目录找到该文件。
解决方案
方法1:打包时通过命令行参数添加模型文件
先定位模型文件的实际路径:
在你的Python脚本中添加以下代码并运行,输出模型的绝对路径:import face_recognition_models print(face_recognition_models.pose_predictor_model_location())示例输出可能为:
C:\Python39\Lib\site-packages\face_recognition_models\models\shape_predictor_68_face_landmarks.dat用PyInstaller打包时,通过
--add-data参数将模型文件包含进去:pyinstaller --onefile --add-data "模型绝对路径;face_recognition_models/models/" 你的脚本名.py(Windows系统用分号分隔路径,Linux/macOS用冒号)
方法2:通过.spec文件配置打包
生成初始的.spec文件:
pyinstaller --onefile 你的脚本名.py打开生成的
你的脚本名.spec文件,修改datas字段,添加模型文件的映射:datas = [ ('模型绝对路径', 'face_recognition_models/models/') ]基于修改后的.spec文件重新打包:
pyinstaller 你的脚本名.spec
方法3:修改代码手动指定模型路径
将
shape_predictor_68_face_landmarks.dat复制到你的脚本所在目录(可从face_recognition_models的安装目录中找到)。修改脚本代码,替换默认的
face_encodings函数,手动指定本地模型路径:import cv2 import glob import requests import face_recognition as fr from face_recognition.api import _raw_face_landmarks import numpy as np import os import csv from csv import writer import pickle # 指定本地模型文件路径 predictor_path = os.path.join(os.path.dirname(__file__), 'shape_predictor_68_face_landmarks.dat') # 自定义face_encodings函数,使用本地模型 def custom_face_encodings(face_image, num_jitters=1): landmarks = _raw_face_landmarks(face_image, predictor_path=predictor_path) return fr.face_encodings(face_image, landmarks, num_jitters=num_jitters) # 原有代码部分 downloaded_images_folder = 'Images' resized_images_folder = 'Images_r' os.chdir(r"F:\This Semester\Python\Projects\Face Recognition") binary_images = [] name_of_people = [] knownEncodedList = [] try: os.mkdir(os.path.join(os.getcwd(), resized_images_folder)) except: pass p=1 for img in glob.glob(downloaded_images_folder + "/*.jpeg"): try : image = cv2.imread(img) imgResized = cv2.resize(image, (300, 400)) cv2.imwrite(os.path.join(resized_images_folder, img.split(os.sep)[-1]), imgResized) print("No. of image resized : " + str(p)) p = p+1 except: pass try: list_of_names_in_resized_image_folder = os.listdir(resized_images_folder) except: pass q = 1 for jpg in list_of_names_in_resized_image_folder : x = [] x.append(cv2.imread(f'{resized_images_folder}/{jpg}')) for img in x: try : # 使用自定义的编码函数替代原函数 encode = np.array(custom_face_encodings(img)[0]) knownEncodedList.append(encode) name_of_people.append(os.path.splitext(jpg)[0]) print("No. of image encoded : " + str(q)) q = q+1 except : pass pickle.dump(knownEncodedList , open("Face data" , "wb")) pickle.dump(name_of_people , open("Name data" , "wb")) print("done Pickling")打包时将本地模型文件一起包含:
pyinstaller --onefile --add-data "shape_predictor_68_face_landmarks.dat;." 你的脚本名.py
注意事项
- 确保模型路径的正确性,不同Python环境下
site-packages的位置可能不同,务必通过代码打印确认。 - 使用
--onefile打包时,PyInstaller会将所有文件解压到系统临时目录,因此路径映射要匹配临时目录内的结构。 - 打包完成后,测试exe文件时,若使用方法3,需确保模型文件与exe在同一目录(或代码中指定的路径正确)。
内容的提问来源于stack exchange,提问作者Zahin Fyz
相关产品推荐
相关产品推荐

