You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法使用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()

关键修改说明

  1. 统一人脸尺寸:添加了TARGET_FACE_SIZE参数,将所有检测到的人脸区域裁剪后统一缩放到指定尺寸,彻底解决尺寸不兼容的问题。
  2. 修正ID数据类型:将ID转为整数类型的numpy数组,完全匹配recognizer.train()的参数要求。
  3. 优化目录操作:使用os.path.join()拼接路径,彻底避免os.chdir()带来的路径混乱,代码稳定性大幅提升。
  4. 增加错误处理:添加图像读取异常捕获,跳过损坏的图像;同时检查有效样本数量,避免空训练集导致的崩溃。
  5. 灵活的ID获取方式:提供两种ID生成逻辑,你可以根据自己的样本命名规则自由切换。

内容的提问来源于stack exchange,提问作者Bikash Pandey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 23:53:12