0 前言

2020年1月30日,看到团团发的视频,报道有用无人机劝老奶奶戴口罩的做法,突然萌生了这个想法,就是实现通过机器视觉检测有没有戴口罩。

那么,既然无聊在家,就挑战七天实现机器视觉检测戴口罩。

【武汉加油!中国加油!】挑战七天 实现机器视觉检测有没有戴口罩系统——第一二三天

【武汉加油!中国加油!】挑战七天 实现机器视觉检测有没有戴口罩系统——第四五六七天

【B站视频】:在家无聊写了一个视觉检测戴口罩程序,基于OpenCV和Python的戴口罩检测程序
2020年2月2日- 2020年2月6日:

经过前三天断断续续的查找资料和阅读相关文献,虽然比较繁琐,但磨刀不误砍柴工,经过充分的查找资料,才对自己要做的东西有较为充分的认识,有利于掌握基本面。
在这里插入图片描述

1 戴口罩检测系统

**为什么研究这个?**采用机器视觉代替人工是自动化的重要研究方向。自动检测口罩的检测系统的优点就在于节省人力、智能提醒、信息化监控。主要可以运用场景有以下三点:

  • 在突发重大疫情时,可以用于监督和提示公众戴好口罩出门,可以搭载在无人机上,在巡视时自动检测没有戴口罩出行的人并进行劝告。
  • 在ATM、银行等监控系统中,此功能可以对可疑人物进行检测。在超市、小区、图书馆等公共场所的入口门禁系统中,对未佩戴口罩的进行提醒。
  • 在手术室运用此系统检测医生是否戴口罩,在除了运用管理手段外,提供用技术手段监督医生的工作的选择,避免发生由工作失误导致的医疗事故。

目前市场上,还少见具有口罩检测功能的门禁系统,比较智能的是体温检测+金属+人脸识别的探测门。
在这里插入图片描述

此系统总体目标在于能够实时监测画面中的人脸,并将其分类为:1.戴口罩的人脸;2.不带口罩的人脸。 若发现不戴口罩,则进行语音提示。
在这里插入图片描述

2 实现步骤

基本思想为经过前景提取后得到人像前景,通过双眼检测得到眼部肤色面积和鼻子口部区域的肤色面积进行比较,若前者小于后者则为无口罩;若后者小于前者为戴口罩。另外加入嘴巴鼻子检测,和对戴口罩人脸的口罩边缘进行霍夫直线检测作为参考决策。

该软件系统的实现步骤为:图像采集和预处理——前景提取——人脸检测——眼睛、鼻子、嘴巴检测——眼部区域肤色面积统计——鼻口部区域肤色检测和霍夫直线检测。
在这里插入图片描述

2.1 图像采集和预处理

1)电脑前置摄像头采集。

import cv2 

if __name__ == '__main__' :
	#0是代表摄像头编号,只有一个的话默认为0
	#绝对路径用\,相对路径用/
	#capture=cv.VideoCapture(“images/vtest.avi”) #路径则为打开视频
    capture=cv2.VideoCapture(0) 
    while(True):
        ok,frame=capture.read()
        if not ok:
            print('Cannot read video file')
            break
        cv2.imshow("live",frame)
		#等待30ms显示图像,若过程中按“Esc”退出
        c= cv2.waitKey(30) & 0xff 
        if c==27:
            capture.release()
            break
            
    cv2.waitKey()
    cv2.destroyAllWindows()

2)预处理运用到以下几点:

高斯滤波,用于消除高斯噪声。

灰度处理,RGB三通道图片转化为灰度值0-255单通道的灰度图片,作用为提高运算速度。

二值化,对灰度图片按照阈值划分为只有0和255的黑白图片。

腐蚀和膨胀,腐蚀,分离距离近的目标。膨胀,填补目标空洞,连通距离相近目标。
在这里插入图片描述
开运算去噪,开运算即先腐蚀运算,再膨胀运算,能够分离细微连接目标,去除噪点。

像基本运算中逻辑与运算,图像存储也是一个特殊矩阵,可进行逻辑运算。

边缘检测,提取图像边缘。Canny 边缘检测算子边缘化效果。

在这里插入图片描述

