基于PaddleHub开发一款学生口罩佩戴情况检测登记系统

PaddleHub介绍

PaddleHub是由百度推出的国产深度学习框架——“飞桨” 预训练模型管理和迁移学习工具,通过PaddleHub开发者可以使用高质量的预训练模型结合Fine-tune API快速完成迁移学习到应用部署的全流程工作。其提供了飞桨生态下的高质量预训练模型,涵盖了图像分类、目标检测、词法分析、语义模型、情感分析、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型。更多模型详情请查看官网:https://www.paddlepaddle.org.cn/hub

基于预训练模型,PaddleHub支持以下功能:

1.模型即软件,通过Python API或命令行实现快速预测,更方便地使用PaddlePaddle模型库。
2.迁移学习,用户通过Fine-tune API,只需要少量代码即可完成自然语言处理和计算机视觉场景的深度 迁移学习。
3.服务化部署,简单一行命令即可搭建属于自己的模型的API服务。
4.超参优化,自动搜索最优超参,得到更好的模型效果。

通过PaddleHub,利用PaddleHub提供的的高质量的预训练模型(涵盖图像分类、目标检测、词法分析、语义模型、情感分析、视频分类、图像生成、图像分割、文本审核、关键点检测等主流模型)你可以方便地进行迁移学习,训练自己的模型,将自己的模型应用到各个场景,部署到移动端,服务器端等等。更多教程详情请查看飞桨官网和官方课程https://aistudio.baidu.com/aistudio/education/group/info/1070

下面,本文将介绍如何利用PaddleHub的预训练模型:口罩检测 来开发一款学生口罩佩戴情况检测登记系统

首先要做的是安装飞桨模块和PaddleHub
paddle安装教程https://www.paddlepaddle.org.cn/documentation/docs/zh/1.7/install/index_cn.html

然后安装PaddleHub:

pip install paddlehub

安装完成后,先来测试一下PaddleHub对单张图片的预测过程和结果:
导入paddlehub模块:

import paddlehub as hub
import cv2

1.准备待测图片:

ima = cv2.imread('D:\\kz2.jpg')
image = cv2.resize(ima,(320,240))

在这里插入图片描述
2.加载paddlehub口罩预训练模型:

PaddleHub口罩检测提供了两种预训练模型,pyramidbox_lite_mobile_mask和pyramidbox_lite_server_mask。二者均是基于2018年百度发表于计算机视觉顶级会议ECCV 2018的论文PyramidBox而研发的轻量级模型,模型基于主干网络FaceBoxes,对于光照、口罩遮挡、表情变化、尺度变化等常见问题具有很强的鲁棒性。不同点在于,pyramidbox_lite_mobile_mask是针对于移动端优化过的模型,适合部署于移动端或者边缘检测等算力受限的设备上。

module = hub.Module(name="pyramidbox_lite_mobile_mask")

准备预测的数据:

input_dict = {"data": [image]}
#或者input_dict = {"image": image_filepath},两种方式均可

3.进行口罩检测:

# 口罩检测预测,module.face_detection(data=input_dict)返回图片的预测结果
results = module.face_detection(data=input_dict)

4.展示预测结果:

result = results[0]#由于只输入了一张图片,batch_size 为1,所以results只有一个元素
for item in result['data']:#将人脸标注框出来
    x1 = item['left']
    y1 = item['top']
    x2 = item['right']
    y2 = item['bottom']
    kz = item['label']

    image = cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
    #并在图片上显示口罩佩戴情况
    cv2.putText(image, kz, (x1 - 5, y1 - 10), cv2.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 255), 1)
GrayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
draw_1 = cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.imshow("draw_0", draw_1)  # 显示画过矩形框的图片
cv2.waitKey(0)
cv2.destroyWindow("draw_0")

在这里插入图片描述
以上就是预测一张图片的过程,接下来我们将利用PaddleHub开发一个简单的视频检测口罩佩戴情况的GUI界面

主要功能:输入学生信息,然后打开摄像头检测是否佩佩戴口罩,并记录佩戴信息,然后可导出信息登记文件

首先,主窗体界面设计:

