2021年大数据挑战赛B题口罩佩戴检测求解全过程论文及程序

news2024/12/26 0:30:49

2021年大数据挑战赛

B题 口罩佩戴检测

原题再现:

  新冠疫情的爆发对人类生命安全及全球经济发展造成了重大影响。虽然现在国内疫情基本得到有效遏制,但日常防控仍不可松懈。戴口罩是预防新冠肺炎最便捷、最有效的措施和方法。人脸佩戴口罩的自动化识别可以有效检测人群佩戴口罩情况,是抑制疾病在人流量大的公共场合快速传播和保护身体健康的重要技术手段。
  图 1 中,每个方框(包围盒)框选出一张人脸,不同的方框颜色用于区分是否佩戴口罩。
在这里插入图片描述
  附件 1 训练样本中包含 train_images 和 train_anotations 两个文件夹,分别提供了 653 张图片和对应的标签信息,请你查阅相关文献,回答以下问题。
  问题 1: 每个标签文件(xml 格式)中,记录了相应图片中所包含人脸信息。见图 2,以标签文件 250.xml 为例,每个元素代表一张人脸,表示该人脸处于“佩戴口罩/未佩戴口罩/未正确佩戴口罩”的其中一种状态。则记录了该人脸的包围盒的左上、右下两个顶点的坐标。你的任务是用程序(建议 Python 软件,其他软件也可以自行选用)读取 xml 中保存的数据,并参考图 1 的方式将人脸框和口罩佩戴状态进行展示,论文中重点展示“250.png” 和“477.png”这两张图片。
  问题 2: 运用 653 张图片和对应的标签信息,设计人脸口罩检测算法,检测任意一张图片中存在的人脸的位置和口罩佩戴情况,并对你的算法进行校验。量化指标为 <被正确分类的人脸的数量>/<标签文件中包含的所有人脸数量>。对某张人脸来说,当且仅当 IoU 大于 0.45 时,才被认为被正确分类。
  问题 3: 使用检测算法对“附件 2 测试样本”文件夹下 test_images 中包含的图片进行检测,并将检测结果汇总填写到“赛题 B 提交结果.xlsx”表格中,单独上传到竞赛平台。所有图片的标记文件需要放到项目源文件中上传。

整体求解过程概述(摘要)

  新冠疫情在全球的蔓延,危害着全球 70 多亿人口的生命财产安全,虽然我国的疫情已经总体得到遏制,但国外疫情依旧严重,由于境外输入导致的小规模新冠疫情在我国时常发生。目前我国要求人员在乘坐火车、地铁等公共交通工具,和出入商场、医院等人员聚集场所时必须佩戴口罩。针对人员是否佩戴口罩,现在采用的主要方式是人工查看,在固定的出入口配备检查人员,这种方式不具有全天性,且在人群大流量流通区域容易出现漏检的情况,这样给防疫安全工作带来了很大的隐患,因此实现人脸口罩的自动化识别就能解决这些问题,有效的检测人群佩戴口罩的情况,给我国的防疫工作智能化做出贡献,抑制新冠疫情在我国的传播,保护人民群众的生命安全。
  对于问题一,通过分析标签文件,理解标签文件中包含的对应图片尺寸、人脸坐标信息,以及人脸佩戴口罩情况,将标签信息在对应的图片上可视化。选用 Python 语言结合 OpenCV 包编写程序,对于“佩戴口罩、未佩戴口罩、未正确佩戴口罩”三种情况,分别选用黄、红、绿三种目标框进行框选,并且在方框的下方显相应的人脸佩戴口罩情况“with_mask、without_mask、mask_weared_incorrect”标注。
  对于问题二,结合成熟的深度学习目标检测算法,和本题的实际应用背景,考虑人脸口罩检测的精确性和实时性,选用最新的 YOLOv5 算法作为本题的人脸口罩检测算法的主体框架;在对训练集数据进行分析时,发现样本数据较小而且类别数据不均衡,于是对 YOLOv5 算法采用 MSFE 损失函数进行改进,尽量消除因为数据不平衡带来的检测精度下降问题;在模型训练阶段,对训练集样本进行 9:1 划分(9 份训练集,1 份验证集),在训练过程中结合检测框和类别损失函数等随迭代次数的变化曲线,最终确定epoch=1000 作为最终迭代次数,模型训练完成之后,进行模型的测试。本模型的准确度acc 值高达 96.1%,precision 达到 86.2%,召回率 97.1%,mAP 值达到 79.1%(IOU=0.45)。
  对于问题三,需要利用问题二设计的算法,对测试集样本进行人脸口罩佩戴检测,将检测的原图片经过算法进行口罩佩戴情况标注后,输出出来,然后将检测到的每张图片包含的人脸数目、正确佩戴口罩数目、未佩戴口罩数目、未正确佩戴口罩数目输出并且填写到结果表格中。

