安全帽佩戴检测算法模型训练详细流程

news2025/1/11 3:21:15
一、任务描述

实际施工现场需要对每个进出的人员进行安全帽监测,对未佩戴安全帽的人员平台进行风险告警,通知工作人员并记录下来。

主要包括三类目标物体:头盔(helmet),人(person)和人头(head)

二、实现流程

1、数据集:直接用的网络数据集,下载地址:

https://aistudio.baidu.com/aistudio/datasetdetail/50329

2、算法:用的算法框架是百度的PaddleDetection,代码下载地址:

https://github.com/PaddlePaddle/PaddleDetection

3、将数据集解压保存在helmet_data文件夹下

4、将数据集拆分成训练集、测试集和验证集,用txt文件记录保存下来。代码如下:

import logging
import random
import os
import os.path as osp
import xml.etree.ElementTree as ET


def list_files(dirname):
    """ 列出目录下所有文件(包括所属的一级子目录下文件)
    Args:
        dirname: 目录路径
    """
    def filter_file(f):
        if f.startswith('.'):
            return True
        return False

    all_files = list()
    dirs = list()
    for f in os.listdir(dirname):
        if filter_file(f):
            continue
        if osp.isdir(osp.join(dirname, f)):
            dirs.append(f)
        else:
            all_files.append(f)
    for d in dirs:
        for f in os.listdir(osp.join(dirname, d)):
            if filter_file(f):
                continue
            if osp.isdir(osp.join(dirname, d, f)):
                continue
            all_files.append(osp.join(d, f))
    return all_files


def is_pic(filename):
    """ 判断文件是否为图片格式
    Args:
        filename: 文件路径
    """
    suffixes = {'JPEG', 'jpeg', 'JPG', 'jpg', 'BMP', 'bmp', 'PNG', 'png'}
    suffix = filename.strip().split('.')[-1]
    if suffix not in suffixes:
        return False
    return True


def replace_ext(filename, new_ext):
    """ 替换文件后缀
    Args:
        filename: 文件路径
        new_ext: 需要替换的新的后缀
    """
    items = filename.split(".")
    items[-1] = new_ext
    new_filename = ".".join(items)
    return new_filename


def split_voc_dataset(dataset_dir, save_dir, val_percent=0.15, test_percent=0.15):
    # 注意图片目录和标注目录名已全部修改
    if not osp.exists(osp.join(dataset_dir, "JPEGImages")):
        logging.error("\'JPEGImages\' is not found in {}!".format(dataset_dir))
    if not osp.exists(osp.join(dataset_dir, "Annotations")):
        logging.error("\'Annotations\' is not found in {}!".format(
            dataset_dir))
    all_image_files = list_files(osp.join(dataset_dir, "JPEGImages"))

    image_anno_list = list()
    label_list = list()
    for image_file in all_image_files:
        if not is_pic(image_file):  # 判断是否为图片格式
            continue
        anno_name = replace_ext(image_file, "xml")
        if osp.exists(osp.join(dataset_dir, "Annotations", anno_name)):
            image_anno_list.append([image_file, anno_name])
            try:
                tree = ET.parse(osp.join(dataset_dir, "Annotations", anno_name))
            except:
                raise Exception("文件{}不是一个良构的xml文件,请检查标注文件".format(
                    osp.join(dataset_dir, "Annotations", anno_name)))
            objs = tree.findall("object")
            for i, obj in enumerate(objs):
                cname = obj.find('name').text
                if not cname in label_list:
                    label_list.append(cname)
        else:
            logging.error("The annotation file {} doesn't exist!".format(anno_name))

    random.shuffle(image_anno_list)  # 随机打乱
    image_num = len(image_anno_list)  # 总图片数量
    val_num = int(image_num * val_percent)  # 验证集数量
    test_num = int(image_num * test_percent)  # 测试集数量
    train_num = image_num - val_num - test_num  # 训练集数量

    train_image_anno_list = image_anno_list[:train_num]  # 训练集样本
    val_image_anno_list = image_anno_list[train_num:train_num + val_num]  # 验证集样本
    test_image_anno_list = image_anno_list[train_num + val_num:]  # 测试集样本

    with open(osp.join(save_dir, 'train_list.txt'), mode='w', encoding='utf-8') as f:
        for x in train_image_anno_list:
            file = osp.join("JPEGImages", x[0])
            label = osp.join("Annotations", x[1])
            f.write('{} {}\n'.format(file, label))
    with open(osp.join(save_dir, 'val_list.txt'), mode='w', encoding='utf-8') as f:
        for x in val_image_anno_list:
            file = osp.join("JPEGImages", x[0])
            label = osp.join("Annotations", x[1])
            f.write('{} {}\n'.format(file, label))
    if len(test_image_anno_list):
        with open(osp.join(save_dir, 'test_list.txt'), mode='w', encoding='utf-8') as f:
            for x in test_image_anno_list:
                file = osp.join("JPEGImages", x[0])
                label = osp.join("Annotations", x[1])
                f.write('{} {}\n'.format(file, label))
    with open(osp.join(save_dir, 'labels.txt'), mode='w', encoding='utf-8') as f:
        for l in sorted(label_list):
            f.write('{}\n'.format(l))
    return image_anno_list, label_list


