1.人脸检测模型Caffe
OpenCV自带了基于Caffe的人脸检测:
GitHub地址:https://github.com/opencv/opencv/tree/4.1.2/samples/dnn/face_detector
训练使用Caffe模型必须的两个文件:
- .prototxt ------------ 模型的网络结构
- .caffemodel ------- 模型权重
1.1 下载预训练权重
这里用了旧版本4.1.0
双击解压提取到一个文件夹下,找到 download_weights.py
和 weights.meta4
文件,用来下载权重文件:
或者weights.meta4
文件包含有链接可直接下载:
https://raw.githubusercontent.com/opencv/opencv_3rdparty/dnn_samples_face_detector_20180205_fp16/res10_300x300_ssd_iter_140000_fp16.caffemodel
下载后的模型文件大小有5M:
2. 人脸图像测试
2.1 代码
import numpy as np
import cv2
def detector_face_image(prototxt_path,model_path,image_path):
# 加载
print("loading model...")
net = cv2.dnn.readNetFromCaffe(prototxt_path,model_path)
#构造blob
image = cv2.imread(image_path)
image = cv2.resize(image,(300,300))
(h,w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(image, 1.0, (300,300),
(104.0,177.0,123.0))
# 检测人脸
print("detecting face... ")
net.setInput(blob)
detections = net.forward()
#遍历
for i in range(0, detections.shape[2]):
confidence = detections[0,0,i,2]
default_confidence = 0.5
# 过滤弱检测
if confidence > default_confidence:
# 获取检测框坐标
box = detections[0,0,i,3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
# 绘制框
print("confidence: {:.3f}".format(confidence))
text = "{:.2f}%".format(confidence * 100)
y = startY - 10 if (startY - 10) > 10 else (startY +10)
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2)
cv2.putText(image,text, (startX, y),cv2.FONT_HERSHEY_SIMPLEX,
0.45, (0,0,255),1)
cv2.imshow("Output_Image",image)
cv2.waitKey(0)
if __name__=="__main__":
# prototxt文件路径
prototxt_path = "G:\\yu_data\\detect_face\\deploy.prototxt"
# model文件路径
model_path = "G:\\yu_data\\detect_face\\res10_300x300_ssd_iter_140000_fp16.caffemodel"
# image路径
image_path = "G:\\yu_data\\detect_face\\01.png"
detector_face_image(prototxt_path, model_path, image_path)
2.2 结果
待检测图像 | 检测结果 |
---|---|
未检测到人脸 |
如果人脸比较远,效果并不好。
3. 人脸视频测试
3.1 代码
import imutils
from imutils.video import VideoStream
from imutils.video import FileVideoStream
from imutils.video import FPS
import numpy as np
import cv2
import time
def detector_face_video(prototxt_path,model_path,video_path):
# 加载
print("loading model...")
net = cv2.dnn.readNetFromCaffe(prototxt_path,model_path)
#从摄像头读取
print("starting video stream...")
# vs = VideoStream(src=0).start()
# time.sleep(2.0)
# 直接读取视频文件
fvs = FileVideoStream(video_path).start()
while True:
# 获取单帧
# frame = vs.read()
frame = fvs.read()
# frame = imutils.resize(frame, width=640)
if frame is None:
break
# 构造blob
(h,w) = frame.shape[:2]
# print(h,w)
frame = cv2.resize(frame,(640,360))
blob = cv2.dnn.blobFromImage(frame, 1.0, (640,360),
(104.0,177.0,123.0))
# 检测人脸
print("detecting face... ")
net.setInput(blob)
detections = net.forward()
#遍历
for i in range(0, detections.shape[2]):
confidence = detections[0,0,i,2]
default_confidence = 0.7
# 过滤弱检测
if confidence < default_confidence:
continue
# 获取检测框坐标
box = detections[0,0,i,3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
# 绘制框
print("confidence: {:.3f}".format(confidence))
text = "{:.2f}%".format(confidence * 100)
y = startY - 10 if (startY - 10) > 10 else (startY +10)
cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2)
cv2.putText(frame,text, (startX, y),cv2.FONT_HERSHEY_SIMPLEX,
0.45, (0,0,255),1)
cv2.imshow("Output_Frame",frame)
key = cv2.waitKey(1) & 0xFF
# 按q键退出
if key == ord("q"):
break
fvs.release()
cv2.destroyAllWindows()
# vs.stop()
if __name__=="__main__":
# prototxt文件路径
prototxt_path = "G:\\yu_data\\detect_face\\deploy.prototxt"
# model文件路径
model_path = "G:\\yu_data\\detect_face\\res10_300x300_ssd_iter_140000_fp16.caffemodel"
# video路径
video_path = "G:\\yu_data\\detect_face\\1.mp4"
detector_face_video(prototxt_path, model_path, video_path)