模型假设:

  根据题目中所给信息以及要求,本文做出如下假设:
  (1) 假设训练样本的标签文件(.xml 格式)与训练集图片一一对应;
  (2) 假设训练样本的标签文件对人脸佩戴口罩类别的标注正确;
  (3) 假设训练样本的标前文件对人脸的框选位置合理;
  (4) 假设训练集标样本的标签文件不存在对图片人脸口罩检测漏标的情况。

问题分析:

  问题一分析
  通过分析题目要求,问题一是一个将附件 1 训练样本中标签信息(人脸口罩佩戴类别、人脸检测框),显示到对应达到图片中的问题。基于以上问题,我们首先读取标签文件(.xml)与对应的图片,然后根据数字图像处理的知识,通过 PIL 包中的 Image 的 Rectangle 函数在对应的图片中画出检测框,然后在根据口罩佩戴情况类别的不同显示不同的颜色框,并直观显示标签文件中“with_mask、without_mask、mask_weared_incorrect”的分类状态,然后利用循环程序一次性标记出一张图片中的所有人脸标签信息。

  问题二分析
  通过分析问题二的要求,需要设计一个人脸口罩检测算法,首先第一步是检测人脸,定位人脸的位置,然后依据人脸佩戴口罩的状态,分为“戴口罩、未戴口罩、未正确佩戴口罩”三类。人脸口罩检测首先是一个目标检测的问题,考虑到各类成熟目标检测算法的特点,以及本题的实际背景,我们不仅需要检测精度高而且需要做到实时检测,只有这样的模型才能符合本题背景的需求,于是最终选定基于深度学习的 YOLOv5 模型来解决这个问题。

   问题三分析
  针对问题三,我们需要利用问题二得到的人脸口罩检测模型对测试集的图片进行人脸口罩检测,查看“问题 B 提交结果.xlsx”文件,我们需要统计模型检测到每张图片中人脸的数目、正确佩戴数量、未佩戴数量、未正确佩戴数量;所以我们只需要将测试集中的 200 张图片输入到我们训练的模型中,然后输出以上数据,并填入相应的表格中即完成本题的任务要求。

模型的建立与求解整体论文缩略图

在这里插入图片描述

全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可

程序代码:

部分程序如下:

from __future__ import division
import os.path
from PIL import Image
import numpy as np
import shutil
import cv2
from tqdm import tqdm

ImgPath = './convertor/fold0/images/val/'  #原始图片
path = './convertor/fold0/labels/val/'  #原始标注

ProcessedPath = './process_data/'  #生成后数据

txtfiles = os.listdir(path)
print(txtfiles)
#patch img_size
patch_size = 1024
#slide window stride
stride = 600

