Python实现人脸口罩检测!这玩意太强大了啊!

由于疫情的影响,人脸口罩检测系统的开发成为很多人争相开发的一种算法。很多公司或者个人都开源了他们很多的代码或者SDK。大家在GitHub或者各种平台上都能够找到很多的资源。 前段时间在博客上看到几个有趣的开源项目,它能检测我们是否有戴口罩,跑起程序测试后,发现识别率挺高的,也适应不同环境;于是分享给大家。我用了其中两种并整合在一个GUI下面,一种是基于深度学习的,一种是基于opencv训练的。

测试环境

windows10 系统; 软件:pyCharm; 使用模型:tenforflow1.15.0 ; python3.7

下面先看一下整个系统的GUI界面:

GUI程序:

from tkinter import *
from tkinter.filedialog import askdirectory
from tkinter.messagebox import showinfo
import cv2
import numpy as np
from PIL import Image, ImageTk
from tkinter import ttk
import pygame
import time

import tensorflow_infer as flow

file_slogan = r'video/slogan.mp3'
file_slogan_short = r'video/slogan_short.mp3'
pygame.mixer.init(frequency=16000, size=-16, channels=2, buffer=4096)

detector = cv2.CascadeClassifier('haarcascades\\haarcascade_frontalface_default.xml')
mask_detector = cv2.CascadeClassifier('xml\\cascade.xml')

class GUI:
    def __init__(self):
        self.camera = None   # 摄像头
        self.root = Tk()
        self.root.title('maskdetection')
        self.root.geometry('%dx%d' % (800, 600))
        self.createFirstPage()
        mainloop()

    def createFirstPage(self):
        self.page1 = Frame(self.root)
        self.page1.pack()
        Label(self.page1, text='欢迎使用口罩检测跟踪系统', font=('粗体', 20)).pack()
        image = Image.open("demo2.jpg") # 随便使用一张图片做背景界面 不要太大
        photo = ImageTk.PhotoImage(image = image)
        self.data1 = Label(self.page1,  width=780,image = photo)
        self.data1.image = photo
        self.data1.pack(padx=5, pady=5)

        self.button11 = Button(self.page1, width=18, height=2, text="深度学习算法", bg='red', font=("宋", 12),
                               relief='raise',command = self.createSecondPage1)
        self.button11.pack(side=LEFT, padx=25, pady = 10)
        self.button12 = Button(self.page1, width=18, height=2, text="传统算法", bg='green', font=("宋", 12),
                               relief='raise', command = self.createSecondPage)
        self.button12.pack(side=LEFT, padx=25, pady = 10)
        self.button13 = Button(self.page1, width=18, height=2, text="打开本地视频", bg='white', font=("宋", 12), relief='raise',
                               command = self.select_path)
        self.button13.pack(side=LEFT, padx=25, pady = 10)
        self.button14 = Button(self.page1, width=18, height=2, text="退出系统", bg='gray', font=("宋", 12),
                               relief='raise',command = self.quitMain)
        self.button14.pack(side=LEFT, padx=25, pady = 10)

    def createSecondPage1(self):
        self.camera = cv2.VideoCapture(0)
        self.page1.pack_forget()
        self.page2 = Frame(self.root)
        self.page2.pack()
        Label(self.page2, text='欢迎使用口罩检测跟踪系统', font=('粗体', 20)).pack()
        self.data2 = Label(self.page2)
        self.data2.pack(padx=5, pady=5)

        self.button21 = Button(self.page2, width=18, height=2, text="返回", bg='gray', font=("宋", 12),
                               relief='raise',command = self.backFirst)
        self.button21.pack(padx=25,pady = 10)
        self.video_loop1(self.data2)

    def video_loop1(self, panela):
        def slogan_short():

            timeplay = 1.5
            global playflag_short
            playflag_short = 1
            while playflag_short:
                track = pygame.mixer.music.load(file_slogan_short)
                print("------------请您戴好口罩")
                pygame.mixer.music.play()
                time.sleep(timeplay)
                playflag_short = 0
            time.sleep(0)

        success, img = self.camera.read()  # 从摄像头读取照片

        if success:

            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            num,c,img = flow.inference(img, conf_thresh=0.5, iou_thresh=0.4, target_shape=(260, 260), draw_result=True,
                                   show_result=False)
            # 语音提示
            # if(isinstance(num/5,int)& (c=='NoMask')):
                # slogan_short()

            # cv2.imshow('image', img)
            # img = flow.inference(img, show_result=True, target_shape=(260, 260))
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

            cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)  # 转换颜色从BGR到RGBA
            current_image = Image.fromarray(cv2image)  # 将图像转换成Image对象
            imgtk = ImageTk.PhotoImage(image=current_image)
            panela.imgtk = imgtk
            panela.config(image=imgtk)
            self.root.after(1, lambda: self.video_loop1(panela))


    def select_path(self):
        self.pash_= askdirectory()
        path = StringVar()
        path.set(self.pash_)

    def createSecondPage(self):
        self.camera = cv2.VideoCapture(0)
        self.page1.pack_forget()
        self.page2 = Frame(self.root)
        self.page2.pack()
        Label(self.page2, text='欢迎使用口罩检测跟踪系统', font=('粗体', 20)).pack()
        self.data2 = Label(self.page2)
        self.data2.pack(padx=5, pady=5)

        self.button21 = Button(self.page2, width=18, height=2, text="返回", bg='gray', font=("宋", 12),
                               relief='raise',command = self.backFirst)
        self.button21.pack(padx=25,pady = 10)
        self.video_loop(self.data2)

    def video_loop(self, panela):


        success, img = self.camera.read()  # 从摄像头读取照片
        if success:
            faces = detector.detectMultiScale(img, 1.1, 3)
            for (x, y, w, h) in faces:
                # 参数分别为 图片、左上角坐标,右下角坐标,颜色,厚度
                face = img[y:y + h, x:x + w]  # 裁剪坐标为[y0:y1, x0:x1]
                mask_face = mask_detector.detectMultiScale(img, 1.1, 5)
                for (x2, y2, w2, h2) in mask_face:
                    cv2.putText(img, 'mask', (x2 - 2, y2 - 2),
                                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255))
                    cv2.rectangle(img, (x2, y2), (x2 + w2, y2 + h2), (0, 0, 255), 2)


            #img = mask.facesdetecter(img)
            cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)  # 转换颜色从BGR到RGBA

            #faces = detector.detectMultiScale(cv2image, 1.1, 3)
            current_image = Image.fromarray(cv2image)  # 将图像转换成Image对象
            imgtk = ImageTk.PhotoImage(image=current_image)
            panela.imgtk = imgtk
            panela.config(image=imgtk)
            self.root.after(1, lambda: self.video_loop(panela))




    def backFirst(self):
        self.page2.pack_forget()
        self.page1.pack()
        # 释放摄像头资源
        self.camera.release()
        cv2.destroyAllWindows()

    def backMain(self):
        self.root.geometry('900x600')
        self.page3.pack_forget()
        self.page1.pack()

    def quitMain(self):
        sys.exit(0)





