基于图像的口罩佩戴自动检测系统设计

一、前言

学校的一门综合设计,在此仅作学习记录,在此仅作学习记录!在此仅作学习记录!再不记录一下自己都忘掉了,同时希望看到的友友指出不足,共同进步,如果有的话吼吼吼吼吼~。

二、背景

  1. 2020 年初,新型冠状肺炎疫情爆发,研究表明佩戴口罩相对于不佩戴口罩的感染风险大大降低。
  2. 设计实现一种可以基于视频图像的口罩佩戴正确与否的自动检测系统具有重要意义。
  3. 虽然现在似乎好像应该大概是有亿点过时,但是问题不大,浅记一下。

三、设计目标

  1. 进行人脸检测,将人脸进行框选
  2. 进行人脸物理特征识别,框选眼睛、鼻子、嘴巴等人脸特征信息
  3. 进行口罩佩戴判断,利用以上特征信息,通过是否检测到相关特征进行口罩佩戴情况的判断,佩戴情况分成三种:未佩戴,正确佩戴,错误佩戴。

四、实现方法

1. 基于特征检测的方法(本文方法)

  1. 输入视频图像,获取图像帧
  2. 背景减除法分离运动前景,即移动的人,目的是缩小检测氛围。
  3. 肤色提取分离人脸。
  4. Haar特征级联分类器进行人脸检测和特征提取,并框选人脸和相关特征。
  5. 根据是否检测到眼睛、鼻子、嘴巴等特征进行口罩佩戴情况分类,给出警示信息。

2. 深度学习的方法 (底子薄,没用这个)

咱就是一小小本科生,当时才开始接触深度学习,深度学习底子薄,用深度学习感觉难度大,就没选择这种方案。现在还是建议采用深度学习,准确率高,速度快,用yolo系列可以直接一步到位。

五、实现源代码