txtfiles = tqdm(txtfiles)
for file in txtfiles: #遍历txt进行操作
    image_pre, ext = os.path.splitext(file)
    imgfile = ImgPath + image_pre + '.jpg'
    txtfile = path + image_pre + '.txt'
    # if not os.path.isdir(file):  # 判断是否是文件夹,不是文件夹才打开
    #     print(file)

    img = cv2.imread(imgfile)
    sp = img.shape
    img_h, img_w = sp[0], sp[1]

    f = open(os.path.join(path, file), "r")
    lines = f.readlines()
    savepath_img = ProcessedPath + 'images' + '/val'  #处理完的图片保存路径
    savepath_txt = ProcessedPath + 'labels' + '/val'  #处理完的图片标签路径
    if not os.path.exists(savepath_img):
        os.makedirs(savepath_img)
    if not os.path.exists(savepath_txt):
        os.makedirs(savepath_txt)

    bndbox = []
    boxname = []
    for line in lines:
        c, x_c, y_c, w, h, _ = line.split(' ')
        c, x_c, y_c, w, h = float(c), float(x_c), float(y_c), float(w), float(h)
        bndbox.append([x_c, y_c, w, h])
        boxname.append([c])
    # print("boxname: ", boxname)
    # b = bndbox[1]
    # print(b.nodeName)
    #a: x起点, b: y起点, w: 宽, h: 高

    a = []
    b = []
    for a_ in range(0, img_w, stride):
        a.append(a_)
    for b_ in range(0, img_h, stride):
        b.append(b_)


    cropboxes = []
    for i in a:
        for j in b:
            cropboxes.append([i, j, i + patch_size, j + patch_size])
    i = 1
    top_size, bottom_size, left_size, right_size = (150, 0, 0, 0)

    def select(m, n, w, h):
        # m: x起点, n: y起点, w: 宽, h: 高
        bbox = []
        # 查找图片中所有的 box 框
        for index in range(0, len(bndbox)):
            boxcls = boxname[index]#获取回归框的类别
            # print(bndbox[index])
            # x min
            x1 = float(bndbox[index][0] * img_w - bndbox[index][2] * img_w/2)
            # y min
            y1 = float(bndbox[index][1] * img_h - bndbox[index][3] * img_h/2)
            # x max
            x2 = float(bndbox[index][0] * img_w + bndbox[index][2] * img_w/2)
            # y max
            y2 = float(bndbox[index][1] * img_h + bndbox[index][3] * img_h/2)
            # print("the index of the box is", index)
            # print("the box cls is",boxcls[0])
            # print("the xy", x1, y1, x2, y2)
            #如果标记框在第一个范围内则存入bbox[] 并转换成新的格式
            if x1 >= m and x2 <= m + w and y1 >= n and y2 <= n + h:
                a1 = x1 - m
                b1 = y1 - n
                a2 = x2 - m
                b2 = y2 - n
                box_w = a2 - a1
                box_h = b2 - b1
                x_c = (a1 + box_w/2)/w
                y_c = (b1 + box_h/2)/h
                box_w = box_w / w
                box_h = box_h / h
                bbox.append([boxcls[0], x_c, y_c, box_w, box_h])  # 更新后的标记框
        if bbox is not None:
            return bbox
        else:
            return 0

    img = Image.open(imgfile)
    for j in range(0, len(cropboxes)):
        # print("the img number is :", j)
        # 获取在 patch 的 box
        Bboxes = select(cropboxes[j][0], cropboxes[j][1], patch_size, patch_size)
        if len(Bboxes):
            with open(savepath_txt + '/' + image_pre + '_' + '{}'.format(j) + '.txt', 'w') as f:
                for Bbox in Bboxes:
                    for data in Bbox:
                        f.write('{} '.format(data))
                    f.write('\n')

        #图片裁剪
            try:
                cropedimg = img.crop(cropboxes[j])
                # print(np.array(cropedimg).shape)
                cropedimg.save(savepath_img + '/' + image_pre + '_' + str(j) + '.jpg')
                # print("done!")
            except:
                continue
全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/160998.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022跨境支付回顾,iPayLinks让“链接”更高效

