首先来看下从摄像头视频流中检测人脸的demo:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
def face_detected(img):
face_cascade = cv2.CascadeClassifier('D:\python_code\haarcascades\haarcascade_frontalface_alt.xml') #脸部haar特征文件
eye_cascade = cv2.CascadeClassifier('D:\python_code\haarcascades\haarcascade_eye.xml') #眼部haar特征文件
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.1,3,0)
for (x,y,w,h) in faces: #遍历返回的值
img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) #画框
roi_eye = img[y:y+h,x:x+w] #分割出脸部区域
eyes = eye_cascade.detectMultiScale(roi_eye,1.03,5,0,(40,40)) #在脸部区域寻找眼部
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(img,(x+ex,y+ey),(x+ex+ew,y+ey+eh),(0,255,0),2)
return img
while True:
ret,frame = cap.read()
if ret == True:
frame = face_detected(frame)
frame = cv2.flip(frame,1)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
注意!haar特征文件的路径需要读者根据自己本地的文件路径进行更改!
代码中的:`
eyes = eye_cascade.detectMultiScale(roi_eye,1.03,5,0,(40,40)) #在脸部区域寻找眼部,通过对眼睛搜索的最小尺寸为40*40,可去掉假阳性(false positive)。
这一行,需要注意detectMultiScale函数有许多可选参数,在人脸检测时默认参数足以检测人脸。但是眼睛是一个比较小的人脸特征,并且胡字和鼻子的本身阴影以及帧的随机阴影都会产生假阳性,通过对搜索像素的大小进行限制,即可去掉假阳性的情况。然后测试参数直到达到比较理想的效果。
运行效果:
PS:打了马赛克了哈,效果是将你的脸和眼睛框选出来。
下面让我们在图像中加上FPS来查看算法效率。
关键代码:
start = time.time() #开始计时
###运行代码段
end = time.time() #结束计时
seconds = end-start
fps = 1 / seconds #计算帧率
print(face_position)
cv2.putText(frame, #图像
"FPS: {0}".format(float('%.1f'%fps)), #fps数值
(int(frame.shape[0]/10), #x坐标
int(frame.shape[1]/10)), #y坐标
cv2.FONT_HERSHEY_SIMPLEX, #字体
1, #字体大小
(0, 0, 255), #颜色
1) #粗细
效果:
可以看到帧率不是很高,每秒才10帧上下,光线较暗的情况下可以达到大约13帧。下面实验下opencv内置的DNN模块,使用caffe模型的效果。
使用前,找到你的opencv安装目录,sources\samples\dnn\face_detector,里面有个download_weights.py,执行后,会下载两个文件, opencv_face_detector_uint8.pb和res10_300x300_ssd_iter_140000_fp16.caffemodel。
caffemodel的是caffe框架训练出来的,pb的是tenserflow框架训练出来的。这里我们实验一下caffe框架训练出来的模型。
完整代码:
import cv2
import numpy as np
import time
import os
cap = cv2.VideoCapture(0)
cap.set(5,30)
net = cv2.dnn.readNetFromCaffe(prototxt="D:\github\Opencv-Algorithm-summary\deploy.prototxt",
caffeModel="D:\\github\\Opencv-Algorithm-summary\\res10_300x300_ssd_iter_140000_fp16.caffemodel")
face_positon=[0,0,0,0]
def face_detected(img):
eye_cascade = cv2.CascadeClassifier('D:\python_code\haarcascades\haarcascade_eye.xml') #眼部haar特征文件
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blob = cv2.dnn.blobFromImage(cv2.resize(img,(300,300)),
1.0,
(300,300),
(104.0,177.0,123.0))
net.setInput(blob)
detections = net.forward()
h,w,c=img.shape
for i in range(0,detections.shape[2]):
confidence = detections[0,0,i,2]
if confidence > 0.6:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
text = "{:.2f}%".format(confidence * 100)
y = startY - 10 if startY - 10 > 10 else startY + 10
cv2.rectangle(img, (startX, startY), (endX, endY),
(0, 255,0), 1)
cv2.putText(img, text, (startX, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
return img
while True:
ret,frame = cap.read()
if ret == True:
start = time.time()
face_position = [0,0,frame.shape[1],frame.shape[0]]
frame = face_detected(frame)
frame = cv2.flip(frame,1)
end = time.time()
seconds = end-start
#print( "Time taken : {0} seconds".format(seconds))
fps = 1 / seconds
#print( "Estimated frames per second : {0}".format(fps))
#print(face_position)
cv2.putText(frame, "FPS: {0}".format(float('%.1f'%fps)),(int(frame.shape[0]/10),int(frame.shape[1]/10)),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255),
1)
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
注意!模型和配置文件的路径要根据你自己的环境进行更改!注意避坑!很容易出问题!
运行截图:
可以看到效果还是不错的,基本上运行帧率在20帧左右。
暂时优化到这边,改天再继续优化。
另:南方科技大学余仕琪老师开源的MTCNN人脸检测算法是目前最高效的算法。可达2000FPS!