Python实战:人脸识别

1. 流程

  • 人脸录入
    • 打开摄像头
    • 输入名字
    • 检测人脸
    • 保存图片
  • 训练数据
    • 读取全部图片
    • 训练数据
    • 保存数据
  • 人脸识别
    • 打开摄像头
    • 检测人脸
    • 识别人脸

2. 练习模块

1. 捕捉摄像头实时画面

import cv2 as cv

# 打开摄像头
cap = cv.VideoCapture(0)
if not cap.isOpened():
    print('摄像头连接失败')

while True:
    # 读取每一帧画面
    ret, frame = cap.read()
    if not ret:
        print('读帧失败')
        break

    # 展示当前画面
    cv.imshow('frame', frame)

    # 按'q'键退出
    if cv.waitKey(1) == ord('q'):
        break

# 释放捕获器和关闭窗口
cap.release()
cv.destroyAllWindows()

2. 人脸检测

import cv2 as cv

# 读取图像
img = cv.imread('jjy.jpg')

# 图像调整比例
img = cv.resize(img, None, fx=0.5, fy=0.5)

# 转为灰度图像,减少计算量
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 加载级联检测器,人脸特征分类器
face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')

# 提取人脸信息
faces = face_classifier.detectMultiScale(gray)

# 框出人脸
for x, y, w, h in faces:
    cv.rectangle(img, (x, y), (x + w, y + h), color=(0, 255, 0), thickness=2)

# 展示人脸
cv.imshow('face', img)

# 按'q'键退出
while True:
    if cv.waitKey(1) == ord('q'):
        break

# 关闭窗口
cv.destroyAllWindows()

3. 训练数据

import cv2 as cv
import numpy as np

images = ['jjy.jpg', 'lye.jpg']
faces_list = []
labels = []
label = 1

for f in images:
    # 读取图片并转成灰度图像
    img = cv.imread(f, 0)

    # 加载级联检测器,人脸特征分类器
    face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')

    # 提取人脸信息
    faces = face_classifier.detectMultiScale(img)

    x, y, w, h = faces[0]

    # 将提取出的人脸放入列表
    faces_list.append(img[y:y + h, x:x + w])

    # 将标签放入列表
    labels.append(label)
    label += 1

# 加载识别器
recognizer = cv.face.LBPHFaceRecognizer_create()

# 训练数据
recognizer.train(faces_list, np.array(labels))

recognizer.write('train.yml')

4. 人脸识别

import cv2 as cv

# 读取图片
img = cv.imread('jjy.jpg')

# 调整图像比例
img = cv.resize(img, None, fx=0.5, fy=0.5)

# 转成灰度图像
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 加载级联检测器,人脸特征分类器
face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')

# 提取人脸信息
faces = face_classifier.detectMultiScale(gray)

# 加载识别器
recognizer = cv.face.LBPHFaceRecognizer_create()

# 读取训练数据
recognizer.read('train.yml')

