【竞赛02】安全帽佩戴检测(Helmet Detection) | 返回首页

作者:欧新宇(Xinyu OU)
当前版本:Release v2.0
开发平台:PaddlePaddle 3.0.0beta2, PaddleDetection-release-2.8
运行环境:Intel Core i7-13700KF CPU 3.4GHz, nVidia GeForce RTX 4080
本教案所涉及的数据集仅用于教学和交流使用,请勿用作商用。

最后更新:2025年1月30日


所有作业均在AIStudio上进行提交,提交时包含源代码和运行结果

一、任务描述

近年来,随着人工智能的发展,其在语音识别、自然语言处理、图像与视频分析等诸多领域取得了巨大成功。“安全帽佩戴检测”比赛,旨在利用先进的计算机视觉技术,实现对工地、工厂等高风险作业环境中工作人员安全帽佩戴情况的智能检测。参赛者需设计并开发高效的算法模型,能够准确识别监控视频中的人员,并判断其是否佩戴了安全帽。此任务不仅考验参赛者对图像处理、目标检测与识别等技术的掌握程度,更强调算法的实时性与准确性,以期为解决实际生产中的安全问题提供技术支撑。通过本次比赛,我们期待发掘更多创新性的计算机视觉解决方案,共同推动智能安防领域的发展,为构建更加安全的工作环境贡献力量。

二、数据说明

本竞赛所用训练和测试图片均来自生活场景。总共三个类别,分别是head, helmet, person,其中head表示未佩戴安全帽,helmet表示佩戴了安全帽,类别标签保存在 label_list.txt。图片中安全帽存在多种情况,包括不同颜色,不同位置,是否遮挡,并且每幅图片的安全帽的数量也不同。

HelmetExamples

数据集包含4000个训练样本和1000个测试样本,与百度AIStudio提供的竞赛评价标准一致。所有图像均给出voc标注和coco标注格式,前者每幅图片都生成了一个 .xml 的标注文件,后者所有样本生成了一个 .json 的标注文件。PS:voc标注为原始标注,coco是使用PaddleDetection自带的xcoco工具生成的json标注文件。关于这两种标注格式的说明,请参考Pascal VOC和MSCOCO数据集简介

注意:使用PaddleDetection时,模型在训练 train.py 和验证 eval.py 时,voc和coco标注文件都可以使用;但进行推理 infer.py 时,只能使用coco标注文件。(估计是PaddleDetection自身的Bug)

三、分数评定

  1. 所有奖励分数均叠加到期末总成绩中
  2. 第一名奖励10分,第二名奖励8分,第三名奖励7分
  3. 排名4~10名,奖励6分;排名11~20名,奖励5分
  4. 所有参与竞赛者,奖励2分,与排名奖励不冲突
  5. 分数评定高于Baseline的参与者,奖励3分,与排名奖励不冲突

四、提交答案

  1. 所有内容均在AIStudio上进行提交,提交时包含源代码和运行结果
  2. 数据集下载地址:https://aistudio.baidu.com/datasetdetail/315030
  3. 提交完整程序代码,包括运行过程(非必须)
  4. 提交结果文件。结果文件为 .txt 文件格式,命名为 pred_result.txt,文件内的字段需要按照指定格式写入。
    • 每行数据格式:图像名 置信度 xmin ymin xmax ymax 类别ID,其中图像名不带扩展名,置信度建议保留三位小数,四个坐标值和类别ID为整型。
    • 输出结果的每一行都包含一个文件名、空格和一个预测结果(数字)

样例如下:

hard_hat_workers1428 0.789 251 0 264 6 1
hard_hat_workers4025 0.999 204 203 243 246 2
hard_hat_workers4025 0.889 403 203 413 245 2
hard_hat_workers1853 0.998 222 301 247 328 0
···

五、结果展示

六、输出预测结果示例代码

为了使用飞桨平台进行性能评测,您需要将预测结果保存为指定的格式,并进行上传。下面给出一种推荐方法供参考使用。

  1. 使用飞桨 inter.py 命令行工具进行推理,并保存预测结果。