从2015年服务第一个客户开始iPayLinks已陪伴用户走过8个春秋作为贴心的跨境资金管家iPayLinks跨越山海&#xff0c;链接全球以产品为基石这一年&#xff0c;iPayLinks持续开发新产品、新功能&#xff0c;帮助外贸企业和跨境卖家抓住机遇&#xff0c;降本增效。B2B外贸收款主打“…

Python 使用TF-IDF

第一个 简易版本 直接来至 jieba 包&#xff0c; 一下代码直接来源 https://blog.csdn.net/qq_38923076/article/details/81630442 这里记录 进行对比 jieba.analyse.extract_tags(sentence, topK20, withWeightFalse, allowPOS()) sentence&#xff1a;待提取的文本语料 topK…

【阶段三】Python机器学习25篇:机器学习项目实战:LigthGBM算法的核心思想、原理与LightGBM分类模型

本篇的思维导图: LigthGBM算法的核心思想 LigthGBM算法是Boosting算法的新成员,由微软公司开发。它和XGBoost算法一样是对GBDT算法的高效实现,在原理上与GBDT算法和XGBoost算法类似,都采用损失函数的负梯度作为当前决策树的残差近似值,去拟合新的决策树。 …

MATLAB实验五

实验五 A 1、在同一图形窗口绘制。利用plot绘图指令绘图命令。 &#xff08;1&#xff09;在窗口上部绘制正弦信号 x(t)sin(0.5πtπ4),t∈[0,4π]x(t)sin(0.5\pi t\frac \pi 4),t∈[0,4\pi]x(t)sin(0.5πt4π​),t∈[0,4π]。要求曲线为黑色实线。 &#xff08;2&#xff…

QT(7)-初识委托

初识委托1 简介2 QT中的委托类2.1 函数2.1.1 关键函数2.1.2 其他函数3 例子3.1 官方例子3.2 修改官方例子4 设想1 简介 委托是Qt中的一种机制&#xff0c;用于在Qt模型/视图架构中处理特定类型的数据。委托提供了一种方便的方法来定制特定类型的数据的显示和编辑。 委托可以做…

天空卫士参与编写的《数据安全治理实践指南(2.0)》正式发布

2023年1月5日&#xff0c;由中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;、中国通信标准化协会指导&#xff0c;中国通信标准化协会大数据技术标准推进委员会主办&#xff0c;数据安全推进计划承办的第二届数据安全治理峰会在北京召开。本次峰会发布多项…

算法刷题打卡第64天:平衡二叉树

平衡二叉树 难度&#xff1a;简单 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1&#xff1a; 输入&#xff1a;root [3,9,…

错误票据(第四届蓝桥杯省赛C++A/B组,第四届蓝桥杯省赛JAVAA/B组)

题目详细&#xff1a;解题思路&#xff1a;这题的难点主要在于对于数据的读入以及对于两个数字的查找对于数据的读入&#xff1a;1.直接对单行字符串进行转换&#xff1a;题目所给出的输入只有行数并不知道一行有多少个数字所以我们采用一下读取一行然后对一行的结果进行读入首…

docker提交腾讯云标准模式

简介我们公司的容器化标准模式&#xff0c;本次是以redis为例进行示范技术要求:你会简单的docker容器打包环境需要:docker、docker-compose、联网环境、腾讯云容器及镜像服务&#xff08;公司已有TKE&#xff09;文件需要&#xff1a;除了你自己的Dockerfile所需要的东西外&…

TensorFlow 基础(三)梯度和自动微分

文章目录Computing gradientsGradient tapesGradients with respect to a modelControlling what the tape watchesIntermediate resultsGradients of non-scalar targetsCases where gradients returns NoneReferencesimport numpy as np import matplotlib.pyplot as pltimpo…

【自学Python】Python三目运算符