for x, y, w, h in faces:
    # 识别图中人脸,返回标签和置信度
    img_id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
    if confidence > 100:
        name = 'unknown'
    else:
        name = 'jjy' if img_id == 1 else 'lye'

    cv.putText(img=img, org=(x, y), text=name, fontFace=cv.FONT_HERSHEY_SIMPLEX, fontScale=0.75, color=(0, 255, 0),
               thickness=2)
    cv.circle(img=img, center=(x + w // 2, y + h // 2), radius=h // 2, color=(0, 0, 255), thickness=2)

# 展示人脸
cv.imshow('face', img)

# 按'q'键退出
while True:
    if cv.waitKey(1) == ord('q'):
        break

# 关闭窗口
cv.destroyAllWindows()

3. 完整代码

1. 人脸录入

import os

import cv2 as cv

IMG_SAVE_PATH = '../data/'


def main():
    # 打开摄像头
    cap = cv.VideoCapture(0)
    if not cap.isOpened():
        print('摄像头连接失败')

    # 输入姓名
    name = input('请输入需要录入的名字:')
    print("姓名输入完成,按's'键保存图片,按'q'键退出")

    # 循环读取每一帧画面
    while True:
        ret, frame = cap.read()
        if not ret:
            print('读帧失败')
            break

        # 提取的人脸信息和灰度图像
        faces, gray = img_extract_faces(frame)

        # 框出人脸
        for x, y, w, h in faces:
            cv.rectangle(img=frame, pt1=(x, y), pt2=(x + w, y + h), color=(255, 0, 0), thickness=2)

        # 展示人脸
        cv.imshow('face', frame)

        k = cv.waitKey(1)

        # 按 's' 键保存人脸
        if k == ord('s'):
            save_face(faces, frame, name)

        # 按 'q' 键退出
        elif k == ord('q'):
            break

    # 关闭摄像头和窗口
    cap.release()
    cv.destroyAllWindows()


# 返回提取的人脸信息和灰度图像
def img_extract_faces(img):
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')
    faces = face_classifier.detectMultiScale(gray)
    return faces, gray


# 保存提取到的人脸信息和姓名
def save_face(faces, img, name):
    if len(faces) == 0:
        print('没有检测到人脸,请调整')
        return
    if len(faces) > 1:
        print('检测到多个人脸,请调整')
        return
    x, y, w, h = faces[0]
    cv.imwrite(get_img_name(name), img[y:y + h, x:x + w])
    print('录入成功,按 q 键退出')


# 返回保存路径 + name_number + '.' + name + '.jpg'
def get_img_name(name):
    # 读取保存路径下所有的目录,格式:name_number + '.' + name + '.jpg'
    name_map = {f.split('.')[1]: int(f.split('.')[0]) for f in os.listdir(IMG_SAVE_PATH)}
    if not name_map:
        name_number = 1
    elif name in name_map:
        name_number = name_map[name]
    else:
        name_number = max(name_map.values()) + 1
    return IMG_SAVE_PATH + str(name_number) + '.' + name + '.jpg'


if __name__ == '__main__':
    main()

2. 训练数据

import cv2 as cv
import os
import numpy as np

IMG_SAVE_PATH = '../data/'

# 读取所有图片路径
image_paths = [os.path.join(IMG_SAVE_PATH, f) for f in os.listdir(IMG_SAVE_PATH)]

# 读取所有图片并转成灰度图像
faces_list = [cv.imread(image_path, 0) for image_path in image_paths]

# 读取所有标签
labels = [int(f.split('.')[0]) for f in os.listdir(IMG_SAVE_PATH)]

# 加载识别器
recognizer = cv.face.LBPHFaceRecognizer_create()

# 训练数据,放入人脸信息列表和标签数组
recognizer.train(faces_list, np.array(labels))

# 保存数据
recognizer.write('train.yml')

3. 人脸识别

import os

import cv2 as cv

IMG_SAVE_PATH = '../data/'

recognizer = cv.face.LBPHFaceRecognizer_create()
recognizer.read('train.yml')

cap = cv.VideoCapture(0)
if not cap.isOpened():
    print('摄像头连接失败')

name_map = {int(f.split('.')[0]): f.split('.')[1] for f in os.listdir(IMG_SAVE_PATH)}

while True:
    ret, frame = cap.read()
    if not ret:
        print('读帧失败')
        break

    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')
    faces = face_classifier.detectMultiScale(gray)

    for x, y, w, h in faces:
        img_id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
        if confidence > 85:
            name = 'unknown'
        else:
            name = name_map[img_id]
        cv.putText(frame, name, (x, y), fontFace=cv.FONT_HERSHEY_SIMPLEX, fontScale=0.75, color=(0, 255, 0),
                   thickness=2)
        cv.circle(frame, (x + w // 2, y + h // 2), w // 2, color=(255, 0, 0), thickness=2)

    cv.imshow('face', frame)
    if cv.waitKey(1) == ord('q'):
        break

cap.release()
cv.destroyAllWindows()

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值