# Project: zonghesheji
# author:@hong
# Time: 2022/12import numpy as np
import cv2 as cv
import random#face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
#读取面部识别分类器
face_cascade = cv.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
#读取嘴巴识别分类器
mouth_cascade = cv.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_mcs_mouth.xml')
#读取鼻子识别分类器
nose_cascade = cv.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_mcs_nose.xml')
#读取眼睛识别分类器
eye_cascade = cv.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_eye.xml')#二值化最小阈值
black_white_threshold = 80##初始化字体
font = cv.FONT_HERSHEY_SIMPLEX
#绘制字体框的大小
org = (30, 30)
#戴口罩字体颜色
weared_mask_font_color = (0, 255, 0)
#不戴口罩字体颜色
not_weared_mask_font_color = (0, 0, 255)
#错误佩戴口罩字体颜色
error_weared_mask_font_color = (30, 255, 255)noface = (255, 255, 255)
thickness = 2
font_scale = 1
weared_mask = "Thank You for wearing MASK"
not_weared_mask = "Please wear MASK to defeat Corona"
error_weared_mask="Please wear MASK correctly"def empty(a):pass# 更新背景照片
def getbackground():cap = cv.VideoCapture(0)num = 0while True:ok, frame = cap.read()image = cv.GaussianBlur(frame, (3, 3), 0)  # 高斯滤波# cv2.imshow("gauss",image)gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)  # 将图片转化成灰度num = num + 1if num == 10:backgound = graycv.imwrite("./backgound.jpg", backgound)cv.imshow("backgound", backgound)breakimage = cv.imread("./withmask.jpg")  # 读取初始照片
cv.imshow('orignal_image', image)  # 展示
#cv.createTrackbar("Hmin", "orignal_image", 0, 90, empty)  # 创建bar
#cv.createTrackbar("Hmax", "orignal_image", 25, 90, empty)#定义背景颜色
colour = ((0, 205, 205), (154, 250, 0), (34, 34, 178), (211, 0, 148), (255, 118, 72), (137, 137, 139))
#打开摄像头
cap = cv.VideoCapture(0)
history=200  #训练帧数
bs=cv.createBackgroundSubtractorKNN(detectShadows=False)  ##基于KNN的前景分割算法
#bs=cv.createBackgroundSubtractorMOG2(detectShadows=True)  ##基于MOG2的前景分割算法,速度比KNN快,但是质量没有LNN好,因此选择KNN算法
#bs=cv.createb(detectShadows=True)  ##基于KNN的前景分割算法    ##opencv库中没有GMG算法用于背景减除
bs.setHistory(history)
frames=0#前景分割算法的前提是要先拍摄一张环境图作为背景
getbackground()#保存背景
backgound=cv.imread("./backgound.jpg")
backgound=cv.cvtColor(backgound, cv.COLOR_BGR2GRAY)#将图片转化成灰度
gray=backgound #k-1张while True:gray_last=gray    #k-1张,方便后面考虑对比帧间差分法#cv.imshow("gray_last", gray)ret, img = cap.read()#镜像翻转img = cv.flip(img, 1)cv.imshow("orignal_image", img)      ##展示摄像头输入图像###肤色区域检测  Ycrcb法ycrcb = cv.cvtColor(img, cv.COLOR_BGR2YCR_CB)       #将BGR色彩空间图片转化到YCrCb色彩空间(y, cr, cb) = cv.split(ycrcb)            #分别提取cr1 = cv.GaussianBlur(cr, (5, 5), 0)     #高斯模糊去除高斯噪声,降低细节层次_, skin = cv.threshold(cr1, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)  #大津法(大阈值图像分割法)二值化处理#cv.imshow("image raw", img)#cv.imshow("image CR", cr1)cv.imshow("Skin Cr+OTSU", skin)dst = cv.bitwise_and(img, img, mask=skin)cv.imshow("seperate", dst)      #分离提取肤色区间####显示肤色区域  HSV法---效果很差"""""""""hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)    #将图片转化成HSV格式H, S, V = cv.split(hsv)Hmin = cv.getTrackbarPos("Hmin", 'orignal_image')  # 获取barHmax = cv.getTrackbarPos("Hmax", 'orignal_image')if Hmin > Hmax:Hmax = Hminthresh_h = cv.inRange(H, Hmin, Hmax)  # 提取人体肤色区域cv.imshow("thresh_h1", thresh_h)"""#高斯模糊去除噪声#img = cv.GaussianBlur(dst, (3, 3), 0)   ##检测不到人脸img = cv.GaussianBlur(img, (3, 3), 0)#cv.imshow("Gaussionblur", img)#转为灰度图像gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)cv.imshow("gray_image", gray)"""""""""### 背景差分处理fgmask1 = cv.absdiff(gray, backgound)  # 背景差分cv.imshow("fgmask1", fgmask1)### 帧间差分处理fgmask2 = cv.absdiff(gray, gray_last)  # 帧间差分法cv.imshow("fgmask2", fgmask2)###按比例而调节的改进差分法fgmask = cv.addWeighted(fgmask1, 0.3, fgmask2, 0.7, 0)  # 按比例相加,相当于差分均值cv.imshow("weight", fgmask)"""# 获取foreground mask 获取前景分割图fg_mask = bs.apply(img)         ##应用于前景掩模cv.imshow("foreground mask", fg_mask)if frames<history:frames+=1continue#图像二值化thresh, black_and_white= cv.threshold(fg_mask, 100, 255, cv.THRESH_BINARY)cv.imshow("threshold_image", black_and_white)""""""""""fgmask = cv.dilate(black_and_white, cv.getStructuringElement(cv.MORPH_ELLIPSE,(8,3)), iterations=8)  # 膨胀cv.imshow('dilate', fgmask)fgmask = cv.erode(fgmask, cv.getStructuringElement(cv.MORPH_ELLIPSE,(3,3)), iterations=5 )  # 腐蚀cv.imshow('erode', fgmask)"""""# 腐蚀fgmask = cv.erode(black_and_white, cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5)), iterations=1 )#cv.imshow('erode', fgmask)# 膨胀fgmask = cv.dilate(fgmask, cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5)), iterations=20)#cv.imshow('dilate', fgmask)# 形态学去噪element = cv.getStructuringElement(cv.MORPH_CROSS, (25, 25))# 开运算去噪fgmask = cv.morphologyEx(fgmask, cv.MORPH_CLOSE, element)#cv.imshow('kaiyunsuan', fgmask)# 寻找运动前景勾画轮廓contours, hierarchy = cv.findContours(fgmask.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)cv.drawContours(img, contours, -1, (0, 0, 255), 3)rect_array = []count = 0for cont in contours:Area = cv.contourArea(cont)  # 计算轮廓面积if Area < 1500:  # 过滤面积小于10的形状continuecount += 1  # 计数加一# print("{}-prospect:{}".format(count,Area),end="  ") #打印出每个前景的面积rect = cv.boundingRect(cont)  # 提取矩形坐标# rect_array.append(rect)# print("x:{} y:{}".format(rect[0],rect[1]))#打印坐标#cv.rectangle(img, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), colour[count % 6],1)  # 原图上绘制矩形cv.rectangle(fgmask, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (0xff, 0xff, 0xff), 1)  # 黑白前景上绘制矩形y = 10 if rect[1] < 10 else rect[1]  # 防止编号到图片之外cv.putText(img, str(count), (rect[0], y), cv.FONT_HERSHEY_COMPLEX, 0.4, (0, 255, 0), 1)  # 在前景上写上编号cv.putText(img, "count:", (5, 20), cv.FONT_HERSHEY_COMPLEX, 0.6, (0, 255, 0), 1)  # 显示总数cv.putText(img, str(count), (75, 20), cv.FONT_HERSHEY_COMPLEX, 0.6, (0, 255, 0), 1)# 勾画前景后展示图像# cv2.imshow("bitwise_and",fgmask)cv.imshow("findcont", img)#脸部检测,缩放系数1.1,4轮确定faces = face_cascade.detectMultiScale(gray, 1.1, 10, 0, (100, 100))faces_bw = face_cascade.detectMultiScale(black_and_white, 1.1, 10, 0, (100, 100))if len(faces) == 0 and len(faces_bw) == 0:cv.putText(img, "No face found...", org, font, font_scale, noface, thickness, cv.LINE_AA)elif len(faces) == 0 and len(faces_bw) == 1:cv.putText(img, weared_mask, org, font, font_scale, weared_mask_font_color, thickness, cv.LINE_AA)else:for (x, y, w, h) in faces:cv.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]##检测到鼻子并标记nose_rects = nose_cascade.detectMultiScale(gray,1.05,4,0,(50,50),(100,100))for (nx,ny,nw,nh) in nose_rects:cv.line(img,(int(nx+nw/2),ny),(int(nx+nw/2),int(ny+nh/2)),(0,255,0),2)##检测到眼睛并标记eyes_rects = eye_cascade.detectMultiScale(gray, 1.1, 3, 0, (50, 50),(100,100))for (ex,ey,ew,eh) in eyes_rects:cv.rectangle(img,(int(ex+ew/4),int(ey+eh/4)),(int(ex+ew*0.8),int(ey+eh*0.8)),(255,0,0),2)##检测到嘴巴并标记mouth_rects = mouth_cascade.detectMultiScale(gray,1.1,5,0,(80,80),(100,120))for (mx,my,mw,mh) in mouth_rects:cv.ellipse(img, (int(mx+mw/2), int(my+mh/2.5)), (int(mw/3),int(mh/3)),0,0,360,(0,0,255),1)##没有检测到鼻子也没有检测到嘴巴,则是戴好了口罩if (len(nose_rects) == 0 and len(mouth_rects)==0):cv.putText(img, weared_mask, org, font, font_scale, weared_mask_font_color, thickness, cv.LINE_AA)##只遮住了嘴巴或者只遮住了鼻子则是错误佩戴口罩elif ((len(nose_rects) == 1 and len(mouth_rects)==0)or(len(nose_rects) == 0 and len(mouth_rects)==1)):cv.putText(img, error_weared_mask, org, font, font_scale, error_weared_mask_font_color, thickness, cv.LINE_AA)##其它情况认为没有佩戴口罩(检测到鼻子也检测到了嘴巴)else:for (mx, my, mw, mh) in nose_rects:##对于鼻子在检测到人脸上,在多个人脸的情况if (y < my < y + h):cv.putText(img, not_weared_mask, org, font, font_scale, not_weared_mask_font_color, thickness,cv.LINE_AA)breakcv.imshow('Mask Detection', img)k = cv.waitKey(30) & 0xffif k == 27:breakcap.release()
cv.destroyAllWindows()

