opencv的包中自带有人脸分类器,可以方便实现对人脸、人眼和微笑的检测,值得注意的是人脸分类器对于正脸有较好的提取,对于侧脸就需要其他的了。
人脸 - haarcascade_frontalface_default.xml
人眼 - haarcascade_eye.xml
微笑 - haarcascade_smile.xml
一般的路径为:
AppData/Local/Programs/Python/Python37/Lib\site-packages/cv2\data/haarcascade_frontalface_alt.xml
如果没有的话,在此附上百度云盘链接,下载即可:
链接:链接:https://pan.baidu.com/s/1psup-wR53xvxl9GkzdhgOA
提取码:kc7s。
核心的步骤是:
# 按照1.1倍放大 周围最小像素为5
face_zone = face_detect.detectMultiScale(gray, scaleFactor = 1.1, minNeighbors = 5)
输入图像为灰度图
经过试验,倍数为1.1,周围最小像素为5,最为合适。
以下就是全部代码:
#coding:utf-8
from cv2 import cv2
# 调用熟悉的人脸分类器 识别特征类型
# 人脸 - haarcascade_frontalface_default.xml
# 人眼 - haarcascade_eye.xm
# 微笑 - haarcascade_smile.xml
face_detect = cv2.CascadeClassifier(r'c:/Users/liu\AppData/Local/Programs/Python/Python37/Lib\site-packages/cv2\data/haarcascade_frontalface_alt.xml')
# 读取图片
photo = cv2.imread('shili.jpg')
# cv2.imshow('photo', photo)
# 灰度处理
gray = cv2.cvtColor(photo, code=cv2.COLOR_BGR2GRAY)
# 检查人脸 按照1.1倍放到 周围最小像素为5
face_zone = face_detect.detectMultiScale(gray, scaleFactor = 1.1, minNeighbors = 5)
# 绘制矩形和圆形检测人脸
num = 0 # 统计人数
for x, y, w, h in face_zone:
num = num + 1
# 画矩形
cv2.rectangle(photo, pt1 = (x, y), pt2 = (x+w, y+h), color = [0,0,255], thickness=2)
# 画圆
cv2.circle(photo, center = (x + w//2, y + h//2), radius = w//2, color = [0,255,0], thickness = 2)
# 显示文字
cv2.putText(photo, str(num), (x,y), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 1)
# 总人数
cv2.putText(photo, "{}people".format(num), (10,50), cv2.FONT_HERSHEY_COMPLEX, 1, (142, 125, 52), 1)
cv2.imshow('result', photo)
cv2.waitKey(0)
# 释放资源
cv2.destroyAllWindows()
图片效果如下:
(为保护隐私,模糊化处理,直男马赛克)
在左上角显示总人数,但是显然有一个同学没有算进去,因为在图片上来看,当时她有些低头,分类器对正脸识别较好。
除此之外,还可以用作视频检测:
如果要启用摄像头的话,切换一下代码里的注释即可,
如下:
#识别电脑摄像头并打开
cap = cv2.VideoCapture(0)
#coding:utf-8
from cv2 import cv2
import os
import matplotlib.pyplot as plt
# # 识别电脑摄像头并打开
# cap = cv2.VideoCapture(0)
# # 加载视频
cap = cv2.VideoCapture('//path.mp4')
# 调用熟悉的人脸分类器 识别特征类型
# 人脸 - haarcascade_frontalface_default.xml
# 人眼 - haarcascade_eye.xm
# 微笑 - haarcascade_smile.xml
face_detect = cv2.CascadeClassifier(r'c:/Users/liu\AppData/Local/Programs/Python/Python37/Lib\site-packages/cv2\data/haarcascade_frontalface_alt.xml')
num_list = []
while True:
# 读取视频片段
flag, frame = cap.read()
if flag == False:
print("失败")
break
# 灰度处理
gray = cv2.cvtColor(frame, code=cv2.COLOR_BGR2GRAY)
# 检查人脸 按照1.1倍放到 周围最小像素为5
face_zone = face_detect.detectMultiScale(gray, scaleFactor = 1.2, minNeighbors = 5)
# 绘制矩形和圆形检测人脸
num = 0
for x, y, w, h in face_zone:
num = num + 1
cv2.rectangle(frame, pt1 = (x, y), pt2 = (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 = 2)
cv2.putText(frame, str(num), (x,y), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 1)
# 显示图片
cv2.putText(frame, "{}people".format(num), (10,50), cv2.FONT_HERSHEY_COMPLEX, 1, (142, 125, 52), 1)
cv2.imshow('video', frame)
num_list.append(num)
# 设置空格退出键和展示频率
if ord(' ') == cv2.waitKey(20):
break
cap.release()
plt.plot(num_list,'ro')
plt.show()
# 释放资源
cv2.destroyAllWindows()
最后结束后,还会plot出随着时间变化的人数变化。
视频效果如下:
ps:视频来源于网上,侵删
对于人物脸部前无遮挡、正脸的识别效果较好。
可用于一些其他的场景,比如:上课听课的抬头率等。