前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手教你用OpenCV做人脸口罩佩戴检测(附详细步骤+代码)

手把手教你用OpenCV做人脸口罩佩戴检测(附详细步骤+代码)

作者头像
Color Space
发布2021-04-30 11:29:08
12.2K44
发布2021-04-30 11:29:08
举报
文章被收录于专栏:OpenCV与AI深度学习

导读

本期将介绍使用OpenCV实现人脸口罩佩戴检测的详细步骤,手把手教你做一个效果还可以的口罩佩戴检测系统。

口罩检测思路与常用方法

在动手实现人脸口罩佩戴检测系统之前,我们常常会思考如何检测一个人是否佩戴口罩?方法很多,这里列举几个比较典型的方法:

① 用深度学习目标检测的方法,标注佩戴口罩与未佩戴口罩两类,然后选择合适的网络去训练检测,比如YoloV5等;

② 先检测人脸,然后将人脸ROI图像做分类,分为佩戴口罩和未佩戴口罩两类,结合人脸检测和分类网络实现;

③ 用OpenCV实现,先检测人脸,然后判断人脸ROI是否有佩戴口罩的特征;

④ 其他更好的方法。


本文使用第③种方法,选择合适的人脸检测方法与口罩佩戴判断方法即可。

效果展示

演示从视频中检测人脸是否佩戴口罩,未佩戴口罩将语音提示,避免露脸,测试视频素材来源于网络,实测使用笔记本自带摄像头检测效果更佳:

实现步骤与对应代码

程序实现步骤

(1) 使用OpenCV DNN网络检测人脸;

(2) 通过HSV阈值提取肤色;

(3) 通过肤色轮廓面积与人脸ROI面积比值判断是否佩戴口罩。


人脸检测方法对比

(1) 使用OpenCV Haar分类器检测人脸,例如使用自带的haarcascade_frontalface_alt.xml不能适应光线暗的情况和人脸遮挡情况,佩戴了口罩无法检测到人脸,无法继续进行后面步骤;

(2) 使用Dlib检测人脸,例如使用自带的shape_predictor_5_face_landmarks.dat不能适应人脸遮挡情况,佩戴了口罩无法检测到人脸,无法继续进行后面步骤;

(3) 使用OpenCV DNN网络检测人脸,使用自带的opencv_face_detector_uint8.pb能适应部分人脸遮挡和侧脸情况,能继续进行后续检测。

人脸检测步骤与代码

(1) 下载OpenCV DNN人脸检测模型:

链接:https://pan.baidu.com/s/1AaLYDjyMn17ZTxOv5f-m5A

提取码:9396

(2) 加载模型检测人脸,实例代码与效果如下;

代码语言:javascript
复制
import sys
import numpy as np
import cv2

modelFile = "opencv_face_detector_uint8.pb"
configFile = "opencv_face_detector.pbtxt"
net = cv2.dnn.readNetFromTensorflow(modelFile, configFile)
conf_threshold = 0.7

def detectFaceOpenCVDnn(net, frame):
    blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300), [104, 117, 123], False, False)
    frameHeight = frame.shape[0]
    frameWidth = frame.shape[1]
    net.setInput(blob)
    detections = net.forward()
    bboxes = []
    ret = 0
    for i in range(detections.shape[2]):
        confidence = detections[0, 0, i, 2]
        if confidence > conf_threshold:
            x1 = int(detections[0, 0, i, 3] * frameWidth)
            y1 = int(detections[0, 0, i, 4] * frameHeight)
            x2 = int(detections[0, 0, i, 5] * frameWidth)
            y2 = int(detections[0, 0, i, 6] * frameHeight)


            ROI = frame[y1:y2,x1:x2].copy()
            
            cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),2)#框出人脸区域
            
    return ret, frame

if __name__ == '__main__':
  img = cv2.imread("./2.jpg")
  _, result = detectFaceOpenCVDnn(net,img)
  cv2.imshow("face_detection", result)
  cv2.waitKey()
  cv2.destroyAllWindows()

(3) 通过HSV阈值提取肤色轮廓:

代码语言:javascript
复制
ROI = frame[y1:y2,x1:x2].copy()
hsv_img=cv2.cvtColor(ROI,cv2.COLOR_BGR2HSV)
lower_hsv_1 = np.array([0,30,30])#颜色范围低阈值
upper_hsv_1 = np.array([40,255,255])#颜色范围高阈值
lower_hsv_2 = np.array([140,30,30])#颜色范围低阈值
upper_hsv_2 = np.array([180,255,255])#颜色范围高阈值
mask1 = cv2.inRange(hsv_img,lower_hsv_1,upper_hsv_1)
mask2 = cv2.inRange(hsv_img,lower_hsv_2,upper_hsv_2)
mask = mask1 + mask2
mask = cv2.blur(mask,(3,3))
    
mask_color = cv2.cvtColor(mask,cv2.COLOR_GRAY2BGR)
cv2.imshow("mask", mask)

(4) 通过肤色轮廓面积与ROI面积比值判断是否有佩戴口罩,这里设置比值为0.65,上面三幅图的比例分别如下:

代码语言:javascript
复制
def cnt_area(cnt):
  area = cv2.contourArea(cnt)
  return area

def If_Have_Mask(img):
  hsv_img=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
  lower_hsv_1 = np.array([0,30,30])#颜色范围低阈值
  upper_hsv_1 = np.array([40,255,255])#颜色范围高阈值
  lower_hsv_2 = np.array([140,30,30])#颜色范围低阈值
  upper_hsv_2 = np.array([180,255,255])#颜色范围高阈值
  mask1 = cv2.inRange(hsv_img,lower_hsv_1,upper_hsv_1)
  mask2 = cv2.inRange(hsv_img,lower_hsv_2,upper_hsv_2)
  mask = mask1 + mask2
  mask = cv2.blur(mask,(3,3))
    
  mask_color = cv2.cvtColor(mask,cv2.COLOR_GRAY2BGR)
  cv2.imshow("mask", mask)

  contours,hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
  if len(contours) < 1:
      return "No Mask" 
      
  contours.sort(key = cnt_area, reverse=True)  
  #print(cv2.contourArea(contours[0]))
  area = cv2.contourArea(contours[0])
  mask_rate = area / (img.shape[0]*img.shape[1])
  print(mask_rate)
  if mask_rate < 0.65:
    return "Have Mask"
  else:
    return "No Mask"

结尾语:

文章实现的步骤并非最优,但基本检测效果还OK,大家跟着上述步骤和代码完全可以自己做出来。当然如果你懒得动手,那就加入知识星球获取吧,那里为你准备了完整源码和测试素材。

更多实用文章请移步至--精华文章--专题文章分类。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV与AI深度学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 口罩检测思路与常用方法
  • 效果展示
  • 实现步骤与对应代码
  • 结尾语:
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档