转换颜色空间为HSV作为肤色检测,由于HSV把颜色分离为一个通道,即色调通道,通过此通道作为肤色检测更加稳定。HSV颜色空间分为色调(H),饱和度(S),明度(V),肤色的色调范围有论文数据:H∈[34°,50°]

提取人脸肤色如下图:
在这里插入图片描述
HSV颜色空间显示如下:
在这里插入图片描述
相关OpenCV函数:

image=cv2.GaussianBlur(image,(5,5),0) # 高斯滤波

element = cv2.getStructuringElement(cv2.MORPH_CROSS, (25, 25)) # 形态学去噪
gmask = cv2.morphologyEx(frame, cv2.MORPH_CLOSE, element) # 开运算去噪图

frame = cv2.bitwise_and(frame, frame, mask=erode)#与操作
hsv=cv2.cvtColor(image,cv2.COLOR_BGR2HSV)#将图片转化成HSV格式
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)#将图片转化成灰度
dilate = cv2.dilate(fgmask, None, iterations=13)#膨胀
erode = cv2.erode(dilate, None, iterations=1)# 腐蚀
ret,fgmask=cv2.threshold(fgmask, 60, 255, cv2.THRESH_BINARY)#二值化

2.2 前景运动目标提取

本系统所感兴趣的图像区域是人的面部区域。如果在整幅视频图像中进行人脸的检测无疑会大大增加算法的搜索范围和时间。所以在预处理中需要进行前景提取。

目标检测的目的是尽可能地将用户感兴趣的目标清晰、完整地从视频序列中提取出来,并将检测的结果提交给更高层次的视觉算法做进一步的分析处理,如目标跟踪等。
在这里插入图片描述

检测方法主要有几种:背景差分法,帧间差法,三帧差法,基于帧间差法思想改进的背景差分法、光流法(运算量较大)和高斯背景建模。

1)背景差分法: 将当前图片与背景图差分,阈值化后得到前景,本文采用背景差分法实现,流程如下:

在这里插入图片描述
当背景颜色和前景部分颜色相似时和背景光线变换时,造成比较多的空洞和误判。
在这里插入图片描述

可改进为,而阈值现在为手动给定,后期可改为自适应阈值。
在这里插入图片描述
2)高斯背景建模的: 在OpenCV库中,提供了三种基于高斯背景建模的算法:

  • BackgroundSubtractorMOG,混合高斯模型为基础的前景/背景分割算法,使用存在时间的长短作为混合的权重,因为背景像素存在时间长,前景时间短;
  • BackgroundSubtractorMOG2,混合高斯模型为基础的前景/背景分割算法,可以选择是否检测阴影,detectShadows = True(默认值),它就会检测并将影子以灰色标记出来。
    BackgroundSubtractorGMG,结合了静态背景图像估计和每个像素的贝叶斯分割。
    在这里插入图片描述
    存在问题,当物体不动时,这些算法会把物体也当作背景。

图像后处理
检测到运动物体后,进行开运算去噪、查找轮廓以通过面积过滤干扰目标,并查找轮廓的最小封闭矩形。

OpenCV相关函数:
mog = cv2.createBackgroundSubtractorMOG2()#混合高斯实例化
fgmask = mog.apply(frame)#对frame进行运动运动目标检测

contours, hierarchy = cv2.findContours(erode.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #查找轮廓
cv2.drawContours(frame,contours,-1,(0,0,255),3) #画出轮廓

rect = cv2.boundingRect(cont) #提取矩形坐标

见下。

2.4 眼镜、鼻子、嘴巴检测

采用Opencv的分类器即可,注意xml文件路径。通过例程可以看到添加实例化分类器就可同时进行人脸,鼻子,嘴巴的检测。可在官方OpenCV附加库中获取鼻子和嘴巴的xml训练文件,可通过git单文件下载工具下载:https://minhaskamal.github.io/DownGit/#/home。

haarcascade_mcs_nose.xml
haarcascade_mcs_mouth.xml

############################人脸\眼睛\上半身 视频检测
import cv2
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_alt2.xml")
face_cascade.load("data/haarcascades/haarcascade_frontalface_alt2.xml")#一定要告诉编译器文件所在的具体位置
'''此文件是opencv的haar人脸特征分类器'''
eyes_cascade = cv2.CascadeClassifier("haarcascade_eye_tree_eyeglasses.xml")
eyes_cascade.load("data/haarcascades/haarcascade_eye_tree_eyeglasses.xml")#一定要告诉编译器文件所在的具体位置
'''此文件是opencv的haar眼镜特征分类器'''

capture=cv2.VideoCapture(0) 
while(True):
    ref,frame=capture.read()
 
    #cv2.imshow("frame",frame)
    #等待30ms显示图像,若过程中按“Esc”退出
    c= cv2.waitKey(30) & 0xff 
    if c==27:
        capture.release()
        break
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)#将图片转化成灰度
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)
    eyes = eyes_cascade.detectMultiScale(gray, 1.3, 5)
    for (x,y,w,h) in faces:
        frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
    for (x,y,w,h) in eyes:
        frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
