0

0

【公共场所吸烟检测吸烟】爸,你还敢抽烟么

P粉084495128

P粉084495128

发布时间:2025-07-22 15:59:08

|

598人浏览过

|

来源于php中文网

原创

该项目针对公共场所禁烟效果不佳问题,基于PaddleX训练模型,结合语音播报实现控烟。先处理数据集,修改XML文件适配格式,清理冗余文件并划分训练、验证、测试集(7:2:1)。用PPYolo模型训练300个epoch,第277个效果最佳,map约76。导出模型后部署,通过摄像头检测,阈值≥0.3时播放禁烟语音。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

【公共场所吸烟检测吸烟】爸,你还敢抽烟么 - php中文网

不抽烟,也没有烟,所以只能以这种形式代替了

爸,这下你还敢抽烟吗?/邪笑

【公共场所吸烟检测吸烟】爸,你还敢抽烟么 - php中文网        

我爸:这锅我不背!!

项目背景

  2014年11月24日,卫生计生委起草了《公共场所控制吸烟条例(送审稿)》向社会公开征求意见。送审稿明确,所有室内公共场所一律禁止吸烟。此外,体育、健身场馆的室外观众坐席、赛场区域;公共交通工具的室外等候区域等也全面禁止吸烟。而《公共场所控制吸烟条例》实施后,卫计委将考虑为控烟条例设置举报电话,同时开展监测评估,鼓励全社会参与戒烟活动。 

  但有很多人秉持“多一事不如少一事”的原则:“欸,有点电话就不打,我就忍着!”,导致社会公共场所禁烟效果普遍不佳。

  因而“公共场所,禁止吸烟”的标牌,也渐渐沦为了摆设。

【公共场所吸烟检测吸烟】爸,你还敢抽烟么 - php中文网        

项目介绍

  本项目基于PaddleX进行模型训练,并利用inference导出后部署在本地,并使用百度大脑合成后进行“公共场所,禁止吸烟”的语音播报。

首先导入使用PaddleX时所需的模块

In [9]
!pip install paddlex
!pip install paddle2onnx
   
In [65]
# 进行数据集解压!unzip -oq /home/aistudio/data/data86368/smoke.zip -d /home/aistudio/dataset2
   

  下面这个check.py是我在开发过程中遇到点小问题在PaddleX的Github issue中找到的,后面我们会提到这个脚本的功能。
(深刻启示:有问题就去逛issue!!!要相信你现在所遇到的绝大多数问题已经有“先烈”替你趟过了!即使没有也可以提issue!飞桨的开发小哥哥们回复也是炒鸡快!!!!)

In [52]
!mv check.py dataset
   

数据处理和数据清洗

  在执行数据集解压命令后,可以看到本数据集提供了images和Annotations两个文件夹,分别存放.jpg和.xml文件。为了能够顺利使用PaddleX进行数据集划分和模型训练,需要将原本数据集修改为符合PaddleX数据集格式的数据集。
In [53]
# 这里修改.xml文件中的<path>元素!mkdir dataset/Annotations1import xml.dom.minidomimport os

path = r'dataset/Annotations'  # xml文件存放路径sv_path = r'dataset/Annotations1'  # 修改后的xml文件存放路径files = os.listdir(path)
cnt = 1for xmlFile in files:
    dom = xml.dom.minidom.parse(os.path.join(path, xmlFile))  # 打开xml文件,送到dom解析
    root = dom.documentElement  # 得到文档元素对象
    item = root.getElementsByTagName('path')  # 获取path这一node名字及相关属性值
    for i in item:
        i.firstChild.data = '/home/aistudio/dataset/JPEGImages/' + str(cnt).zfill(6) + '.jpg'  # xml文件对应的图片路径

    with open(os.path.join(sv_path, xmlFile), 'w') as fh:
        dom.writexml(fh)
    cnt += 1
   
In [55]
# 这里修改.xml文件中的<failname>元素!mkdir dataset/Annotations2import xml.dom.minidomimport os

