Python使用 Open CV 进行口罩检测

根据 Worldometer 汇编的数据(截至 2020 年 6 月 5 日),冠状病毒病已蔓延到超过 213 个国家,在全球范围内感染了超过 700 万人并造成超过 403,202 人死亡

为了限制冠状病毒的传播,保持社交距离和遵守卫生标准(例如强制佩戴口罩、使用手手套、面罩和使用消毒剂)非常重要。

许多组织强制要求遵守社交距离和戴口罩。本文介绍了如何使用 OpenCV 和 Python 检测口罩监控。

我假设您具有 OpenCV 和 Python 的基本知识。

主要有两个步骤:

  1. 在输入视频的每一帧中识别人脸和嘴巴

  2. 识别人员是否使用面具

第 1 步:使用 Python 和 OpenCV 识别人脸和嘴巴进行人脸预测的步骤是:

  1. 使用“CascadeClassifier”函数和“haarcascade_frontalface_default.xml”创建HAAR Cascade对象

  2. 使用功能读取的图像“imread”(或用于视频“读” /相机输入)功能

  3. 使用'cvtColor'函数进行灰度转换

  4. 使用“detectMultiScale”功能检测人脸

要获取 Open CV 如何检测人脸的详细信息,请参阅使用 OpenCV 的人脸识别链接— OpenCV 2.4.13.7 文档

据观察,戴白色面具的人,大多数时候 OpenCV 无法正确识别人脸。为了克服这个困难,使用“阈值”函数转换黑白图像,然后将此图像发送到“detectMultiScale”函数。

注意:根据相机和周围光线在80 到 105 “阈值”范围内调整阈值 (bw_threshold) 值很重要。

以下代码检测图像中人脸和嘴巴:

1.png

第 2 步:识别是否使用面具

如上代码所示,一共有三个矩形对象:

  1. “灰色”图像人脸矩形。
  2. “黑白”图像人脸矩形。
  3. '灰色' 图像 嘴矩形。

添加以下代码以在“检测嘴巴”代码后验证掩码/无掩码。

=> 当人戴着面具时,它将显示为检测到面具:-

2.png

=> 当人不戴口罩时,它将显示为未检测到口罩:-

3.png

质量检测标准

根据矩形的数量和矩形的嘴和脸的位置,我们可以创建规则来检测面具。以下真值表将提供带面具/不带面具的正确条件。

4.png

您可以从 GitHub 下载完整的代码和 HAAR 级联 XML 文件。

import numpy as np
import cv2
import random

# multiple cascades: https://github.com/Itseez/opencv/tree/master/data/haarcascades

face_cascade = cv2.CascadeClassifier('data\\xml\\haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('data\\xml\\haarcascade_eye.xml')
mouth_cascade = cv2.CascadeClassifier('data\\xml\\haarcascade_mcs_mouth.xml')
upper_body = cv2.CascadeClassifier('data\\xml\\haarcascade_upperbody.xml')



# Adjust threshold value in range 80 to 105 based on your light.
bw_threshold = 80

# User message
font = cv2.FONT_HERSHEY_SIMPLEX
org = (30, 30)
weared_mask_font_color = (255, 255, 255)
not_weared_mask_font_color = (0, 0, 255)
thickness = 2
font_scale = 1
weared_mask = "Thank You for wearing MASK"
not_weared_mask = "Please wear MASK to defeat Corona"

# Read video
cap = cv2.VideoCapture(0)

while 1:
    # Get individual frame
    ret, img = cap.read()
    img = cv2.flip(img,1)

    # Convert Image into gray
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Convert image in black and white
    (thresh, black_and_white) = cv2.threshold(gray, bw_threshold, 255, cv2.THRESH_BINARY)
    #cv2.imshow('black_and_white', black_and_white)

    # detect face
    faces = face_cascade.detectMultiScale(gray, 1.1, 4)

    # Face prediction for black and white
    faces_bw = face_cascade.detectMultiScale(black_and_white, 1.1, 4)


    if(len(faces) == 0 and len(faces_bw) == 0):
        cv2.putText(img, "No face found...", org, font, font_scale, weared_mask_font_color, thickness, cv2.LINE_AA)
    elif(len(faces) == 0 and len(faces_bw) == 1):
        # It has been observed that for white mask covering mouth, with gray image face prediction is not happening
        cv2.putText(img, weared_mask, org, font, font_scale, weared_mask_font_color, thickness, cv2.LINE_AA)
    else:
        # Draw rectangle on gace
        for (x, y, w, h) in faces:
            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 255), 2)
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = img[y:y + h, x:x + w]


            # Detect lips counters
            mouth_rects = mouth_cascade.detectMultiScale(gray, 1.5, 5)

        # Face detected but Lips not detected which means person is wearing mask
        if(len(mouth_rects) == 0):
            cv2.putText(img, weared_mask, org, font, font_scale, weared_mask_font_color, thickness, cv2.LINE_AA)
        else:
            for (mx, my, mw, mh) in mouth_rects:

                if(y < my < y + h):
                    # Face and Lips are detected but lips coordinates are within face cordinates which `means lips prediction is true and
                    # person is not waring mask
                    cv2.putText(img, not_weared_mask, org, font, font_scale, not_weared_mask_font_color, thickness, cv2.LINE_AA)

                    #cv2.rectangle(img, (mx, my), (mx + mh, my + mw), (0, 0, 255), 3)
                    break

    # Show frame with results
    cv2.imshow('Mask Detection', img)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

# Release video
cap.release()
cv2.destroyAllWindows()

  • 9
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值