人脸检测有几种方法,主要讲2种,一种是基于Haar,另外一种基于深度学习,从效果上看肯定是后者效果较好,但是前者简单。
人脸识别讲4种方法,EigenFaces、FisherFaces和LBPH以及Dlib方法。
import cv2
img=cv2.imread('E:\VSCode\CSDN\my.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图像
#加载人脸检测器
face = cv2.CascadeClassifier('E:\VSCode\CSDN\haarcascade_frontalface_default.xml')
eye = cv2.CascadeClassifier('E:\VSCode\CSDN\haarcascade_eye.xml')#加载眼睛检测器
faces = face.detectMultiScale(gray)#执行人脸检测
for x,y,w,h in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)#绘制矩形标注人脸
roi_eye = gray[y:y+h, x:x+w] #根据人脸获得眼睛的检测范围
eyes = eye.detectMultiScale(roi_eye) #在人脸范围内检测眼睛
for (ex,ey,ew,eh) in eyes: #标注眼睛
cv2.circle(img[y:y+h, x:x+w],(int(ex+ew/2),
int(ey+eh/2)),int(max(ew,eh)/2),(0,255,0),1)
cv2.imshow('faces',img)
cv2.waitKey(0)
基于视频的代码:
import cv2
capture = cv2.VideoCapture(0) #创建视频捕捉器对象
face = cv2.CascadeClassifier('E:\VSCode\CSDN\haarcascade_frontalface_default.xml')#加载人脸检测器
eye = cv2.CascadeClassifier('E:\VSCode\CSDN\haarcascade_eye.xml')#加载眼睛检测器
while True:
ret, frame = capture.read()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) #转换为灰度图像
faces = face.detectMultiScale(gray) #执行人脸检测
for x,y,w,h in faces:
cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) #绘制矩形标注人脸
roi_eye = gray[y:y+h, x:x+w] #根据人脸获得眼睛的检测范围
eyes = eye.detectMultiScale(roi_eye) #在人脸范围内检测眼睛
for (ex,ey,ew,eh) in eyes: #标注眼睛
cv2.circle(frame[y:y+h, x:x+w],(int(ex+ew/2),
int(ey+eh/2)),int(max(ew,eh)/2),(0,255,0),2)
cv2.imshow('faces',frame)
key = cv2.waitKey(20)
if key == 27:
break
opencv的深度神经网络(DNN)模块提供了基于深度学习的人脸检测器。DNN使用的深度学习框架包括Caffe、TensorFlow、Torch等。OpenCV提供了2个预训练的人脸检测模型,Caffee和Tensorflow模型。
以下为代码:
import cv2
import numpy as np
from matplotlib import pyplot as plt
#加载训练好的模型,可以选择使用Caffee或者Tensorflow模型,加载的2个文件不一样。
#dnnnet = cv2.dnn.readNetFromCaffe("E:\VSCode\CSDN\deploy.prototxt", "E:\VSCode\CSDN\res10_300x300_ssd_iter_140000_fp16.caffemodel")
dnnnet = cv2.dnn.readNetFromTensorflow("E:\VSCode\CSDN\opencv_face_detector_uint8.pb", "E:\VSCode\CSDN\opencv_face_detector.pbtxt")
img = cv2.imread("E:\VSCode\CSDN\hello.jpg") #读取图像
h, w = img.shape[:2] #获得图像尺寸
blobs = cv2.dnn.blobFromImage(img, 1.0, (300, 300), #创建图像的块数据
[104., 117., 123.], False, False)
dnnnet.setInput(blobs) #将块数据设置为输入
detections = dnnnet.forward() #执行计算,获得检测结果
faces = 0
for i in range(0, detections.shape[2]): #迭代,输出可信度高的人脸检测结果
confidence = detections[0, 0, i, 2] #获得可信度
if confidence > 0.6: #输出可行度高于60%的结果
faces += 1
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) #获得人脸在图像中的坐标
x1,y1,x2,y2 = box.astype("int")
y = y1 - 10 if y1 - 10 > 10 else y1 + 10 #计算可信度输出位置
text = "%.3f"%(confidence * 100)+'%'
cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2)#标注人脸范围
cv2.putText(img,text, (x1, y),cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)#输出可信度
cv2.imshow('faces',img)
cv2.waitKey(0)
deploy.prototxt
文件定义模型结构配置文件。
res10_300x300_ssd_iter_140000_fp16.caffemodel
包含实际权重训练模型文件。
opencv_face_detector_uint8.pb
包含实际权重训练模型文件。
opencv_face_detector.pbtxt
定义模型结构配置文件
函数cv2.dnn.blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop[, ddepth]]]]]])
作用:对图像进行预处理,包括减均值,比例缩放,裁剪,交换通道等,返回一个4通道的blob(blob可以简单理解为一个N维的数组,用于神经网络的输入)
参数:
image:输入图像(1、3或者4通道)
可选参数
scalefactor:图像各通道数值的缩放比例
size:输出图像的空间尺寸,如size=(200,300)表示高h=300,宽w=200
mean:用于各通道减去的值,以降低光照的影响(e.g. image为bgr3通道的图像,mean=[104.0, 177.0, 123.0],表示b通道的值-104,g-177,r-123)
swapRB:交换RB通道,默认为False.(cv2.imread读取的是彩图是bgr通道)
crop:图像裁剪,默认为False.当值为True时,先按比例缩放,然后从中心裁剪成size尺寸
ddepth:输出的图像深度,可选CV_32F 或者 CV_8U.
代码如下(示例):
import cv2
import numpy as np
liudehua_img_1=cv2.imread('E:/VSCode/CSDN/liudehua1.jpg',cv2.IMREAD_GRAYSCALE)) #打开图像,灰度图
liudehua_img_2=cv2.imread('E:/VSCode/CSDN/liudehua2.jpg',cv2.IMREAD_GRAYSCALE))
liudehua_img_3=cv2.imread('E:/VSCode/CSDN/liudehua3.jpg',cv2.IMREAD_GRAYSCALE))
wangzuxian_img_1=cv2.imread('E:/VSCode/CSDN/wangzuxian1.jpg',cv2.IMREAD_GRAYSCALE))
wangzuxian_img_2=cv2.imread('E:/VSCode/CSDN/wangzuxian2.jpg',cv2.IMREAD_GRAYSCALE))
wangzuxian_img_3=cv2.imread('E:/VSCode/CSDN/wangzuxian3.jpg',cv2.IMREAD_GRAYSCALE))
train_images=[liudehua_img_1,liudehua_img_2,liudehua_img_3,wangzuxian_img_1,wangzuxian_img_2,wangzuxian_img_3] #创建训练图像数组
labels=np.array([0,0,0,1,1,1]) #创建标签数组,0和1表示对应的训练图像数组中人脸的身份
recognizer=cv2.face.EigenFaceRecognizer_create()#创建EigenFaces识别器
recognizer.train(train_images,labels) #执行训练操作
testimg=cv2.imread('E:/VSCode/CSDN/test.jpg',0) #打开测试图像
label,confidence=recognizer.predict(testimg) #识别人脸
print('匹配标签:',label)
print('可信度:',confidence)
要求训练和预测图片的大小一致。可以使用在线图片处理网站将图片处理成同样大小。
train_images=[liudehua_img_1,liudehua_img_2,liudehua_img_3,wangzuxian_img_1,wangzuxian_img_2,wangzuxian_img_3]
labels=np.array([0,0,0,1,1,1])
要求标签中的序号要和图片一一对应,比如刘德华照片是1,2,3,则labels中,前3个都是0号。后3张都是王祖贤,则序号都是1。
confidence表示置信度,值通常在0~20000之间,只要低于5000都被认为是相当可靠的识别结果。
代码和前一种方法一样,只有一个地方不一样。
recognizer=cv2.face.FisherFaceRecognizer_create()#创建FisherFaces识别器
confidence表示置信度,值通常在0~20000之间,只要低于5000都被认为是相当可靠的识别结果。
代码和第一种方法一样,只有一个地方不一样。
recognizer=cv2.face.LBPHFaceRecognizer_create()#创建LBPH识别器
confidence表示置信度,一个好的识别参考值要低于 50 , 任何高于 80 的参考值都会被认为是低的置信度评分。
Dlib库的安装比较麻烦。这边创建了一个专门的环境给Dlib用。创建环境的方法请看。conda基本操作
先安装这两个库。
pip3 install cmake -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install boost -i https://pypi.tuna.tsinghua.edu.cn/simple
dlib库直接PIP3安装的话基本都会报错,这里使用whl文件安装。
下载whl文件这个链接中只有python3.7和python3.8的版本。
选择你对应python版本的whl文件,然后执行
用绝对途径安装。这就安装成功了。
具体算法实现,参考此链接
也可以参考此篇。使用dlib库进行人脸识别
当然也可以使用Dlib来实现人脸识别,效果也很好。
以下是人脸检测(非识别)代码:
import cv2
import dlib
detector = dlib.get_frontal_face_detector()# Load the detector
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")# Load the predictor
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
# Convert image into grayscale
gray = cv2.cvtColor(src=frame, code=cv2.COLOR_BGR2GRAY)
# Use detector to find landmarks
faces = detector(gray)
for face in faces:
x1 = face.left() # left point
y1 = face.top() # top point
x2 = face.right() # right point
y2 = face.bottom() # bottom point
# Create landmark object
landmarks = predictor(image=gray, box=face)
# Loop through all the points
for n in range(0, 68):
x = landmarks.part(n).x
y = landmarks.part(n).y
# Draw a circle
cv2.circle(img=frame, center=(x, y), radius=3, color=(0, 255, 0), thickness=-1)
# show the image
cv2.imshow(winname="Face", mat=frame)
# Exit when escape is pressed
if cv2.waitKey(delay=1) == 27:
break
# When everything done, release the video capture and video write objects
cap.release()
# Close all windows
cv2.destroyAllWindows()
shape_predictor_68_face_landmarks.da文件可留下邮箱获取也可以自行百度搜索。
Dlib效果不错。