if __name__ == '__main__':
    dataset_dir = "/root/bigdata/pycharm_projects/PaddleDetection/data/helmet_data/helmet_train_data"
    split_voc_dataset(dataset_dir=dataset_dir, save_dir=dataset_dir)

5、修改tools下的x2coco.py的训练集文件地址参数,然后运行x2coco.py来将xml文件转成json文件,具体修改如下(我这边为了方便,将需要修改的参数都放到一个params.py文件中):

 

注意:由于数据集标注文件已经是xml,所以不需要做其他转换。如果标注文件是yolo格式的txt文件,则需要先将其转换为voc格式的xml文件。

6、修改PaddleDetection中的/configs/ppyoloe/ppyoloe_plus_crn_x_80e_coco.yml'文件,

及其相关文件。

具体修改如下:

'../datasets/coco_detection.yml',

--------------------------------------------------------------------------------

ppyoloe_plus_crn_x_80e_coco.yml:

--------------------------------------------------------------------------------

'./_base_/optimizer_80e.yml',

--------------------------------------------------------------------------------

'../runtime.yml',

 这里注意,没gpu的这个数据集要跑三天左右,建议买个gpu,不然感觉有点浪费时间

--------------------------------------------------------------------------------

另外有需要调整神经网络训练参数的可以去'./_base_/ppyoloe_plus_crn.yml'里面修改;有需要调整样本参数的可以去'./_base_/ppyoloe_plus_reader.yml'里面修改。

7、执行模型训练文件train.py:

 python tools/train.py -c configs/ppyoloe/ppyoloe_plus_crn_x_80e_coco.yml --eval --amp

如果直接执行train.py不指定coco文件的话,就在cli.py中修改config的默认值,具体如下:

 8、推理测试集数据,先修改infer.py的参数值,修改如下:

执行语句:python tools/infer.py -c configs/ppyoloe/ppyoloe_plus_crn_x_80e_coco.yml -o weights=../output/ppyoloe_plus_crn_x_80e_coco/best_model

 如果直接执行infer.py不指定weights的话,就会直接使用ppyoloe_plus_crn_x_80e_coco.yml中的weights值。

其中weights参数是最好的训练模型的权重的绝对路径,

infer_dir是测试集图片数据的绝对路径,

output_dir是结果输出绝对路径,

最终生成推理结果的图片和测试集的推理结果bbox.json都存储在helmet_output/infer_output/路径下。

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

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

相关文章

100种思维模型之耗散结构理论思维模型-96

避免熵死的方法之一就是建立 耗散结构 。 那么,何谓耗散结构理论? 01、何谓耗散结构思维模型‍‍‍ 一、耗散结构理论 1969年,比利时学者 伊里亚普利高津 在对热力学第二定律研究的基础上,提出了 “耗散结构理论”。 他认…

【导航电子地图(MAP)模块功能】

Map功能:提供导航系统中地图描画、地图操作、地图检索的功能。 地图操作功能:地图滚动等。 地图检索功能:附近名称取得、View内检索等。 地图描画功能:是指从地图Data base中读出地点情报,然后按照一定的风格&#…

Meta提出全新参数高效微调方案,仅需一个RNN,Transformer模型GPU使用量减少84%!

近来,随着ChatGPT和GPT-4模型的不断发展,国内外互联网大厂纷纷推出了自家的大语言模型,例如谷歌的PaLM系列,MetaAI的LLaMA系列,还有国内公司和高校推出的一些大模型,例如百度的文心一言,清华的C…

vue3中通过vue-i18n实现国际化

效果图 前言 突然想在vue3项目中使用国际化功能,查阅相关资料后发现和vue2的用法有些出入,记录一下 使用 下载vue-i18n npm i vue-i18n2、准备语言文件 目前我的项目只支持中英文切换,故准备一份中文文件和一份对应的英译文件 创建langur…

七大排序算法——直接插入排序,通俗易懂的思路讲解与图解(完整Java代码)

文章目录 一、排序的概念排序的概念排序的稳定性七大排序算法 二、直接插入排序核心思想代码实现 三、性能分析四、七大排序算法性能对比 一、排序的概念 排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小&#…

【Java进阶之路】NIO基础

