PythonOpenCV-人脸检测和识别-人脸检测
1. 基于Haar的人脸检测
在 OpenCV源代码中的“datalhaarcascades”文件夹中包含训练好的 Haar 级联分类器文件,示例如下:
- haarcascade_eye.xml::人眼检测
- haarcascade_eye tree_eyeglasses.xml:眼镜检测
- haarcascade_frontalcatface.xml:猫脸检测
- haarcascade_frontalface_alt.xml:人脸检测
- haarcascade_frontalface_default.xml:人脸检测
- haarcascade_profileface.xml::侧脸检测
cv2.CascadeClassifier()函数用于加载分类器,其基本格式如下:
faceClassifier = cv2.CascadeClassifier(filename)
参数说明:
faceClassifier:返回的级联分类器对象
filename:级联分类器的文件名
级联分类器对象的 detectMultiScale()方法用于执行检测,其基本格式如下:
objects = faceClassifier.detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]])
参数说明:
objects:返回的目标矩形,矩形中为人脸
image:输入图像,通常为灰度图像
scaleFactor:图像缩放比例
minNeighbors:构成目标矩形的最少相邻矩形个数
flags:在低版本的 OpenCV 1.x 中使用,高版本中通常省略该参数
minSize:目标矩形的最小尺寸
maxSize:目标矩形的最大尺寸
1.1 使用 Haar 级联分类器检测人脸
使用haarcascade_frontalface_default.xml和haarcascade_eye.xml分类器检测图像中的人脸和眼睛
代码示例:
import cv2 as cv img = cv.imread('src.jpg') # 打开输入图像 cv.imshow('src', img) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 转换为灰度图像 # 加载人脸检测器 face = cv.CascadeClassifier('haarcascade_frontalface_default.xml') # 加载眼睛检测器 eye = cv.CascadeClassifier('haarcascade_eye.xml') faces = face.detectMultiScale(gray) # 执行人脸检测 for x, y, w, h in faces: cv.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: # 标注眼睛 cv.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) cv.imshow('faces', img) # 显示检测结果 cv.waitKey(0)
1.2 使用 Haar 级联分类器检测猫脸
使用 haarcascade_frontalcatface.xml 分类器检测图像中的猫脸
代码示例:
import cv2 as cv img = cv.imread('cat2.jpg') # 打开输入图像 cv.imshow('src', img) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 转换为灰度图像 # 加载猫脸检测器 face = cv.CascadeClassifier('haarcascade_frontalcatface.xml') faces = face.detectMultiScale(gray) # 执行猫脸检测 for x, y, w, h in faces: cv.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) # 绘制矩形标注猫脸 cv.imshow('faces', img) # 显示检测结果 cv.waitKey(0)
运行结果:
1.3 使用 Haar 级联分类器检测摄像头视频中的人脸
代码示例:
import cv2 as cv capture = cv.VideoCapture(0) # 创建视频捕捉器对象 if not capture.isOpened: print('不能打开摄像头') exit(0) # 不能打开摄像头时结束程序 # 加载人脸检测器 face = cv.CascadeClassifier('haarcascade_frontalface_default.xml') # 加载眼睛检测器 eye = cv.CascadeClassifier('haarcascade_eye.xml') while True: ret, frame = capture.read() # 读摄像头的帧 if frame is None: break gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) # 转换为灰度图像 faces = face.detectMultiScale(gray) # 执行人脸检测 for x, y, w, h in faces: cv.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: # 标注眼睛 cv.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) cv.imshow('faces', frame) # 显示帧 key = cv.waitKey(30) if key == 27: # 按Esc键结束程序 break
运行结果:
由于本人太丑了,显示不了一点!!!
2. 基于深度学习的人脸检测
OpenCV 的深度神经网络模块提供了基于深度学习的人脸检测器。DNN 模块中使用了广受欢迎的深度学习框架,包括Caffe、TensorFlow、Torch 和 Darknet 等。
OpenCV 提供了两个预训练的人脸检测模型: Caffe 和 TensorFlow 模型Caffe 模型需加载以下两个文件:
- deploy.prototxt: 定义模型结构的配置文件
- res10_300x300_ssd_iter_140000 fp16.cafemodel:包含实际层权重的训练模型文件
TensorFlow 模型需加载以下两个文件:
- opencv_face detector.pbtxt: 定义模型结构的配置文件
- opencv_face_detector_uint8.pb: 包含实际层权重的训练模型文件
使用预训练的模型执行人脸检测时主要包含下列步骤:
- 调用 cv2.dnn.readNetFromCaffe)或 cv2.dnn.readNetFromTensorflow0函数加载模型,创建检测器
- 调用 cv2.dnn.blobFromlmage()函数将待检测图像转换为图像块数据
- 调用检测器的 setlnput()方法将图像块数据设置为模型的输入数据
- 调用检测器的 forward()方法执行计算,获得预测结果
- 将可信度高于指定值的预测结果作为检测结果,在原图像中标注人脸,同时输出可信度作为参考
代码示例:
import cv2 as cv import numpy as np from matplotlib import pyplot as plt # dnnnet = cv.dnn.readNetFromCaffe("deploy.prototxt", #加载训练好的模型 # "res10_300x300_ssd_iter_140000_fp16.caffemodel") dnnnet = cv.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt") img = cv.imread("src.jpg") # 读取图像 cv.imshow('src', img) h, w = img.shape[:2] # 获得图像尺寸 # 创建图像的块数据 blobs = cv.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: # 输出可行度高于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) + '%' cv.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2) # 标注人脸范围 # 输出可信度 cv.putText(img, text, (x1, y), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2) cv.imshow('faces', img) cv.waitKey(0)
/*-------------------------------------------------------------------------------------------------------
笔者说明:
该笔记来源于本人学习Python + OpenCv时的资料,
分享出来只是为了供大家学习,并且为了自己以后想要用的时候方便寻找。
时间:2023年9月3日
------------------------------------------------------------------------------------------------------------*/