六、效果说明与总结

由于这个并不是采用深度学习的方法做的,在此强调!!!效果一般般!!!该方案适用于学习使用,对于现实中或者精度速度要求较高的,采用深度学习方法更好。演示图片设及本人,咱就不上传啦~
PS:后继有时间再选用其它视频检测后再更新展示图片~。
最后欢迎交流,good good study,day day up !

参考文献:

[1] https://blog.csdn.net/allway2/article/details/120831486
[2] https://blog.csdn.net/weixin_45224869/article/details/105275628
[3] https://blog.csdn.net/qq_42807924/article/details/104116361
[4] https://blog.csdn.net/weixin_44255592/article/details/89505450
[5] https://blog.csdn.net/drippingstone/article/details/116186462
[6] https://blog.csdn.net/qq_22527639/article/details/81501565
[7] https://blog.csdn.net/xss20072754/article/details/110147675
[8] https://blog.csdn.net(广大博友)

基于图像的口罩佩戴自动检测系统设计相关推荐

  1. 基于YOLOv5的口罩佩戴检测方法

    摘 要 正确的佩戴口罩对现阶段有效减低人员之间感染新型冠状病毒具有重要意义.基于YOLOv5在图像识别检测领域的优异性能,本文研究基于基于YOLOv5的口罩佩自动戴检测方法.首先从网络和真实生活中中寻 ...

  2. 基于YOLOv3的口罩佩戴检测

    摘 要 为解决市民口罩佩戴目标检测中因小尺寸目标较多导致其识别精度不高的问题,提出一种基于 YOLOv3改进的算法 M_YOLOv3.重构特征金字塔机制,把原本3*3的类金字塔结构扩建为4*4尺寸,把 ...

  3. 基于诱捕器图像的飞蛾害虫自动检测

    ABSTRACT 在以信息素为基础的害虫管理系统中,监测害虫数量是一个至关重要的组成部分.在本文中,我们提出了一种基于深度学习的自动检测管道,用于识别和计数田间诱捕器内拍摄的图像中的害虫.将该方法应用 ...

  4. (毕业设计资料)基于51单片机控制的自动浇水系统设计

    功能描述: 本次毕业设计是设计一种51单片机控制的自动浇水系统,实现室内盆花浇水的自动化系统.该系统可对土壤的湿度进行监控,并对作物进行适时适量的浇水.其核心是51单片机和土壤湿度检测器YL-69和显 ...

  5. 两个一样的图像相除会怎么样_【壮凌自动化分析】一种动力电池生产中基于图像运动模糊的速度检测方法...

    一种动力电池生产中基于图像运动模糊的速度检测方法 1.西南大学 电子信息工程学院,重庆 400715) 2.非线性电路与智能信息处理重庆市重点实验室,重庆 400715) 1.当前背景与成熟方法介绍 ...

  6. 基于温湿度和烟雾传感器的火灾检测系统设计

    基于温湿度和烟雾传感器的火灾检测系统设计 一.硬件介绍 1.单片机STM32F103ZET6 2.MQ-2烟雾传感器 3.DHT11数字温湿度传感器 4.高电平触发有源蜂鸣器模块 5.ESP8266 ...

  7. 基于YOLOv5s 的口罩佩戴检测

    现阶段新冠肺炎疫情虽然已经放开,但是我们仍不能放松警惕,因此口罩的佩戴极其重要.针对这一现象,笔者提出了基于YOLOv5s的检测是否佩戴口罩.采用了 YOLOv5s.YOLOv3和YOLOv4检测算法 ...

  8. 烟花视频软件测试,基于视频分析的烟火自动检测预警系统

    基于视频分析的室内.室外烟火自动检测预警系统的目的是能够实现无人值守的不间断工作,自动发现监控区域内的异常烟雾和火灾苗头,以最快.最佳的方式进行告警和协助消防人员处理火灾危机,并最大限度的降低误报和漏 ...

  9. 基于机器视觉的洋葱霜霉病症状自动检测

    1.研究思想 提出了一种基于图像的田间自动监测系统,包括构建田间监测系统,定期采集洋葱田间图像,训练深层神经网络模型,检测病害症状,并对系统性能进行评估.现场监控系统由PTZ摄像机.电机系统.无线收发 ...