import time
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(1000, 800)

        self.label5 = QtWidgets.QLabel(Form)
        self.label5.setGeometry(QtCore.QRect(0, 240, 1000, 560))
        self.label5.setObjectName("label5")
        self.label5.setStyleSheet(
            '''QLabel{background:#76789E}''')



        '''tableView设计'''
        self.tableView = QtWidgets.QTableView(Form)
        self.tableView.setGeometry(QtCore.QRect(180, 290, 820, 510))
        self.tableView.setObjectName("tableView")
        # 设置数据层次结构,可指定n行n列,传入(n,n)即可
        self.model = QtGui.QStandardItemModel()
        # 设置水平方向五个个头标签文本内容
        self.model.setHorizontalHeaderLabels(['姓名', '学号', '学院', '口罩佩戴情况','日期'])
        self.tableView.setModel(self.model)
        # 水平方向标签拓展剩下的窗口部分,填满表格
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        #设计tableView的样式
        self.tableView.setStyleSheet(
            '''QTableView{
                    border:1px solid #74E9FF;
                    border-radius:10px;
                    padding:2px 4px;
            }''')
        self.tableView.horizontalHeader().setStyleSheet("QHeaderView::section{background:#87C9FF;}")#设置表头颜色
        self.tableView.horizontalHeader().setSectionsClickable(False)#设置表头不可被点击
        self.tableView.verticalHeader().setSectionsClickable(False)#设置表头不可被点击
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)#设置不可编辑
        #初始化时添加一个样例
        self.model.appendRow([
            QtGui.QStandardItem('林xx'),
            QtGui.QStandardItem('U2018XXXXX'),
            QtGui.QStandardItem('人工智能与自动化学院'),
            QtGui.QStandardItem('未戴口罩'),
            QtGui.QStandardItem(time.strftime('%Y.%m.%d', time.localtime(time.time()))),
        ])
        '''tableView设计结束'''



        '''LineEdit输入框设计'''
        self.name = QtWidgets.QLineEdit(Form)
        self.name.setGeometry(QtCore.QRect(40, 430, 100, 28))
        self.name.setObjectName("name")
        self.name.setPlaceholderText("输入姓名")

        self.ID = QtWidgets.QLineEdit(Form)
        self.ID.setGeometry(QtCore.QRect(40, 490, 100, 28))
        self.ID.setObjectName("ID")
        self.ID.setPlaceholderText("输入学号")

        self.xueyuan = QtWidgets.QLineEdit(Form)
        self.xueyuan.setGeometry(QtCore.QRect(40, 550, 100, 28))
        self.xueyuan.setObjectName("xueyuan")
        self.xueyuan.setPlaceholderText("输入学院")

        self.name.setStyleSheet(
            '''QLineEdit{
                    border:1px solid gray;
                    width:300px;
                    border-radius:10px;
                    padding:2px 4px;
            }''')
        self.ID.setStyleSheet(
            '''QLineEdit{
                    border:1px solid gray;
                    width:300px;
                    border-radius:10px;
                    padding:2px 4px;
            }''')
        self.xueyuan.setStyleSheet(
            '''QLineEdit{
                    border:1px solid gray;
                    width:300px;
                    border-radius:10px;
                    padding:2px 4px;
            }''')

        '''LineEdit输入框设计结束'''

        '''QLabel设计'''
        self.labelplay = QtWidgets.QLabel(Form)
        self.labelplay.setGeometry(QtCore.QRect(0, 0, 320, 240))
        self.labelplay.setObjectName("labelplay")
        self.labeldete = QtWidgets.QLabel(Form)
        self.labeldete.setGeometry(QtCore.QRect(680, 0, 320, 240))
        self.labeldete.setObjectName("labeldete")

        self.labelname = QtWidgets.QLabel(Form)
        self.labelname.setGeometry(QtCore.QRect(5, 430, 30, 28))
        self.labelname.setObjectName("labelname")
        self.labelid = QtWidgets.QLabel(Form)
        self.labelid.setGeometry(QtCore.QRect(5, 490, 30, 28))
        self.labelid.setObjectName("labelid")
        self.labelxy = QtWidgets.QLabel(Form)
        self.labelxy.setGeometry(QtCore.QRect(5, 550, 30, 28))
        self.labelxy.setObjectName("labelxueyuan")

        self.labelinfo = QtWidgets.QLabel(Form)
        self.labelinfo.setGeometry(QtCore.QRect(180, 260, 300, 28))
        self.labelinfo.setObjectName("labelinfo")




        font = QtGui.QFont()
        font.setFamily("Algerian")
        font.setPointSize(16)

        self.labelpaddle = QtWidgets.QLabel(Form)
        self.labelpaddle.setGeometry(QtCore.QRect(320, 0, 360, 240))
        self.labelpaddle.setObjectName("labelpaddle")

        self.labell = QtWidgets.QLabel(Form)
        self.labell.setGeometry(QtCore.QRect(320, 0, 180, 30))
        self.labell.setObjectName("labell")
        self.labelr = QtWidgets.QLabel(Form)
        self.labelr.setGeometry(QtCore.QRect(500, 0, 180, 30))
        self.labelr.setObjectName("labell")


        self.labell.setFont(font)
        self.labelr.setFont(font)
        self.labell.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)       #文本显示位置
        self.labelr.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTop | QtCore.Qt.AlignTrailing) #文本显示位置

        self.labelplay.setStyleSheet(
            '''QLabel{
                    border:1px solid red;
            }''')
        self.labeldete.setStyleSheet(
            '''QLabel{
                    border:1px solid red;
            }''')
        self.labelpaddle.setStyleSheet(
            '''QLabel{
                    border:1px solid #E8B735;
            }''')
        self.labell.setStyleSheet("color:white")#设置字体颜色
        self.labelr.setStyleSheet("color:white")#设置字体颜色

        '''QLabel设计结束'''


        '''Button设计'''
        font = QtGui.QFont()
        font.setFamily("Algerian")
        font.setPointSize(12)
        self.play = QtWidgets.QPushButton(Form)
        self.play.setGeometry(QtCore.QRect(10, 260, 100, 28))
        self.play.setObjectName("play")
        self.dete = QtWidgets.QPushButton(Form)
        self.dete.setGeometry(QtCore.QRect(10, 310, 100, 28))
        self.dete.setObjectName("dete")
        self.quit = QtWidgets.QPushButton(Form)
        self.quit.setGeometry(QtCore.QRect(10, 360, 100, 28))
        self.quit.setObjectName("quit")
        self.daochu = QtWidgets.QPushButton(Form)
        self.daochu.setGeometry(QtCore.QRect(5, 650, 150, 28))
        self.daochu.setObjectName("daochu")

        self.play.setFont(font)
        self.dete.setFont(font)
        self.quit.setFont(font)
        #self.daochu.setFont(font)

        self.play.setStyleSheet(
            '''QPushButton{background:#87C9FF;border-radius:5px;}QPushButton:hover{background:blue;}''')
        self.dete.setStyleSheet(
            '''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')
        self.quit.setStyleSheet(
            '''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')
        self.daochu.setStyleSheet(
            '''QPushButton{background:#F4605F;border-radius:5px;}QPushButton:hover{background:red;}''')

        self.retranslateUi(Form)
        self.play.clicked.connect(Form.shoot_play)
        self.dete.clicked.connect(Form.frame_detect)
        self.quit.clicked.connect(Form.detect_quit)
        self.daochu.clicked.connect(Form.getinfo)
        QtCore.QMetaObject.connectSlotsByName(Form)
        '''Button设计结束'''

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "学生口罩检测登记系统(基于PaddleHub的口罩检测系统)"))
        self.labelplay.setText(_translate("Form", "TextLabel"))
        self.labeldete.setText(_translate("Form", "TextLabel"))
        self.labell.setText(_translate("Form", "摄像区"))
        self.labelr.setText(_translate("Form", "检测区"))
        self.labelname.setText(_translate("Form", "姓名"))
        self.labelid.setText(_translate("Form", "学号"))
        self.labelxy.setText(_translate("Form", "学院"))
        self.labelinfo.setText(_translate("Form", "学生口罩佩戴情况记录:"))
        self.labelpaddle.setText(_translate("Form", "paddle"))
        self.play.setText(_translate("Form", "开启摄像"))
        self.dete.setText(_translate("Form", "检测口罩"))
        self.quit.setText(_translate("Form", "结束检测"))
        self.daochu.setText(_translate("Form", "导出检测信息表"))

