实验准备
硬件设备准备
-
旭日X3派一块
-
USB数据线(tpye-c)
-
USB摄像头(ANC狼魔)
其他准备
-
MpbaXterm
-
Ubuntu20.04系统环境
-
python3.8.10环境
-
jupyterlab环境
-
笔记本电脑一台
一,基于Haar的人脸检测
在之前的博客中,博主做过摄像头驱动的实验,今天,我们在此基础上继续学习一下基于Haar的人脸检测
本次实验使用OpenCV提供的Haar级联分类器来进行人脸检测。在OpenCV源代码中的“data\haarcascades”文件夹中包含训练好的Haar级联分类器文件,示例如下
haarcascade_exe.xml #人眼检测
haarcascade_eye_tree_eyeglasses #眼镜检测
haarcascade_frontalcatface.xml #猫脸检测
haarcascade_frontalface_alt.xml #人脸检测
haarcascade_frontalface_default.xml #人脸检测
haarcascade_profileface.xml #侧脸检测
haarcascade_exe.xml #人眼检测 haarcascade_eye_tree_eyeglasses #眼镜检测 haarcascade_frontalcatface.xml #猫脸检测 haarcascade_frontalface_alt.xml #人脸检测 haarcascade_frontalface_default.xml #人脸检测 haarcascade_profileface.xml #侧脸检测
haarcascade_exe.xml #人眼检测 haarcascade_eye_tree_eyeglasses #眼镜检测 haarcascade_frontalcatface.xml #猫脸检测 haarcascade_frontalface_alt.xml #人脸检测 haarcascade_frontalface_default.xml #人脸检测 haarcascade_profileface.xml #侧脸检测
haarcascade_exe.xml #人眼检测 haarcascade_eye_tree_eyeglasses #眼镜检测 haarcascade_frontalcatface.xml #猫脸检测 haarcascade_frontalface_alt.xml #人脸检测 haarcascade_frontalface_default.xml #人脸检测 haarcascade_profileface.xml #侧脸检测
haarcascade_exe.xml #人眼检测 haarcascade_eye_tree_eyeglasses #眼镜检测 haarcascade_frontalcatface.xml #猫脸检测 haarcascade_frontalface_alt.xml #人脸检测 haarcascade_frontalface_default.xml #人脸检测 haarcascade_profileface.xml #侧脸检测
cv2.CascadeClassifier()函数用于加载分类器,其基本格式如下。
faceClassifier=cv2.CascadeClassifier(filename)
faceClassifier=cv2.CascadeClassifier(filename)
faceClassifier=cv2.CascadeClassifier(filename)
faceClassifier=cv2.CascadeClassifier(filename)
faceClassifier=cv2.CascadeClassifier(filename)
参数说明如下:
faceClassifier为返回的级联分类器对象
filename为级联分类器的文件名
级联分类器对象的detectMultiScale()方法用于执行检测,其基本格式如下。
objectsfaceClassifier.detectMultiScale(image[,scaleFactor[,minNeighbors[,flags[,maxSize]]]])
objectsfaceClassifier.detectMultiScale(image[,scaleFactor[,minNeighbors[,flags[,maxSize]]]])
objectsfaceClassifier.detectMultiScale(image[,scaleFactor[,minNeighbors[,flags[,maxSize]]]])
objectsfaceClassifier.detectMultiScale(image[,scaleFactor[,minNeighbors[,flags[,maxSize]]]])
objectsfaceClassifier.detectMultiScale(image[,scaleFactor[,minNeighbors[,flags[,maxSize]]]])
参数说明如下
objects问返回的目标矩形,矩形中为人脸。
image为输入图像,通常为灰度图像。
scaleFactor为图像缩放比例。
minNeighbors为构成目标矩形的最少相邻矩形个数。
flags在低版本的OpenCV1.x中使用,高版本中通常省略该参数。
minSize为目标矩形的最小尺寸。
maxSize为目标矩形的最大尺寸。
1.使用Haar级联分类器检测人脸
下面的代码使用haarcascade_frontalface_default.xml和haarcascade_eye.xml分类器检测图像中的人脸和眼睛。
#test9-1.py:使用Haar级联检测器检测人脸
#将用于眼睛和人脸检测的Harr级联检测器文件复制到程序文件位置
import cv2
img=cv2.imread('heard.jpg') #打开输入图像
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图像
#加载人脸检测器
face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
#加载眼睛检测器
eye = cv2.CascadeClassifier('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),2)
cv2.imshow('faces',img) #显示检测结果
cv2.waitKey(0)
#test9-1.py:使用Haar级联检测器检测人脸 #将用于眼睛和人脸检测的Harr级联检测器文件复制到程序文件位置 import cv2 img=cv2.imread('heard.jpg') #打开输入图像 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图像 #加载人脸检测器 face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载眼睛检测器 eye = cv2.CascadeClassifier('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),2) cv2.imshow('faces',img) #显示检测结果 cv2.waitKey(0)
#test9-1.py:使用Haar级联检测器检测人脸 #将用于眼睛和人脸检测的Harr级联检测器文件复制到程序文件位置 import cv2 img=cv2.imread('heard.jpg') #打开输入图像 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图像 #加载人脸检测器 face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载眼睛检测器 eye = cv2.CascadeClassifier('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),2) cv2.imshow('faces',img) #显示检测结果 cv2.waitKey(0)
#test9-1.py:使用Haar级联检测器检测人脸 #将用于眼睛和人脸检测的Harr级联检测器文件复制到程序文件位置 import cv2 img=cv2.imread('heard.jpg') #打开输入图像 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图像 #加载人脸检测器 face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载眼睛检测器 eye = cv2.CascadeClassifier('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),2) cv2.imshow('faces',img) #显示检测结果 cv2.waitKey(0)
#test9-1.py:使用Haar级联检测器检测人脸 #将用于眼睛和人脸检测的Harr级联检测器文件复制到程序文件位置 import cv2 img=cv2.imread('heard.jpg') #打开输入图像 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图像 #加载人脸检测器 face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载眼睛检测器 eye = cv2.CascadeClassifier('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),2) cv2.imshow('faces',img) #显示检测结果 cv2.waitKey(0)
2.使用Haar级联分类器检测摄像头视频中的人脸
除了可以检测图片中的人脸,Haar级联分类器还可以用于检测视频中的人脸,默认的摄像头帧率为30帧,同时也可以自己设置摄像头帧率使用capture.set()函数定义。
#test9-3.py:检测摄像头视频中的人脸
import cv2
capture = cv2.VideoCapture(0) #创建视频捕捉器对象
if not capture.isOpened:
print('不能打开摄像头')
exit(0) #不能打开摄像头时结束程序
#加载人脸检测器
face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
#加载眼睛检测器
eye = cv2.CascadeClassifier('haarcascade_eye.xml')
while True:
ret, frame = capture.read() #读摄像头的帧
if frame is None:
break
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(30)
if key == 27: #按Esc键结束程序
break
#test9-3.py:检测摄像头视频中的人脸 import cv2 capture = cv2.VideoCapture(0) #创建视频捕捉器对象 if not capture.isOpened: print('不能打开摄像头') exit(0) #不能打开摄像头时结束程序 #加载人脸检测器 face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载眼睛检测器 eye = cv2.CascadeClassifier('haarcascade_eye.xml') while True: ret, frame = capture.read() #读摄像头的帧 if frame is None: break 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(30) if key == 27: #按Esc键结束程序 break
#test9-3.py:检测摄像头视频中的人脸 import cv2 capture = cv2.VideoCapture(0) #创建视频捕捉器对象 if not capture.isOpened: print('不能打开摄像头') exit(0) #不能打开摄像头时结束程序 #加载人脸检测器 face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载眼睛检测器 eye = cv2.CascadeClassifier('haarcascade_eye.xml') while True: ret, frame = capture.read() #读摄像头的帧 if frame is None: break 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(30) if key == 27: #按Esc键结束程序 break
#test9-3.py:检测摄像头视频中的人脸 import cv2 capture = cv2.VideoCapture(0) #创建视频捕捉器对象 if not capture.isOpened: print('不能打开摄像头') exit(0) #不能打开摄像头时结束程序 #加载人脸检测器 face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载眼睛检测器 eye = cv2.CascadeClassifier('haarcascade_eye.xml') while True: ret, frame = capture.read() #读摄像头的帧 if frame is None: break 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(30) if key == 27: #按Esc键结束程序 break
#test9-3.py:检测摄像头视频中的人脸 import cv2 capture = cv2.VideoCapture(0) #创建视频捕捉器对象 if not capture.isOpened: print('不能打开摄像头') exit(0) #不能打开摄像头时结束程序 #加载人脸检测器 face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') #加载眼睛检测器 eye = cv2.CascadeClassifier('haarcascade_eye.xml') while True: ret, frame = capture.read() #读摄像头的帧 if frame is None: break 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(30) if key == 27: #按Esc键结束程序 break
二,基于深度学习的人脸检测
OpenCV的深度神经网络( Deep Neural Network, DNN)模块提供了基于深度学习的人脸检测器。DNN模块中使用了广受欢迎的深度学习框架,包括Caffe、TensorFlow、Torch 和Darknet等。
OpenCV提供了两个预训练的人脸检测模型: Caffe 和TensorFlow模型。
Caffe模型需加载以下两个文件。
deploy.prototxt 定义模型结构的配置文件
res10_300*300_ssd_iter_140000_fp16.caffemodel 包含实际层权重的训练模型文件。
TensorFlow模型需加载以下两个文件。
opencv_ face_ detector.pbtxt 定义模型结构的配置文件
opencv_ face_ _detector _uint8.pb 包含实际层权重的训练模型文件
在OpenCV源代码的“sources\samples\dnn\face_detector”文件夹中提供了模型配置文件,但未提供训练模型文件。可运行该文件夹中的download—weights.py下载上述的两个训练模型文件。
使用预训练的模型执行人脸检测时主要包含下列步骤。
(1)调用Cv2 dn.derFromafe或cv2 dnrecn eromenroo函数加载模型,创建检测器。
(2)调用cv2.dnn.blobFromlmage()函数将待检测图像转换为图像块数据。
(3)调用检测器的setInput()方法将图像块数据设置为模型的输入数据。
(4)调用检测器的forward()方法执行计算,获得预测结果。
(5)将可信度高于指定值的预测结果作为检测结果,在原图像中标注人脸,同时输出可信度作为参考。
示例代码如下:
#test9-4.py:DNN人脸检测
import cv2
import numpy as np
from matplotlib import pyplot as plt
#dnnnet = cv2.dnn.readNetFromCaffe("deploy.prototxt", #加载训练好的模型
# "res10_300x300_ssd_iter_140000_fp16.caffemodel")
dnnnet = cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")
img = cv2.imread("heard.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
print("detections.shape[2]",detections.shape[2])
for i in range(0, detections.shape[2]): #迭代,输出可信度高的人脸检测结果
confidence = detections[0, 0, i, 2] #获得可信度
print("confidence", detections[0, 0, i, 2])
if confidence > 0.6: #输出可行度高于80%的结果
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)
#test9-4.py:DNN人脸检测 import cv2 import numpy as np from matplotlib import pyplot as plt #dnnnet = cv2.dnn.readNetFromCaffe("deploy.prototxt", #加载训练好的模型 # "res10_300x300_ssd_iter_140000_fp16.caffemodel") dnnnet = cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt") img = cv2.imread("heard.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 print("detections.shape[2]",detections.shape[2]) for i in range(0, detections.shape[2]): #迭代,输出可信度高的人脸检测结果 confidence = detections[0, 0, i, 2] #获得可信度 print("confidence", detections[0, 0, i, 2]) if confidence > 0.6: #输出可行度高于80%的结果 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)
#test9-4.py:DNN人脸检测 import cv2 import numpy as np from matplotlib import pyplot as plt #dnnnet = cv2.dnn.readNetFromCaffe("deploy.prototxt", #加载训练好的模型 # "res10_300x300_ssd_iter_140000_fp16.caffemodel") dnnnet = cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt") img = cv2.imread("heard.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 print("detections.shape[2]",detections.shape[2]) for i in range(0, detections.shape[2]): #迭代,输出可信度高的人脸检测结果 confidence = detections[0, 0, i, 2] #获得可信度 print("confidence", detections[0, 0, i, 2]) if confidence > 0.6: #输出可行度高于80%的结果 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)
程序运行结果如下:
评论(0)
您还未登录,请登录后发表或查看评论