Python三目运算符 Python三目运算符教程 Python 中没有其他语言类型的三目运算符&#xff0c;但是我们可以借助 if 语句实现类似的三目运算符。 Python三目运算符详解 说明 Python 的三目运算符是借助于 if 语句来实现的。 语法 True_statements if condition else Fals…

千锋教育嵌入式物联网教程之系统编程篇学习-02

目录 系统调用函数与库函数 库函数的组成 库函数与系统调用的关系 进程概述 进程的定义 进程与程序的区别 进程的状态及其转换 进程的调度机制 进程控制块 查看当前系统所有进程 进程号函数 进程创建fork函数 进程挂起 进程的等待 wait() waitpid 特殊进程 …

CPU 运行时的硬件环境详解

注&#xff1a;本文参考小林coding相关文章&#xff0c;侵权请联系 目录 1.图灵机的工作方式 2.冯诺依曼模型 3.内存 4.中央处理器 5总线 6.输入、输出设备 7.线路位宽与 CPU 位宽 代码写了那么多&#xff0c;你知道 a 1 2 这条代码是怎么被 CPU 执行的吗&#xff1f; …

TCP/IP协议族之TCP、UDP协议详解(小白也能看懂)

前言 在进行网络编程之前&#xff0c;我们必须要对网络通信的基础知识有个大概的框架&#xff0c;TCP/IP协议族涉及到多种网络协议&#xff0c;一般说TCP/IP协议&#xff0c;它不是指某一个具体的网络协议&#xff0c;而是一个协议族。本篇章主要针对IP协议、TCP和UDP协议记录总…

常用的代码命名方法

常见的三种命名方法1 驼峰命名法&#xff08;CamelCase&#xff09;驼峰命名法应该我们最常见的一个&#xff0c;这种命名方式使用大小写混合的格式来区别各个单词&#xff0c;并且单词之间不使用空格隔开或者连接字符连接的命名方式1 大驼峰命名法&#xff08;UpperCamelCase&…

Mysql 基础-持续更新

去重 DISTINCT DISTINCT 关键字的主要作用就是对数据表中一个或多个字段重复的数据进行过滤&#xff0c;只返回其中的一条数据给用户 注意点&#xff1a; DISTINCT 关键字只能在 SELECT 语句中使用。在对一个或多个字段去重时&#xff0c;DISTINCT 关键字必须在所有字段的最前…

IPv6路由协议实验配置(ospfv3、isis-ipv6、bgp4+)

目录 OSPFv3实验配置 建立OSPFv3邻居 AR1修改DR优先级 AR1引入直连路由 配置Stub区域 ISIS IPv6实验配置 建立ISIS邻居 修改AR1的DIS优先级 在AR1上配置路由泄露 BGP4实验配置 AR1与AR2、AR3建立IBGP邻居关系 AR2与AR4建立EBGP邻居关系 配置AR1为反射器 OSPFv3实验…

Android时间与服务器同步方案

转自&#xff1a; https://blog.csdn.net/qinci/article/details/70666631这个的吧&#xff1f;转发请注明来源吧&#xff1f;Android时间与服务器同步方法_飛舞的青春的博客-CSDN博客Android时间与服务器同步方案 在部分软件应用场景里&#xff0c;我们对应用时间要求非常苛刻…

mysql navicat函数_Navicat for MySQL函数高级属性

过程和函数是一组可以保存在服务器上的SQL语句。MySQL(www.formysql.com)函数高级属性主要涉及安全性&#xff0c;定义者&#xff0c;数据访问&#xff0c;决定性等方面的内容Navicat 函数高级属性安全性&#xff1a;指定用创建函数的用户权限来运行函数&#xff0c;或是用启用…

【C++】vector (vector的介绍及使用)

文章目录vector的介绍及使用前面我们学习了string&#xff0c;我们在学vector可以结合之前的理解&#xff0c;所以我们vector就不详细介绍了。 vector的介绍及使用 vector是表示可变大小数组的序列容器。就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就…