无法使用LBPHFaceRecognizer与OpenCV训练图像的技术求助
解决OpenCV人脸识别训练模块的错误问题
我仔细看了你的代码和遇到的问题,这里有几个关键问题导致训练失败,我会逐一说明并给出修复后的完整代码:
核心问题分析
- 人脸样本尺寸不统一:LBPHFaceRecognizer训练时要求所有输入的人脸图像尺寸必须一致,你的代码直接保留了检测到的不同大小的人脸区域,这是训练报错的主要原因。
- ID数据类型错误:你提取的ID是字符串格式,但
recognizer.train()需要整数类型的标签。 - 目录操作易出错:频繁使用
os.chdir()切换目录很容易引发路径混乱,不如直接用路径拼接更可靠。 - 未处理人脸检测失败的情况:部分图像可能检测不到人脸,这时候会产生无效数据,需要跳过这些情况。
修复后的完整代码
import os import cv2 import numpy as np from PIL import Image # 初始化识别器和人脸检测器 recognizer = cv2.face.LBPHFaceRecognizer_create() target_images_dir = "sampleImgFolder/" face_cascade = cv2.CascadeClassifier('resources/haarcascade_frontalface_default.xml') # 统一人脸样本尺寸,可根据需求调整,比如设置为200x200 TARGET_FACE_SIZE = (200, 200) def get_images_with_id(path): sample_faces = [] sample_face_ids = [] # 遍历主文件夹下的所有子文件夹(每个子文件夹对应一个样本) for person_id, dir_name in enumerate(os.listdir(path)): person_dir = os.path.join(path, dir_name) # 跳过非目录文件 if not os.path.isdir(person_dir): continue # 遍历子文件夹下的所有图像文件 for file_name in os.listdir(person_dir): img_path = os.path.join(person_dir, file_name) # 读取图像并转为灰度图 try: img_pil = Image.open(img_path).convert('L') img_np = np.array(img_pil, 'uint8') except Exception as e: print(f"读取图像失败 {img_path}: {e}") continue # 检测人脸,调整参数提升检测准确率 faces = face_cascade.detectMultiScale(img_np, scaleFactor=1.1, minNeighbors=5) # 处理检测到的人脸 for (x, y, w, h) in faces: # 裁剪人脸区域并统一尺寸 face_roi = img_np[y:y+h, x:x+w] resized_face = cv2.resize(face_roi, TARGET_FACE_SIZE) sample_faces.append(resized_face) # 两种ID获取方式可选: # 1. 用子文件夹索引作为ID(简单可靠) sample_face_ids.append(person_id) # 2. 按你原来的文件名规则提取ID(如果需要) # id = file_name.split('_')[0].split('-')[2] # sample_face_ids.append(int(id)) # 将ID转为numpy整数数组,符合训练要求 return np.array(sample_face_ids, dtype=np.int32), sample_faces print("开始读取样本图像...") ids, faces = get_images_with_id(target_images_dir) print(f"读取完成,共加载 {len(faces)} 个人脸样本") if len(faces) == 0: print("错误:未检测到任何人脸样本,请检查图像和检测器路径") else: print("开始训练模型...") recognizer.train(faces, ids) # 确保train目录存在,避免保存失败 os.makedirs('train', exist_ok=True) recognizer.write('train/trainningData.yml') print("训练完成,模型已保存到 train/trainningData.yml") cv2.destroyAllWindows()
关键修改说明
- 统一人脸尺寸:添加了
TARGET_FACE_SIZE参数,将所有检测到的人脸区域裁剪后统一缩放到指定尺寸,彻底解决尺寸不兼容的问题。 - 修正ID数据类型:将ID转为整数类型的numpy数组,完全匹配
recognizer.train()的参数要求。 - 优化目录操作:使用
os.path.join()拼接路径,彻底避免os.chdir()带来的路径混乱,代码稳定性大幅提升。 - 增加错误处理:添加图像读取异常捕获,跳过损坏的图像;同时检查有效样本数量,避免空训练集导致的崩溃。
- 灵活的ID获取方式:提供两种ID生成逻辑,你可以根据自己的样本命名规则自由切换。
内容的提问来源于stack exchange,提问作者Bikash Pandey
相关产品推荐
相关产品推荐