检测模块封装:

import paddlehub as hub
import cv2

def Mask_detect(image):
    state = '未戴口罩'
    module = hub.Module(name="pyramidbox_lite_mobile_mask")  # 加载paddlehub预训练模型
    input_dict = {"data": [image]}

    results = module.face_detection(data=input_dict)  # 口罩检测预测
    result = results[0]
    for item in result['data']:#paddlehub的口罩检测可以检测多张人脸,本项目默认每次视频中只出现一个学生,故for循环仅执行一次
        x1 = item['left']
        y1 = item['top']
        x2 = item['right']
        y2 = item['bottom']
        kz = item['label']

        image = cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
        cv2.putText(image, str(kz), (x1 - 5, y1 - 10), cv2.FONT_HERSHEY_COMPLEX, 1.0, (0, 0, 255), 1)
        if kz == 'MASK':
            state = '已戴口罩'

    return image,len(result['data']),state#返回检测结果,检测到人脸的个数,口罩佩戴情况

最后是检测系统逻辑功能设计:
视频检测当中用到了多线程QTread类

from form2 import Ui_Form
import numpy
import cv2
import csv
import sys, time
from detection import Mask_detect
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

class MyDesiger(QMainWindow, Ui_Form):
    def __init__(self, parent=None):
        super(MyDesiger, self).__init__(parent)
        self.setupUi(self)
        self.star_show()
        self.info = [["姓名","学号","学院","口罩佩戴情况","日期"]]
        self.VideoTimer = Video()
        self.VideoTimer.changePixmap.connect(self.setImage)
        self.VideoTimer.detectPixmap.connect(self.setDetect)
        self.VideoTimer.run_over.connect(self.finish_detect)
        self.VideoTimer.update_data.connect(self.add_data)

    def shoot_play(self):#摄像头展示
        if self.name.text()=='' or self.ID.text()=='' or self.xueyuan.text()=='':
            QMessageBox.information(self, '信息不完整', '请正确填写完整信息',QMessageBox.Yes)
        else:
            self.VideoTimer.working = True  # 使摄像和检测线程能工作
            self.VideoTimer.start()

    def frame_detect(self):#检测每一帧
        if self.VideoTimer.working:
            self.VideoTimer.setDetect()

    def detect_quit(self):#结束检测
        self.close()

    def getinfo(self):#导出文件
        with open('resource\\info.csv', 'w', newline='') as csvfile:
            writer = csv.writer(csvfile)
            for row in self.info:
                writer.writerow(row)
        QMessageBox.information(self, '导出成功', '文件保存路径为:resource\\info.csv', QMessageBox.Yes)


    def star_show(self):#初始化显示界面
        frame = QPixmap('resource\\sample.jpg').scaled(self.labelplay.width(), self.labelplay.height())
        self.labelplay.setPixmap(frame)
        image = QPixmap('resource\\sample_detection.jpg').scaled(self.labeldete.width(), self.labeldete.height())
        self.labeldete.setPixmap(image)
        paddlehub = QPixmap('resource\\paddlehub.png').scaled(self.labelpaddle.width(), self.labelpaddle.height())
        self.labelpaddle.setPixmap(paddlehub)

    def finish_detect(self,kz):#检测完毕
        self.star_show()
        QMessageBox.information(self, '检测结果:', kz+'!!', QMessageBox.Yes)
        self.name.clear()
        self.ID.clear()
        self.xueyuan.clear()



    def add_data(self,kz):#记录表信息更新
        self.model.appendRow([
            QStandardItem(self.name.text()),
            QStandardItem(self.ID.text()),
            QStandardItem(self.xueyuan.text()),
            QStandardItem(kz),
            QStandardItem(time.strftime('%Y.%m.%d',time.localtime(time.time()))),
        ])
        self.info.append([self.name.text(), self.ID.text(), self.xueyuan.text(),kz,time.strftime('%Y.%m.%d',time.localtime(time.time()))])



    def setImage(self, frame):
        self.labelplay.setPixmap(QPixmap.fromImage(QImage(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB),640/2,480/2,13)))

    def setDetect(self, image):
        self.labeldete.setPixmap(QPixmap.fromImage(QImage(cv2.cvtColor(image, cv2.COLOR_BGR2RGB),640/2,480/2,13)))


