记录实现:Python+opencv实现人脸识别训练模型+数据集本地生成(附源码)

一、本地数据集生成

用opencv操作本地摄像机,实现自定义数量照片截取并命名,通过按键方式实现不同角度拍摄,提高训练精度。具体解释都在代码里面,不一一赘述。

# coding=utf8
import cv2

# 收集人脸照片
cap = cv2.VideoCapture(0)  # 视频图像化
# 0表示打开笔记本内置摄像头 ==》可以换成视频路径“/目标地址”

num = 1

while cap.isOpened():  # 检测是否在开启状态
    tenser, V_show = cap.read()
    # cap.read 表示按帧读取视频
    # 用两个参数接收返回值  参数一:布尔值   参数二:每一帧图像,三维矩阵
    k = cv2.waitKey(1) & 0xFF
    # 键盘的十六进制表示  s=0xFF
    # cv2.waitKey() 方法本身表示等待键盘输入   参数为1则为延时1ms切换到下一帧图像   参数为0则只显示当前帧图像
    cv2.imshow('camera', V_show)  # 显示图像
    if k == ord('s'):  # 按s键保存
    # 文件命名
        name = 'D:/Python_Work_Space/python_csdn_face/face2/img_face/' + str(num) + '_liuyang' + '.jpg'
        cv2.imwrite(name, V_show)
        num = num + 1
        # time.sleep(0.5)
        # cv2.imwrite 保存图像(保存地址,图像(三维矩阵))
        print('保存成功' + name)
        num += 1
    elif k == ord(' '):  # 识别空格退出
        break

# 释放摄像头
cap.release()
cv2.destroyAllWindows()
# 关闭所有图像窗口

过程截图:


二、训练模型

import os
import cv2
from PIL import Image
import numpy as np


def face_train(path):
    # 储存人脸数据
    facesSamples = []
    ids = []
    # 储存图片信息
    imagePaths = [os.path.join(path, i) for i in os.listdir(path)]
    # 加载分类器
    face_detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
    # 遍历列表中的图片
    for imagePath in imagePaths:

        # 打开图片,PIL有九种不同的模式:1,L,P,RGB,RGBA,CMYK,YCbCr,I,F
        PIL_img = Image.open(imagePath).convert('L')
        # L表示灰度图像,每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同灰度
        # 转化公式  L = R * 299 / 1000 + G * 587 / 1000 + B * 114 / 1000。

        # 将图像转化为数组,以黑白深浅 image转array
        img_numpy = np.array(PIL_img)

        # 获取图片人脸特征
        faces = face_detector.detectMultiScale(img_numpy)
        # opencv中人脸检测使用的是 detectMultiScale 函数。
        # 它可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小(用矩形表示),

        # 拿到id和姓名
        id = int(os.path.split(imagePath)[1].split('_')[0])
        # 预防无面容照片
        for x, y, w, h in faces:
            ids.append(id)
            facesSamples.append(img_numpy[y:y + h, x:x + w])
    # 打印面部特征和id
    print("id",id)
    print('面部特征矩阵:', facesSamples)

    return facesSamples,ids


if __name__ == '__main__':
    # 图片路径
    path = 'img_face/'
    # 获取图像数组和id标签数组和姓名
    faces,ids = face_train(path)
    # 加载识别器
    recognizer = cv2.face.LBPHFaceRecognizer_create()
    # 训练
    recognizer.train(faces, np.array(ids))
    # 保存文件
    recognizer.write('liuyang.yml')

运行截图:

三、测试检测模型

import cv2

# 加载训练数据文件
recogizer = cv2.face.LBPHFaceRecognizer_create()
# 加载数据
recogizer.read("liuyang.yml")
# 名称
names = []
# 报警全局变量
warningtime = 0


# 准备识别的图片
def face_detect_demo(img):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度
    face_detector = cv2.CascadeClassifier('D:/Python_Work_Space/python_csdn_face/face2\haarcascade_frontalface_alt.xml')
    face = face_detector.detectMultiScale(gray)
    for x, y, w, h in face:
        cv2.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2)
        cv2.circle(img, center=(x + w // 2, y + h // 2), radius=w // 2, color=(0, 255, 0), thickness=1)
        # 人脸识别
        ids, confidence = recogizer.predict(gray[y:y + h, x:x + w])  # 对测试数据进行分类  返回值和返回结果
        if confidence > 80:
            global warningtime
            warningtime += 1
            if warningtime > 100:
                warningtime = 0

            # 图片 添加的文字 位置 字体 字体大小 字体颜色 字体粗细
            cv2.putText(img, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
        else:
            cv2.putText(img, "liu", (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
    cv2.imshow('result', img)

# 名字标签
def name():
        names.append("liu")


# 加载视频
cap = cv2.VideoCapture(0)
name()
while True:
    flag, frame = cap.read()
    if not flag:
        break
    face_detect_demo(frame)
    if ord(' ') == cv2.waitKey(10):
        break
# 释放内存+视频
cv2.destroyAllWindows()
cap.release()

运行截图

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年9月2日
下一篇 2023年9月2日

相关推荐