opencv——haar人脸检测与DNN人脸检测算法demo与性能对比

首先来看下从摄像头视频流中检测人脸的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.pbres10_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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值