path = r'dataset/Annotations1'  # xml文件存放路径sv_path = r'dataset/Annotations2'  # 修改后的xml文件存放路径files = os.listdir(path)for xmlFile in files:
    dom = xml.dom.minidom.parse(os.path.join(path, xmlFile))  # 打开xml文件,送到dom解析
    root = dom.documentElement  # 得到文档元素对象
    names = root.getElementsByTagName('filename')
    a, b = os.path.splitext(xmlFile)  # 分离出文件名a
    for n in names:
        n.firstChild.data = a + '.jpg'
    with open(os.path.join(sv_path, xmlFile), 'w') as fh:
        dom.writexml(fh)
   
In [56]
# 这里修改.xml文件中的<name>元素!mkdir dataset/Annotations3#!/usr/bin/env python2# -*- coding: utf-8 -*-
 import osimport xml.etree.ElementTree as ET
 
origin_ann_dir = '/home/aistudio/dataset/Annotations2/'# 设置原始标签路径为 Annosnew_ann_dir = '/home/aistudio/dataset/Annotations3/'# 设置新标签路径 Annotationsfor dirpaths, dirnames, filenames in os.walk(origin_ann_dir):   # os.walk游走遍历目录名
  for filename in filenames:    print("process...")    # if os.path.isfile(r'%s%s' %(origin_ann_dir, filename)):   # 获取原始xml文件绝对路径,isfile()检测是否为文件 isdir检测是否为目录
    origin_ann_path = os.path.join(origin_ann_dir, filename)   # 如果是,获取绝对路径(重复代码)
    new_ann_path = os.path.join(new_ann_dir, filename)
    tree = ET.parse(origin_ann_path)  # ET是一个xml文件解析库,ET.parse()打开xml文件。parse--"解析"
    root = tree.getroot()   # 获取根节点
    for object in root.findall('object'):   # 找到根节点下所有“object”节点
        name = str(object.find('name').text)  # 找到object节点下name子节点的值(字符串)
        # 如果name等于str,则删除该节点
        if (name in ["smoke"]):        #   root.remove(object)
            pass

        # 如果name等于str,则修改name
        else:            object.find('name').text = "smoke"

        tree.write(new_ann_path)#tree为文件,write写入新的文件中。
        print("OK1")
   
由于在上述数据处理过程中我们产生了很多冗余的文件,故需将其删除。并将其更改为适合PaddleX的数据集格式。
In [57]
!rm -rf dataset/Annotations
!rm -rf dataset/Annotations1
!rm -rf dataset/Annotations2
!mv dataset/Annotations3 dataset/Annotations
!mv dataset/images dataset/JPEGImages
   

在原始数据集中,存在.jpg文件和.xml文件匹配不对等的情况,这里我们根据.jpg文件名删除了在Annotations文件夹中无法匹配的.xml文件,使得.jpg和.xml能够一一对应。

In [59]
import osimport shutil
path_annotations = 'dataset/Annotations'path_JPEGImage = 'dataset/JPEGImages'xml_path = os.listdir(path_annotations)
jpg_path = os.listdir(path_JPEGImage)for i in jpg_path:
    a = i.split('.')[0] + '.xml'
    if a in xml_path:        pass
    else:        print(i)
        os.remove(os.path.join(path_JPEGImage,i))
   

因为懒(有现成的为啥还要自己写呢~),所以就用了PaddleX 自带的划分数据集的命令,这里我们训练集、验证集、测试集的比例为7:2:1。

In [60]
!paddlex --split_dataset --format VOC --dataset_dir /home/aistudio/dataset/ --val_value 0.2 --test_value 0.1
       
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/setuptools/depends.py:2: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
  import imp
Dataset Split Done.
Train samples: 3403
Eval samples: 972
Test samples: 486
Split files saved in /home/aistudio/dataset/
       

  当然,从一般情况来说,这一步完成之后就可以进行模型训练了。但其实在实际过程中,若进行模型训练,在训练过程中会报错。具体报错,大家感兴趣的可以实地体验一下(嘿嘿嘿)。这里就需要用到我们在开头所提到的check.py文件。执行以下命令,会输出图片读取有误的图片路径。我们用rm -rf命令将其与其对应的.xml文件删除。

Krea AI
Krea AI

多功能的一站式AI图像生成和编辑平台

下载
In [61]
%cd dataset/
!cat train_list.txt | python check.py
!cat test_list.txt | python check.py
!cat val_list.txt | python check.py
       