一、NIO基础 Java New IO是从Java1.4版本开始引入的一个新的IO api,可以替代以往的标准IO,NIO相比原来的IO有同样的作用和目的,但是使用的方式完全不一样,NIO是面向缓冲区的,基于通道的IO操作,这也让它比传…

美团外卖智能陪伴型导购的探索与实践

相比于其他电商场景,外卖场景对于实时发现和反馈用户兴趣的能力有着更高的要求。近年来,美团外卖算法团队摸索出了一套适用于外卖场景的智能陪伴型导购架构和策略。这一举措已经取得了显著成效,本文将详细介绍外卖搜索技术团队搭建智能陪伴型…

Redis数据结构 — IntSet

目录 整数集合IntSet结构设计 IntSet的升级操作 升级具体过程 升级具体源码 小结 IntSet是Redis中set集合的一种实现方式,基于整数数组来实现,并且具备长度可变、有序等特征。 整数集合IntSet结构设计 整数集合本质上是一块连续内存空间&#xff…

Ubuntu22.04安装飞书

通过以下教程可以快速的安装飞书。 安装包下载 进入飞书下载官网下载飞书Linux客户端 选择deb格式安装包下载 安装方式 方式一:运行安装包安装 双击deb文件,点击install进行安装 方式二:终端命令安装 到安装目录,然后dpkg你的安…

光速吟唱,Clibor ,批量多次复制依次粘贴工具 快捷输入软件教程

批量多次复制依次粘贴工具 批量复制粘贴工具0.81.exe https://www.aliyundrive.com/s/3sbBaGmHkb8 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。 青县solidworks钣金设计培训 …

Web3.0:重新定义数字资产的所有权和交易方式

随着区块链技术的发展和应用,数字资产的概念已经逐渐深入人心。数字资产不仅包括加密货币,还包括数字艺术品、虚拟土地、游戏道具等各种形式的数字物品。然而,在传统的互联网环境下,数字资产的所有权和交易方式往往受到限制和约束…

二极管总结

目录 1.2.2二极管的伏安特性 1.2.3二极管的主要参数 1.2.4二极管的等效电路 1.2.5稳压二极管 1.2.6其它类型二极管 1.2.2二极管的伏安特性 二极管和PN结伏安特性区别: 相同点:同样具有单向导电性 不同点:二极管存在半导体体电阻和引线电阻…

Android JNI线程的创建 (十二)

🔥 Android Studio 版本 🔥 🔥 创建JNI 🔥 package com.cmake.ndk1.jni;public class JNIThread {static {System.loadLibrary("thread-lib");}public native void createNativeThread();public native void createNativeThreadWithArgs();public native v…

金科威GoldWayUT4000监护仪协议对接

通过网口,成功对接到参数: Sys、Dia、Map、Temp、HR、SPO2、Resp、RR、EtCO2、InCO2等数值。

玩玩两个简单的python的web框架 flask、fastapi

IDEA连接远程解释器,本地代码编辑无法代码提示 一、Flask入门使用 官网 其它参考 注意 1.这里使用linux 192.168.72.126上远程解释器,需要/usr/bin/pip3 install flask,host参数不要使用localhost/127.0.0.1,即只监听本地的访问,会导致wind…

electron-updater 自动更新升级应用

electron 内置了 autoUpdater 自动更新功能,但是服务配置有些复杂,最后选择了 electron-updater 工具插件,这里就讲讲如何配置 electron-updater 来自动更新升级应用。 一、项目依赖和 scripts 安装 electron-updater 和 electron-log pnpm…

5分钟构建电商API接口服务 | python小知识

1. 什么是API 我们经常会使用一些API接口来完成特定的功能,比如查询天气的数据,下载股票的数据,亦或是调用ChatGPT模型的结构等等。 API全称是Application Programming Interface,即应用程序接口,它通常提供了一个功…

数据结构与算法——顺序表(顺序存储结构)及初始化详解

顺序表,全名顺序存储结构,是线性表的一种。通过《什么是线性表》一节的学习我们知道,线性表用于存储逻辑关系为“一对一”的数据,顺序表自然也不例外。 不仅如此,顺序表对数据的物理存储结构也有要求。顺序表存储数据…

Android之Glide图片框架分析

为什么使用Glide? 使用简单,链式调用,API简洁。with、load、into三步走就可以加载图片生命周期自动绑定,根据绑定的Activity或者Fragment生命周期管理图片请求高效处理Bitmap。支持bitmap的复用和主动回收,减少系统回…

查看隐藏文件怎么做?4个简单方法分享

“朋友们!想问问大家如果设置了隐藏文件,想查看的时候应该怎么进行查看呀?有没有朋友可以教教我!” 为了保护电脑的隐私,我们有时候可能会给电脑设置某些隐藏的文件,这些隐藏的文件我们是无法看到的。如果我…