if __name__ == '__main__':

    demo = GUI()




1.深度学习的效果:

检测出胡歌没有带口罩。红色框框是圈出人脸部分,上方的字体:NoMask ,准确率 1 (即有100%把握认为没带口罩)

如果在多人的情况下,能检测出来吗?

 

这个模型能同时检测多人的,并且准确高。以上是基于照片的。

下面是基于GUI打开摄像头的,有无口罩的对比:

 

这个深度学习的项目完全开源,可以自己先到网页上去体验一波:

https://demo.aizoo.com/face-mask-detection.html

深度学习开源项目简单介绍:

1)支持5大主流深度学习框架(PyTorch、TensorFlow、MXNet、Keras和Caffe),已经写好接口了;可以根据自身的环境选择合适的框架,比如:TensorFlow;所有模型都在models文件夹下。

2)公开了进8000张的人脸口罩数据和模型,数据集来自于WIDER Face和MAFA数据集, 重新修改了标注并进行了校验(主要是 MAFA和WIDER Face的人脸位置定义不一样,所以进行了修改标注)并将其开源出来。

 

2.基于Opencv的口罩佩戴识别

注:这个方法只能检测有口罩的,无口罩就没法检测,不给任何提示或者标注。

看看有口罩的效果:

 

演示视频视频好像还不支持。故这里不放演示视频了。需要这两种方法完整的源代码都可以去下面的地址找到:

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

python免费学习资料以及群交流解答点击即可加入

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值