>> python tools/infer.py -c configs/Helmet/faster_rcnn_r50_fpn_1x_voc_infer.yml --output_dir=output/Helmet/faster_rcnn_r50_fpn_1x_voc/img_infer_results --infer_dir=D:/WorkSpace/ExpDatasets/Helmet/test/JPEGImages/ --save_results=output/Helmet/faster_rcnn_r50_fpn_1x_voc 2>&1 | tee .\output\helmet\faster_rcnn_r50_fpn_1x_voc\infer_log.txt

上面的命令行工具中,faster_rcnn_r50_fpn_1x_voc_infer.yml 和训练所使用的 faster_rcnn_r50_fpn_1x_voc.yml 基本上是完全相同的,只是使用的是coco标准的数据标注文件;--save_results 命令用于生成预测结果,包括带检测框的图像和预测结果bbox.json 文件;2>&1 | tee ..... 用于生成验证过程中的日志文件,包括预测结果和验证结果。需要了解的时,PaddleDetection的批量推理是自动读取文件夹中的所有图像并生成预测结果,但读取的顺序是不可知的,因此需要手动获取测试时的文件列表。幸运的是,推理过程保存了完整的日志文件,因此可以通过日志文件获取测试时的文件列表。但该日志文件保存的时候,其编码格式为 utf-16,因此还需要先将日志文件转换为 utf-8 格式。

如果您已经准备好了PaddleDetection生成的预测结果 bbox.json,以及推理测试时的日志文件,那么你可以使用如下代码生成竞赛要求提供的结果文件 pred_result.txt。最后,你只需要将该文件提交到飞桨平台即可。

import os
import json

# 0. 定义路径
output_root_path = 'D:/WorkSpace/MyProjects/PaddleDetection-release-2.8/output/helmet/faster_rcnn_r50_fpn_1x_voc/'
json_pred = os.path.join(output_root_path, 'bbox.json')
infer_log = os.path.join(output_root_path, 'infer_log.txt')
infer_log_utf8 = os.path.join(output_root_path, 'infer_log_utf8.txt')
pred_result_path = os.path.join(output_root_path, 'pred_result.txt')

if os.path.exists(pred_result_path):
    os.remove(pred_result_path)

# 1. 获取推理日志中的文件列表
def convert_utf16_to_utf8(input_file, output_file):
    # 读取 UTF-16 编码的文件内容
    with open(input_file, 'r', encoding='utf-16') as infile:
        content = infile.read()

    # 将内容写入 UTF-8 编码的输出文件
    with open(output_file, 'w', encoding='utf-8') as outfile:
        outfile.write(content)

def create_infer_list(file_path):
    image_files = []
    with open(file_path, 'r') as file:
        for line in file:
            index1 = line.find('hard_hat_worker')
            index2 = line.find('.png')
            if index1 != -1 and index2 != -1:
                image_files.append(line[index1:index2])

    return image_files

convert_utf16_to_utf8(infer_log, infer_log_utf8)
infer_list = create_infer_list(infer_log_utf8)

# 2. 输出推理结果
# 2.1 读取PaddleDetection推理过程生成的bbox.json文件
with open(json_pred, 'r', encoding='utf-8') as file:
    data_pred = json.load(file)

# 2. 将json文件的推理信息,按要求写入txt文件
# 提交名: pred_result.txt,每一行代表一个目标: 图像名 置信度 xmin ymin xmax ymax 类别
with open(pred_result_path, 'a', encoding='utf-8') as f_pred:
    for i in range(len(infer_list)):
        img_name = infer_list[i]
        for j in range(len(data_pred)):
            if (data_pred[j]['image_id'] == i):
                bbox = ' '.join(['{}'.format(int(x)) for x in data_pred[j]['bbox']])
                xmin = int(data_pred[j]['bbox'][0])
                ymin = int(data_pred[j]['bbox'][1])
                xmax = xmin + int(data_pred[j]['bbox'][2])
                ymax = ymin + int(data_pred[j]['bbox'][3])
                f_pred.write('{} {:.3f} {} {} {} {} {:d}\n'.format(img_name, data_pred[j]['score'], xmin, ymin, xmax, ymax, data_pred[j]['category_id']))
      

预测结果已保存至 D:/WorkSpace/MyProjects/PaddleDetection-release-2.8/output/helmet/faster_rcnn_r50_fpn_1x_voc/pred_result.txt

【竞赛02】安全帽佩戴检测(Helmet Detection) | 返回首页