基于openCV实现简单的人脸识别
前言
人脸识别是一种基于人的脸部特征信息进行身份识别的一种生物识别技术。它利用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行分析和识别。人脸识别具有方便、快速、友好、无侵入等优点,已经广泛应用于安全防范、金融支付、社交娱乐、智能家居等领域。
本文将介绍如何使用python
和openCV
(接下来简称 cv2 )来实现人脸识别,包括如何采集人脸图像、如何使用摄像头进行人脸检测和识别等,并通过代码示例展示具体的实现过程。
环境配置
本次实验中,主要是在 Jupyter 用 Python 基于 openCV 实现人脸识别。
这里就不详细介绍如何安装配置了,可以通过以下链接访问具体过程:
- Jupyter Notebook 介绍、安装及使用教程
- Python安装与环境配置
- 使用pip或在anaconda安装 openCV
实验原理
此次实验过程内容比较简单,先通过cv2调用摄像头,从视频中分离每一帧画面,再调用cv2预训练的模型face_cascade
对画面进行人脸检测,检测到人脸后,在对应帧画面上绘制红色方框。
除此之外,还加上了眼部检测,由于人脸已经检测到了,只需要将检测到的眼部单独提取出来,在调用eye_cascade
进行眼部检测,同样在检测到的眼部周围绘制绿色方框。
完成检测和标记后,调用cv2进行显示,按键盘 Esc 退出。
程序设计
1. 采集人脸
按照流程图,我们将程序分为三个部分,首先是完成摄像头的采集,然后完成脸部和眼部的检测。在这里摄像头的采集可以调用 cv2 中的VideoCapture
,它既支持从视频文件读取,也支持直接从摄像机(如电脑自带摄像头)中读取。
# 调整参数实现读取视频或调用摄像头
cap = cv2.VideoCapture(0) # 笔记本电脑摄像头用 0 表示即可,视频建议使用绝对地址。
# 读取摄像头中的帧
ret, frame = cap.read()
2. 人脸识别
在这里可以单独写一个face_rec
人脸识别的函数,仅传入frame
即可,因为在后面我们会一直通过摄像头采集去检测窗口中的人脸,直至我们按下 ESC 键退出。
这是修改后的代码:
cap = cv2.VideoCapture(0)
while True:
# 读取摄像头中的帧
ret, frame = cap.read()
# 调用人脸识别函数
face_rec(frame)
c = cv2.waitKey(10)
# 当键盘按下‘ESC’退出程序
if c == 27: # ASCII 码值
break
那么接下来需要完成人脸识别face_rec
函数,这块我们得需要先了解什么是灰度图,它可以减少图像的原始数据量使我们后续的计算更少、更快,从而提高我们的运算速度。
# 转为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
为了方便学习,本文调用cv2预训练的模型face_cascade
对画面进行人脸检测。
# 创建人脸识别分类器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face_cascade.load('haarcascade_frontalface_default.xml')
# 创建人眼识别分类器
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
face_cascade.load('haarcascade_eye.xml')
# 检测人脸
faces = face_cascade.detectMultiScale(gray,
scaleFactor = 1.15,
minNeighbors = 3,
flags = cv2.IMREAD_GRAYSCALE,
minSize = (40,40))
想要了解代码中 haar 可以点击这里,而 Haar 特征分类器就是一个 XML 文件,该文件中会描述人体各个部位的 Haar 特征值。包括人脸、眼睛、嘴唇等等。
cv2中人脸检测使用的是detectMultiScale
函数; 它可以检测出图片中所有的人脸,并将人脸用 vector 保存各个人脸的坐标、大小(用矩形表示); 函数由分类器对象调用,其中的参数包括:
- image:表示的是要检测的输入图像
- objects:表示检测到的人脸目标序列
- scaleFactor:表示每次图像尺寸减小的比例
- minNeighbors:表示一个目标至少要被检测到多少次才算是真的目标
- minSize:为目标的最小尺寸
- maxSize:为目标的最大尺寸
3. 绘制方框
执行完上面代码后,现在只需要我们将检测到的人脸脸部和眼部单独提取出来绘制边框,仅调用cv2中的rectangle()
即可,它可以帮助我们绘制一个简单的、粗的或填充边界的矩形。
# 在人脸周围绘制方框
for (x,y,w,h) in faces:
img = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
# 进行眼部检测
eyes = eye_cascade.detectMultiScale(gray,
scaleFactor = 1.1,
minNeighbors = 3,
flags = cv2.IMREAD_GRAYSCALE,
minSize = (3,3))
for (ex,ey,ew,eh) in eyes:
# 绘制眼部方框
img = cv2.rectangle(frame,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.imshow('result',img)
4. 运行测试
在代码最后输入以下代码:
# 关闭摄像头
cap.release() # 停止捕获视频
cv2.destroyAllWindows() # 关闭相应的显示窗口
测试结果截图:
至此,本次的实验结束,同时感谢文中所提及知识点的作者!最后源代码放在我的GitHub。
可能会遇到的问题?
这是我在实际实验过程中出现到的问题,希望能帮到您。
1. 安装环境网速慢.....
可能你需要加速你的网络环境或者使用国内镜像。
2. 运行报错:error: (-215) !:in function cv
应该是路径出了问题,需要使用绝对路径。
参考文献
转载自:https://juejin.cn/post/7202914988011520037