最新文章

  1. Mysql使用binlog恢复数据解决误操作问题的两种方法
  2. OS X终端颜色[关闭]
  3. Adobe Flash Builder 4.6 开发环境详解
  4. 业界 | 复杂出行场景下,滴滴如何将AI融入地图系统
  5. Dubbo Mesh | 阿里巴巴中间件团队在 Service Mesh 的实践和探索(附PPT)
  6. 按钮3D分层悬停效果
  7. LeetCode 117. 填充每个节点的下一个右侧节点指针 II
  8. python制作一个简单的udp聊天器
  9. 祝心想事成无Bug,1024快乐!
  10. 配置pytoch版人脸关键点网络pfld docker环境
  11. html网页对账单样式,结算对账单.html
  12. itextword加公章 java_新手如何使用itext7生成pdf盖章
  13. 七夕送你最特别的礼物 限时竞拍咯~
  14. UIView相对坐标转换
  15. EasyPoi的简介
  16. IT十年人生过客-十六-再见雍和宫
  17. [爬虫] 上海大学自动抢课工具
  18. STM32CubeMX | HAL库的ADC多通道数据采集(轮训、DMA、DMA+TIM)、读取内部传感器温度
  19. PostgreSQL之Array_to_String用法
  20. python-双均线系统-参数优化

热门文章

  1. sql中nvl和nvl2的区别
  2. TYD深度学习入门 第二章
  3. Oracle ASSM
  4. 常见的内联元素(inline)和块级元素(block)
  5. Halcon 字符识别(初级)(0-9_A-z)
  6. 鸢尾花数据集可视化分析
  7. respond_to的解释
  8. html表单设置单选框,html如何实现表单的选择框效果?单选框与多选框的实现(代码实例)...
  9. 多账号管理如何进行有效运营
  10. 启明的MACD十大形态技战法6-10