先去opencv官网下载人脸识别的训练集 https://opencv.org/releases/ 解压目录要记录
主要使用 haarcascade_frontalface_default.xml
摄像头录入人脸(可选)可以弄一个文件夹,里面放一堆图片
import cv2
face_name = 'xxxx' # 该人脸的名字
# 加载OpenCV人脸检测分类器
face_cascade = cv2.CascadeClassifier("D:/BaiduNetdiskDownload/python/opencv/opencv-4.5.1/"
"data/haarcascades/haarcascade_frontalface_default.xml")
recognizer = cv2.face.LBPHFaceRecognizer_create() # 准备好识别方法LBPH方法
camera = cv2.VideoCapture(0) # 0:开启摄像头
success, img = camera.read() # 从摄像头读取照片
W_size = 0.1 * camera.get(3) # 在视频流的帧的宽度
H_size = 0.1 * camera.get(4) # 在视频流的帧的高度
def get_face():
print("正在从摄像头录入新人脸信息 \n")
picture_num = 0 # 设置录入照片的初始值
while True: # 从摄像头读取图片
global success # 设置全局变量
global img # 设置全局变量
ret, frame = camera.read() # 获得摄像头读取到的数据(ret为返回值,frame为视频中的每一帧)
if ret is True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 转为灰度图片
else:
break
face_detector = face_cascade # 记录摄像头记录的每一帧的数据,让Classifier判断人脸
faces = face_detector.detectMultiScale(gray, 1.3, 5) # gray是要灰度图像,1.3为每次图像尺寸减小的比例,5为minNeighbors
for (x, y, w, h) in faces: # 制造一个矩形框选人脸(xy为左上角的坐标,w为宽,h为高)
cv2.rectangle(frame, (x, y), (x + w, y + w), (255, 0, 0))
picture_num += 1 # 照片数加一
t = face_name
cv2.imwrite("./data/1." + str(t) + '.' + str(picture_num) + '.jpg', gray[y:y + h, x:x + w])
# 保存图像,将脸部的特征转化为二维数组,保存在data文件夹内
maximums_picture = 13 # 设置摄像头拍摄照片的数量的上限
if picture_num > maximums_picture:
break
cv2.waitKey(1)
get_face()
用于训练的图片文件夹格式
用人脸开始训练
import os
import cv2
from PIL import Image
import numpy as np
def getImageAndLabel(path):
# 人脸数据路径
faceSamples = []
# id
ids = []
# 获取当前路径的文件夹
dirs = os.listdir(path)
# 加载分类器 ,这个是刚才官网下载解压后的目录
faceCascade = cv2.CascadeClassifier('./data/haarcascades/haarcascade_frontalface_default.xml')
# 遍历文件夹
for dir in dirs:
# 获取文件夹路径
dir_path = os.path.join(path, dir)
# 获取文件夹下的图片
imagePaths = [os.path.join(dir_path, f) for f in os.listdir(dir_path)]
# 获取id
id = int(dir.split('.')[0])
# 遍历图片
for imagePath in imagePaths:
# 转换为灰度图
PIL_img = Image.open(imagePath).convert('L')
# 转换为数组
img_numpy = np.array(PIL_img, 'uint8')
# 人脸检测
faces = faceCascade.detectMultiScale(img_numpy)
# 遍历人脸
for (x, y, w, h) in faces:
# 添加人脸数据
faceSamples.append(img_numpy[y:y + h, x:x + w])
# 添加id
ids.append(id)
# 返回人脸数据和id
return faceSamples, ids
if __name__ == '__main__':
# 获取人脸数据和姓名
faces, ids = getImageAndLabel('./data/faces')
# 导入人脸识别模型
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 训练模型
recognizer.train(faces, np.array(ids))
# 保存模型
recognizer.save('./data/face_trainer.yml')
人脸识别
可以通过图片,视频,摄像头来进行人脸检测,识别成功后会返回id,根据id索引来对应人物名称
# -*- coding: utf-8 -*-
import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Image
import ffmpeg
import threading
import time
import subprocess
# 加载分类器
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 读取训练数据
recognizer.read('./data/face_trainer.yml')
# 名称
names = ['未知', 'xxxx', '成龙', '胡歌', '刘亦菲']
# 警报全局变量
warningtime = 0
# 设置字体相关参数
font_path = './data/font/simfang.ttf'
def cv2ImgAddText(img, text, left, top, textColor=(0, 0, 255), textSize=20):
"""
文字转换为图片并添加到图片上
"""
if (isinstance(img, np.ndarray)): # 判断是否OpenCV图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 创建一个可以在给定图像上绘图的对象
draw = ImageDraw.Draw(img)
# 字体的格式
fontStyle = ImageFont.truetype(
font_path, textSize, encoding="utf-8")
# 绘制文本
draw.text((left, top), text, textColor, font=fontStyle)
# 转换回OpenCV格式
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
# 人脸检测
def detect_face(src_img):
# 导入人脸检测模型
face_cascade = cv2.CascadeClassifier('./data/haarcascades/haarcascade_frontalface_alt2.xml')
# 灰度转换
gray = cv2.cvtColor(src_img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray) # 灰度图像,缩放因子,最小邻域,最大邻域,最小尺寸,最大尺寸
# 绘制人脸矩形
for (x, y, w, h) in faces:
cv2.rectangle(src_img, (x, y), (x + w, y + h), (0, 0, 255), 2) # 图片,左上角坐标,右下角坐标,颜色,线宽
# 人脸识别
id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
print(id)
# 判断是否为本人
if confidence < 70:
name = names[id]
confidence = "{0}%".format(round(100 - confidence))
else:
name = "unknown"
confidence = "{0}%".format(round(100 - confidence))
# 绘制姓名
src_img = cv2ImgAddText(src_img, name, x + 5, y + 5, (255, 0, 0), 50)
print(name)
# 绘制置信度
src_img = cv2ImgAddText(src_img, confidence, x + 5, y + h - 30, (255, 0, 0), 50)
# 判断是否为本人
if name == "unknown":
# 警报
global warningtime
warningtime += 1
# 警报超过3次
if warningtime > 3:
# 发送邮件
# sendEmail()
print("警报")
# 重置警报次数
warningtime = 0
return src_img
# 关闭
if __name__ == '__main__':
# 读取摄像头
cap = cv2.VideoCapture(0) # 0代表默认摄像头编号,如果有多个摄像头,可以尝试1,2,3等等
# cap = cv.VideoCapture("./images/video.mp4")#读取视频文件
# cap = cv2.VideoCapture('rtmp://') # 读取视频流
cap.set(cv2.CAP_PROP_FPS, 30) # 设置帧率
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 设置缓冲区大小为1
# 人脸检测
while True:
ret, frame = cap.read()
if ret:
img = detect_face(frame)
# 显示图片
cv2.imshow("img", img)
time.sleep(0.1)
# 等待键盘输入
if cv2.waitKey(1) == ord('q'):
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
# # 读取图片
# img = cv2.imread("./images/img_5.png")
# img = detect_face(img) # 开始识别
# img = cv2.resize(img, (800, 600)) # 修改图片大小
# cv2.imshow("face_detect", img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
标签:人脸识别,img,Python,cv2,face,opencv,人脸,import,id
From: https://www.cnblogs.com/qcy-blog/p/18154409