/home/aistudio/dataset
Wrong img file: JPEGImages/790_strawberry.jpg
Wrong img file: JPEGImages/791_strawberry.jpg
Wrong img file: JPEGImages/000143.jpg
Wrong img file: JPEGImages/000144.jpg
Wrong img file: JPEGImages/000120.jpg
Wrong img file: JPEGImages/780_strawberry.jpg
Wrong img file: JPEGImages/845_strawberry.jpg
Wrong img file: JPEGImages/smoke132.jpg
Corrupt JPEG data: 1 extraneous bytes before marker 0xdb
Wrong img file: JPEGImages/000325.jpg
Wrong img file: JPEGImages/000193.jpg
       
In [62]
!rm -rf JPEGImages/000120.jpg
!rm -rf JPEGImages/000143.jpg
!rm -rf JPEGImages/791_strawberry.jpg
!rm -rf JPEGImages/smoke132.jpg
!rm -rf JPEGImages/780_strawberry.jpg
!rm -rf JPEGImages/000193.jpg
!rm -rf JPEGImages/845_strawberry.jpg
!rm -rf JPEGImages/000325.jpg
!rm -rf JPEGImages/000144.jpg
!rm -rf JPEGImages/790_strawberry.jpg
!rm -rf Annotations/000120.xml
!rm -rf Annotations/000143.xml
!rm -rf Annotations/791_strawberry.xml
!rm -rf Annotations/smoke132.xml
!rm -rf Annotations/780_strawberry.xml
!rm -rf Annotations/000193.xml
!rm -rf Annotations/845_strawberry.xml
!rm -rf Annotations/000325.xml
!rm -rf Annotations/000144.xml
!rm -rf Annotations/790_strawberry.xml
   

并且删除之前生成的几个关于数据集的文本文件,重新执行PaddleX划分数据集的命令。

In [63]
!rm -rf val_list.txt
!rm -rf train_list.txt
!rm -rf test_list.txt
!rm -rf labels.txt
   
In [64]
!paddlex --split_dataset --format VOC --dataset_dir /home/aistudio/dataset/ --val_value 0.2 --test_value 0.1
       
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/setuptools/depends.py:2: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
  import imp
Dataset Split Done.
Train samples: 3396
Eval samples: 970
Test samples: 485
Split files saved in /home/aistudio/dataset/
       
In [25]
%cd /home/aistudio/
       
/home/aistudio
       

模型训练

  在使用PaddleX进行模型训练的过程中,我们使用目前PaddleX适配精度最高的PPYolo模型进行训练。其模型较大,预测速度比YOLOv3-DarkNet53更快,适用于服务端。大家也可以更改其他模型尝试一下。这里我训练了大概300个epoch(别问,问就是没算力了也懒得续点了……)其中第277个epoch效果最佳,map大概在76。(有算力的童鞋可以试着调参或者继续往下面去试试)

In [27]
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0'from paddlex.det import transformsimport paddlex as pdx# 定义训练和验证时的transforms# API说明 https://paddlex.readthedocs.io/zh_CN/develop/apis/transforms/det_transforms.htmltrain_transforms = transforms.Compose([
    transforms.MixupImage(mixup_epoch=250), transforms.RandomDistort(),
    transforms.RandomExpand(), transforms.RandomCrop(), transforms.Resize(
        target_size=608, interp='RANDOM'), transforms.RandomHorizontalFlip(),
    transforms.Normalize()
])

eval_transforms = transforms.Compose([
    transforms.Resize(
        target_size=608, interp='CUBIC'), transforms.Normalize()
])# 定义训练和验证所用的数据集# API说明:https://paddlex.readthedocs.io/zh_CN/develop/apis/datasets.html#paddlex-datasets-vocdetectiontrain_dataset = pdx.datasets.VOCDetection(
    data_dir='/home/aistudio/dataset',
    file_list='/home/aistudio/dataset/train_list.txt',
    label_list='/home/aistudio/dataset/labels.txt',
    transforms=train_transforms,
    parallel_method='thread',
    shuffle=True)
