一、引言:

         上一文我们通过python-opencv来获取视频流,并使用自带的人脸识别模型来检测人脸将人脸数据框选并保存下来,那么本文,我将介绍一下如何使用这些图片来进行模型的训练。

二、训练代码:

        废话不多说,我们先把整个代码整理给大家:

import cv2
import os
import numpy as np
import pickle

def train_face_recognition_model():
    # 1. 准备数据集
    dataset_path = "dataset"

    # 自动获取dataset文件夹下的人名
    names = {}
    label = 0
    for name in os.listdir(dataset_path):
        folder_path = os.path.join(dataset_path, name)
        if os.path.isdir(folder_path):  # 确保是文件夹
            names[label] = name
            label += 1

    if not names:
        print("错误:在dataset文件夹中没有找到任何人脸数据!")
        return

    # 准备储存数据的容器
    faces = []  # 储存人脸照片
    labels = []  # 储存对应的标签

    # 2. 读取照片并准备训练数据
    for label, name in names.items():
        folder = os.path.join(dataset_path, name)
        for filename in os.listdir(folder):
            img_path = os.path.join(folder, filename)

            # 读取图片并转为灰度图
            img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)

            if img is not None:
                # 可以在这里添加人脸检测,确保只有人脸区域被用于训练
                faces.append(img)
                labels.append(label)
            else:
                print(f"警告:无法读取图片 {img_path}")

    if len(faces) == 0:
        print("错误:没有找到有效的人脸图片!")
        return

    # 3. 训练模型
    # 创建LBPH人脸识别器
    model = cv2.face.LBPHFaceRecognizer_create()

    # 开始训练
    model.train(faces, np.array(labels))

    # 4. 保存模型
    # 保存模型参数
    model.save("model.yml")

    # 保存标签和人名的对应关系
    with open("names.pkl", "wb") as f:
        pickle.dump(names, f)

    print(f"训练完成!共学习了 {len(faces)} 张照片,{len(names)} 个人。")
    print("已保存模型到 model.yml 和 names.pkl")

# 执行训练
if __name__ == "__main__":
    train_face_recognition_model()

        接下来我会介绍每一段代码的作用: 

1. 导入必要的库

import cv2          # OpenCV库,用于计算机视觉任务
import os           # 用于文件和目录操作
import numpy as np  # 用于数值计算
import pickle       # 用于序列化和保存Python对象

2. 自动获取人名 

dataset_path = "dataset"
names = {}
label = 0
for name in os.listdir(dataset_path):
    folder_path = os.path.join(dataset_path, name)
    if os.path.isdir(folder_path):  # 确保是文件夹
        names[label] = name
        label += 1

        这段代码自动扫描dataset文件夹下的子文件夹,每个子文件夹名被视为一个人名,为每个人分配一个数字标签(0,1,2,...)

3. 准备训练数据

faces = []  # 存储人脸图像
labels = [] # 存储对应的标签

for label, name in names.items():
    folder = os.path.join(dataset_path, name)
    for filename in os.listdir(folder):
        img_path = os.path.join(folder, filename)
        img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
        if img is not None:
            faces.append(img)
            labels.append(label)

        遍历每个人名对应的文件夹,读取文件夹中的所有图片,将图片转换为灰度图(人脸识别通常在灰度图上进行),将有效的图片和对应标签添加到训练集中

 4. 创建和训练模型

model = cv2.face.LBPHFaceRecognizer_create()
model.train(faces, np.array(labels))

        创建LBPH(Local Binary Patterns Histograms)人脸识别器,LBPH是一种基于局部特征的人脸识别算法,对光照变化有一定鲁棒性,使用收集的人脸数据和标签训练模型

5. 保存模型

model.save("model.yml")  # 保存模型参数
with open("names.pkl", "wb") as f:
    pickle.dump(names, f)  # 保存标签和人名的对应关系

        将训练好的模型参数保存到model.yml文件,将标签和人名的映射关系保存到names.pkl文件

6. 使用说明(图片收集的准备工作)

  1. 创建dataset文件夹

  2. dataset下为每个人创建一个子文件夹,文件夹名为人名

  3. 在每个子文件夹中放入该人的多张人脸照片

  4. 运行此脚本进行训练

文件夹结构示例

project/
│── dataset/
│   ├── name1/
│   │   ├── 1.jpg
│   │   ├── 2.jpg
│   │   └── ...
│   ├── neme2/
│   │   ├── 1.jpg
│   │   └── ...
│   └── name3/
│       ├── 1.jpg
│       └── ...
└── train.py (此脚本)

注意事项

  1. 每个人至少需要5-10张不同角度和光照条件的照片以获得较好效果

  2. 图片应主要包含人脸,背景尽量简单

  3. 图片大小不需要完全一致,但建议保持相似的尺寸

  4. 训练完成后会生成model.ymlnames.pkl两个文件,用于后续的人脸识别

三、运行结果

        在我们运行了前一篇文章的程序并收集完人脸图像数据后,我们运行本文的程序:

四、结语

        训练结束,我们得到了两个文件:

  1. model.yml —— 训练好的人脸识别模型(存储了学习到的特征)

  2. names.pkl —— 人名对照表(记录每个编号对应谁,比如 0: "ldh(刘德华)"

         现在,你的电脑已经能"记住"这些人脸了!

        下一章我们将对模型进行调用,用摄像头:检测人脸(用Haar级联),model.yml识别是谁,显示名字(从names.pkl查表)

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