人脸识别
介绍
人脸识别是一项热门的计算机技术研究领域,本篇博客介绍的人脸识别项目是基于opencv实现的人脸录入、打卡、导出并使用语音操作。
# 一、基于opencv实现人脸识别的简单使用
# 1、安装opencv的库
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python
2
# 2、下载opencv提供的分类器
官网https://opencv.org/releases/ (opens new window) 选择你要的版本Windows,学习的话,用最新的就行
觉得下载慢,就用这个下载,可以不全部下载,只下载人脸检测的分类器,深入学习时,再去下载需要的东西
百度网盘链接:https://pan.baidu.com/s/1uPZ0tG_6ZemfA4cU7_ztHQ?pwd=ze8j 提取码:ze8j
自带的分类器很多,想研究哪里,就用那个吧,目录opencv/data/haarcascades
- haarcascade_eye 睁开的眼睛的检测
- haarcascade_eye_tree_eyeglasses 戴眼镜时睁开的眼睛
- haarcascade_frontalcatface 正脸检测
- haarcascade_frontalcatface_extended 正脸检测
- haarcascade_frontalface_alt 正脸检测
- haarcascade_frontalface_alt_tree 正脸检测
- haarcascade_frontalface_alt2 正脸检测
- haarcascade_frontalface_default 正脸检测
- haarcascade_fullbody 全身检测
- haarcascade_lefteye_2splits 检测左眼开或闭合
- haarcascade_licence_plate_rus_16stages 俄罗斯车牌
- haarcascade_lowerbody 下肢检测
- haarcascade_profileface 人脸轮廓检测
- haarcascade_righteye_2splits 检测右眼开或闭合
- haarcascade_russian_plate_number 俄罗斯车牌号
- haarcascade_smile 微笑表情检测
- haarcascade_upperbody 上半身检测
# 简单的使用python-opencv
# 1、cv2打开摄像头或者本地视频
按键盘上的q退出,以确保不卡内存
import cv2
# 使用cv2播放本地的视频(这里本地视频叫做1.mp4)
cap = cv2.VideoCapture('1.mp4')
# 使用cv2调用本地摄像头
# cap = cv2.VideoCapture(0)
# 循环执行
while True:
# 获取图像数据
ret, frame = cap.read()
if not ret:
break
# 修改显示的尺寸(600x400)
frame = cv2.resize(frame, dsize=(600, 400))
# 在capture窗体中展示图像
cv2.imshow("capture",frame)
# cv2.waitKey(0), 表示程序会无限制的等待用户的按键事件;
# cv2.waitKey(1), 表示程序每1ms检测一次按键,检测到返回按键值,检测不到返回 - 1;
# cv2.waitKey(100), 表示程序每100ms检测一次按键,检测到返回按键值,检测不到返回 - 1;
if cv2.waitKey(100) & 0xFF == ord('q'):
# 将capture窗体中显示的图片保存到now.jpg,然后结束程序
cv2.imwrite("now.jpg", frame)
break
# 释放内存
cap.release()
cv2.destroyAllWindows()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
注释够细节吧,哈哈
# 2、检测人脸,画框框
这里用到了opencv 自带的人脸特征分类器 opencv4.6/haarcascade_frontalface_alt2.xml或opencv4.6/haarcascade_frontalface_default.xml
可以画正方形或者圆形框框,都在注释里了
import cv2
# 使用cv2播放本地的视频(这里本地视频叫做1.mp4)
# cap = cv2.VideoCapture('1.mp4')
# 使用cv2调用本地摄像头
cap = cv2.VideoCapture(0)
# 循环执行
while True:
# 获取图像数据
ret, frame = cap.read()
if not ret:
break
# 修改显示的尺寸(600x400)
frame = cv2.resize(frame, dsize=(600, 400))
# 人脸检测
gary = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# opencv提供的人脸特征分类器 下面俩是最快且最准的
face_detect = cv2.CascadeClassifier('opencv4.6/haarcascade_frontalface_alt2.xml')
# face_detect = cv2.CascadeClassifier('opencv4.6/haarcascade_frontalface_default.xml')
# gray:表示当前帧的图片
# 1.01:表示每次检测人脸扩大的倍数
# 5:表示连续检测5次都为人脸时候,才确定是人脸
# 0:一般都用默认值0,不用改
# (100,100):表示检测人脸最小的人脸,低于100 * 100的人脸检测不出
# (300,300):表示能检测到最大的人脸,高于300 * 300的人脸检测不出
face = face_detect.detectMultiScale(gary, 1.01, 5, 0, (100, 100), (300, 300))
# face人脸识别的位置
for x, y, w, h in face:
# 读取人脸识别的位置与响应的区域大小,并画正方形圈出来。
cv2.rectangle(frame, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2)
# 读取人脸识别的位置与响应的区域大小,并画圆出来。
# cv2.circle(frame, center=(x + w // 2, y + h // 2), radius=w // 2, color=(0, 255, 0), thickness=1)
# 在capture窗体中展示图像
cv2.imshow("capture", frame)
# cv2.waitKey(0), 表示程序会无限制的等待用户的按键事件;
# cv2.waitKey(1), 表示程序每1ms检测一次按键,检测到返回按键值,检测不到返回 - 1;
# cv2.waitKey(100), 表示程序每100ms检测一次按键,检测到返回按键值,检测不到返回 - 1;
if cv2.waitKey(10) & 0xFF == ord('q'):
break
# 释放内存
cap.release()
cv2.destroyAllWindows()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 3、画框框加保存图片
使用time库,产生时间戳,以确保文件名不会重复
import cv2, time
# 使用cv2播放本地的视频(这里本地视频叫做1.mp4)
# cap = cv2.VideoCapture('1.mp4')
# 使用cv2调用本地摄像头
cap = cv2.VideoCapture(0)
# 循环执行
while True:
# 获取图像数据
ret, frame = cap.read()
if not ret:
break
# 修改显示的尺寸(600x400)
frame = cv2.resize(frame, dsize=(600, 400))
# cv2.waitKey(0), 表示程序会无限制的等待用户的按键事件;
# cv2.waitKey(1), 表示程序每1ms检测一次按键,检测到返回按键值,检测不到返回 - 1;
# cv2.waitKey(100), 表示程序每100ms检测一次按键,检测到返回按键值,检测不到返回 - 1;
key = cv2.waitKey(1) & 0xFF
# 按s保持当前图像为图片
if key == ord('s'):
# 防止图片名字重复,使用时间戳为图片的名字
now_time = str(round(time.time() * 1000))
# 需要在当前目录新建一个img目录
cv2.imwrite("img/" + now_time + ".jpg", frame)
print("成功保存到图片:" + now_time + ".jpg")
# 按q退出
elif key == ord('q'):
break
# 人脸检测
gary = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# opencv提供的人脸特征分类器 下面俩是最快且最准的
face_detect = cv2.CascadeClassifier('opencv4.6/haarcascade_frontalface_alt2.xml')
# face_detect = cv2.CascadeClassifier('opencv4.6/haarcascade_frontalface_default.xml')
# gray:表示当前帧的图片
# 1.01:表示每次检测人脸扩大的倍数
# 5:表示连续检测5次都为人脸时候,才确定是人脸
# 0:一般都用默认值0,不用改
# (100,100):表示检测人脸最小的人脸,低于100 * 100的人脸检测不出
# (300,300):表示能检测到最大的人脸,高于300 * 300的人脸检测不出
face = face_detect.detectMultiScale(gary, 1.01, 5, 0, (100, 100), (300, 300))
# face人脸识别的位置
for x, y, w, h in face:
# 读取人脸识别的位置与响应的区域大小,并画正方形圈出来。
cv2.rectangle(frame, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2)
# 读取人脸识别的位置与响应的区域大小,并画圆出来。
# cv2.circle(frame, center=(x + w // 2, y + h // 2), radius=w // 2, color=(0, 255, 0), thickness=1)
# 在capture窗体中展示图像
cv2.imshow("capture", frame)
# 释放内存
cap.release()
cv2.destroyAllWindows()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 4、训练数据(生成人脸数据保存到文件中)
import os
import cv2
from PIL import Image
import numpy as np
def getImageAndLabels(path):
# 人脸数据信息
facesSamples=[]
# 人脸数据信息id(编号)
ids=[]
# 全部的图片路径
imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
# 使用opencv提供的分类器检测人脸
face_detector = cv2.CascadeClassifier('opencv4.6/haarcascade_frontalface_alt2.xml')
# 打印数组imagePaths
# print('数据排列:',imagePaths)
# 遍历列表中的图片
for imagePath in imagePaths:
# 打开图片,黑白化
PIL_img=Image.open(imagePath).convert('L')
# 将图像转换为数组,以黑白深浅
img_numpy = np.array(PIL_img,'uint8')
# 获取图片人脸特征
faces = face_detector.detectMultiScale(img_numpy)
# 获取当前照片的文件名
id = imagePath.split("/")[1].split(".")[0]
# face人脸识别的位置
for x,y,w,h in faces:
# id是文件名
ids.append(id)
# img_numpy[y:y+h,x:x+w]人脸识别数据
facesSamples.append(img_numpy[y:y+h,x:x+w])
return facesSamples, ids
if __name__ == '__main__':
# 获取全部保存的图片路径
path = 'img/'
# 获取图像数组和id标签数组和姓名
faces, ids = getImageAndLabels(path)
# 获取训练对象
recognizer = cv2.face.LBPHFaceRecognizer_create()
# 人脸数据写入
recognizer.train(faces, np.array(ids, dtype=np.int64))
# 保存文件到trainer.yml中
recognizer.write('trainer.yml')
print("训练数据完成!")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 5、人脸识别
import cv2
#加载训练数据集文件
recogizer=cv2.face.LBPHFaceRecognizer_create()
recogizer.read('trainer.yml')
warningtime = 0
# 准备识别的图片
def face_detect_demo(img):
# 当前帧图片转换为转换为灰度
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 使用opencv提供的分类器检测人脸
face_detector = cv2.CascadeClassifier('opencv4.6/haarcascade_frontalface_alt2.xml')
# 检测
face = face_detector.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(100,100),(300,300))
# 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])
# print('图片id:',ids,'置信评分:', confidence) # 置信评分越低,准确度越高
# if confidence > 60:
if confidence > 80:
cv2.putText(img, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
else:
cv2.putText(img,str(ids), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1)
cv2.imshow('result',img)
cap=cv2.VideoCapture(0)
# cap=cv2.VideoCapture('1.mp4')
while True:
flag,frame = cap.read()
if not flag:
break
# 人脸识别
face_detect_demo(frame)
if ord('q') == cv2.waitKey(10):
break
cv2.destroyAllWindows()
cap.release()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
简单的人脸识别分成3步可以实现了
- 1、人脸保存为图像
- 2、根据图像生成人脸数据
- 3、通过人脸数据进行人脸识别
完整功能的人脸识别+注释代码够几千行了,粘贴到这里不太合适,就放到了百度网盘,https://pan.baidu.com/s/1uPZ0tG_6ZemfA4cU7_ztHQ?pwd=ze8j ,博客文件夹中,ai.py就是,使用教程以及说明请看下面
# 二、功能全一点的人脸识别,可以联网,语音操作(该网盘文件夹中程序源码介绍ai.py)
上面的百度网盘中,有个已开发完成的zip文件,正是我做的大学作业,python已打包为exe可执行文件(仅Windows64位系统可以用),使用时,请给改程序摄像头和语音权限即可
百度网盘中有个博客文件夹,里面有全部你想要的代码
如果上面的基本使用没有看懂,你可以去b站看这个视频 https://www.bilibili.com/video/BV1Lq4y1Z7dm/ (opens new window)
科大讯飞官网 (opens new window),官网提供的文章很详细,网上也有很多教程,这边不做过多的介绍
# 1、部署本地环境
首先需要安装依赖,可以手动安装也可以一键全部安装
# 1.1、方式1(一个一个pip install)
numpy==1.23.2
opencv_python==4.6.0.66
opencv-contrib-python==4.6.0.66
oss2==2.16.0
Pillow==9.3.0
PyAudio==0.2.12
PyMySQL==1.0.2
requests==2.28.1
websocket_client==1.4.2
XlsxWriter==3.0.3
2
3
4
5
6
7
8
9
10
# 1.2、方式2
在cmd窗口中执行,可一键安装全部依赖
pip install -r requirements.txt
# 2、使用的核心技术
- 使用阿里云OSS用于存储照片
- 使用MySQL做照片与人员姓名对应,并存放打卡记录
- 使用科大讯飞做语音转换,使用的是websocket技术
- 人脸检测使用的opencv
- 使用第三方库xlsxwriter导出Excel
- 本地语音播报使用第三方库pyaudio,声音文件下载自科大讯飞
- 本项目多次使用多线程threading
# 3、使用教程
- 1.运行本地部署环境请跑main.py
- 2.运行可执行文件aiface.exe
本系统语音检测关键字有以下内容:
录入人脸(或者人脸录入,执行成功后保存人脸信息到库中)
训练数据(更新库中的人脸信息,本系统将人脸数据信息跑在内存中,为了节省内存未设置实时刷新)
刷新(和训练数据功能相同)
打卡(根据当前人脸信息进行打卡)
导出录入(导出所有的人脸录入信息)
导出打卡(导出所有的人脸打卡信息)
导出全部(导出全部信息,即录入信息和打卡信息再同一个Excel中) 语音检测以系统翻译为准,一句话只需要包含关键字切连续即可
# 3.1、录入人脸信息
在文本框中输入你的名字,然后对着麦克风说 录入人脸或人脸录入 ,录入成功后系统即可显示名字,然后就可以进行打卡操作了
# 3.2、打卡
当系统检测到你有名字存在时,你对着麦克风说 打卡 ,系统会打卡成功,每天可以多次打卡,当系统中的打卡数据存在时,系统会判断是新增打卡信息还是修改打卡信息,并更新当日打卡的次数。
# 3.3、导出
对着麦克风说导出全部,稍后会在本目录下导出一个Excel文件,文件名为全部数据.xlsx,如下图:
基本的大致上就这些,使用一段时间你会觉得语音系统总是断开,因为使用的webscoket,心跳检测还是没写好,写的不是太完美,当然,我也想过不用科大讯飞的在线语音转换,尝试后失败了,错误率太高了,如果以后在遇到吧,我会深入学习一下。 过两天趁着交作业需要录视频,正好也放到这里。