eval_dataset = pdx.datasets.VOCDetection(
    data_dir='/home/aistudio/dataset',
    file_list='/home/aistudio/dataset/val_list.txt',
    label_list='/home/aistudio/dataset/labels.txt',
    parallel_method='thread',
    transforms=eval_transforms)# 初始化模型,并进行训练# 可使用VisualDL查看训练指标,参考https://paddlex.readthedocs.io/zh_CN/develop/train/visualdl.htmlnum_classes = len(train_dataset.labels)# API说明: https://paddlex.readthedocs.io/zh_CN/develop/apis/models/detection.html#paddlex-det-ppyolomodel = pdx.det.PPYOLO(num_classes=num_classes)# API说明: https://paddlex.readthedocs.io/zh_CN/develop/apis/models/detection.html#train# 各参数介绍与调整说明:https://paddlex.readthedocs.io/zh_CN/develop/appendix/parameters.htmlmodel.train(
    num_epochs=540,
    train_dataset=train_dataset,
    train_batch_size=8,
    eval_dataset=eval_dataset,
    learning_rate=0.000125,
    save_interval_epochs=1,
    lr_decay_epochs=[270,320, 480],
    save_dir='output/ppyolo',
    use_vdl=True)
   

模型导出

  这里我们将训练过程中保存的模型导出为inference格式模型,其原因在于:PaddlePaddle框架保存的权重文件分为两种:支持前向推理和反向梯度的训练模型 和 只支持前向推理的推理模型。二者的区别是推理模型针对推理速度和显存做了优化,裁剪了一些只在训练过程中才需要的tensor,降低显存占用,并进行了一些类似层融合,kernel选择的速度优化。而导出的inference格式模型包括__model__、__params__和model.yml三个文件,分别表示模型的网络结构、模型权重和模型的配置文件(包括数据预处理参数等)。

In [ ]
!paddlex --export_inference --model_dir=PaddleDetection/output/ppyolo/epoch_277 --save_dir=./inference_model
   

简单部署尝试

  下面我们简单地部署体验了一番。这里打开了设备摄像头进行视频流预测,并设置了在阈值>=0.3的时候会播放“公共场所,禁止吸烟!”

  在本项目中可以看到存在“cigarette.mp3”和“dad.mp3”的音频文件。“dad.mp3”的具体内容这里卖个关子。大家下载下来体验一下就知道了hhh。

  而这里的音频,使用的是百度大脑的语音合成API,具体的大家可以去百度大脑官网看看,在本项目中就不予展示了。

In [ ]
import cv2import paddlex as pdxfrom playsound import playsound# 修改模型所在位置predictor = pdx.deploy.Predictor('D:\project\python\cigarette\inference_model')
cap = cv2.VideoCapture(0)while cap.isOpened():
    ret, frame = cap.read()    if ret:
        result = predictor.predict(frame)
        score = result[0]['score']        if score >= 0.3:            print("*"*100)            # 修改音频所在位置
            playsound('D:\project\python\cigarette\cigarette.mp3')        # print(result)
        vis_img = pdx.det.visualize(frame, result, threshold=0.6, save_dir=None)
        cv2.imshow('cigarette', vis_img)        if cv2.waitKey(1) & 0xFF == ord('q'):            break
    else:        breakcap.release()
   

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
好用的视频编辑软件推荐
好用的视频编辑软件推荐

好用的视频编辑软件:1. Final Cut Pro X:适合Mac用户,专业级,配置要求高。2. iMovie:苹果设备自带,适合初学者。3. Adobe Premiere Pro:跨平台,功能强大,适合专业用户。4. DaVinci Resolve:专业调色软件,配置要求高。5. 爱剪辑:适合Windows初学者,功能丰富。6. 威力导演:适合Windows中级用户,支持360度视频编辑。

237

2025.04.15

好用的视频编辑软件推荐
好用的视频编辑软件推荐

好用的视频编辑软件:1. Final Cut Pro X:适合Mac用户,专业级,配置要求高。2. iMovie:苹果设备自带,适合初学者。3. Adobe Premiere Pro:跨平台,功能强大,适合专业用户。4. DaVinci Resolve:专业调色软件,配置要求高。5. 爱剪辑:适合Windows初学者,功能丰富。6. 威力导演:适合Windows中级用户,支持360度视频编辑。

237

2025.04.15

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

38

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

83

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

97

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

223

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

458

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

169

2026.03.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号