cv.waitKey()
cv.destroyAllWindows()

2.5 眼部肤色区域面积统计

目前当双眼检测到后得到眼部肤色区域,通过查找此感兴区内肤色轮廓计算肤色面积。

2.6 鼻口部区域肤色统计

确定眼部区域后,在眼部区域下面长度一样,高度为眼部两倍为鼻口区域,通过查找此感兴区肤色轮廓计算面积。

通过双眼检测得到眼部肤色面积和鼻子口部区域的肤色面积进行比较,若前者小于后者则为无口罩;若后者小于前者为戴口罩。

if total_area_eyes<total_area_mask:
    print("------------无口罩")
if total_area_eyes>total_area_mask:
    print("------------------戴口罩")
3 实验

无口罩:
在这里插入图片描述
有口罩:
在这里插入图片描述
目前体验感不够好,需要改进。

在这里插入图片描述

第九天:

人脸这些分类器是比较耗时的,导致帧率比较低。去除鼻子,嘴巴,人脸检测的分类器,只留下眼部检测,在未前景分离时,可以达到帧率在14fps。如下图
在这里插入图片描述
通过背景差分法分离前景并不理想,前景提取依然是瓶颈,如下图
在这里插入图片描述
采用改进后的背景差分法&帧间差分法,前景提取也不行。
在这里插入图片描述
引用文献:
[1]新京报.雪后天安门广场游客留言:“中国加油”“武汉加油”[EB/OL].http://m.sohu.com/a/371049490_114988,2020-02-06.
[2]新明晚报.视频|红外测体温、刷脸买口罩……上海这个小区防控有点“高科技”[EB/OL].https://baijiahao.baidu.com/s?id=1657691648870932604&wfr=spider&for=pc,2020-02-05.

[3]李丹丹. 铁路轨道异物入侵的智能识别研究[D].兰州交通大学,2016.

[4]王艳红. 基于OpenCV的运动目标检测与跟踪算法的研究[D].杭州电子科技大学,2014.

[5]周维. 视频监控中运动目标发现与跟踪算法研究[D].中国科学技术大学,2012.

[6]陈星明. 基于背景建模的运动目标监控视频检测算法[D].南京大学,2015.

【武汉加油!中国加油!】挑战七天 实现机器视觉检测有没有戴口罩系统——第一二三天

【武汉加油!中国加油!】挑战七天 实现机器视觉检测有没有戴口罩系统——第四五六七天

【B站视频】:在家无聊写了一个视觉检测戴口罩程序,基于OpenCV和Python的戴口罩检测程序

后话:

源码以及数据集分享
写得粗糙,给大家做下参考吧。

方向不当,努力白干,个人认为还是得机器学习来做。另外给大家分享一下自己弄得数据集,有分类和检测的,可以到百度EasyDL平台入门学习一下机器学习,今天2020年2月12日开始有直播课,不过看先前的视频教程https://ai.baidu.com/support/video也是可以的
在这里插入图片描述
源码分享
链接:https://pan.baidu.com/s/1ugC9MBZGlLlWkYPq2YUkQw
提取码:asgq

数据集
百度云盘链接: https://pan.baidu.com/s/1gBi9LuqqzD86v2RYPo9M8A 提取码: yjss
坚果云:https://www.jianguoyun.com/p/DSCCo18QpM-KCBi_09gC (访问密码:fPS0sC)

Logo

为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。

更多推荐