class Video(QThread):
    changePixmap = pyqtSignal(numpy.ndarray)
    detectPixmap = pyqtSignal(numpy.ndarray)
    update_data = pyqtSignal(str)
    run_over = pyqtSignal(str)

    def __init__(self):
        QThread.__init__(self)
        self.detect = False   #是否能检测
        self.working = False  #是否能工作
        self.count = 0        #检测到人脸的次数

    def run(self):
        cap = cv2.VideoCapture(0)
        while self.working:
            ret, frame = cap.read()
            frame = cv2.resize(frame,(320,240))
            self.changePixmap.emit(frame)
            if self.detect:
                img = frame.copy()
                detected_image,num,kz=Mask_detect(img)#口罩检测
                self.detectPixmap.emit(detected_image)
                if num > 0:
                    self.count += 1
            if self.count >= 6:#超过6帧检测到人脸就停止检测
                self.detect = False
                self.working = False
                self.count = 0  #计数清零
                self.run_over.emit(kz)
                self.update_data.emit(kz)
        cap.release()

    def setDetect(self):
        self.detect = True
    def setquit(self):
        self.detect = False
        self.working = False


if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = MyDesiger()
    ui.show()
    sys.exit(app.exec_())

结果展示:
在这里插入图片描述
本项目已上传至github
github项目地址
更好的阅读体验可以访问AI StudioAI Studio项目地址

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值