竞赛 深度学习YOLO抽烟行为检测 - python opencv
文章目录
- 1 前言
- 1 课题背景
- 2 实现效果
- 3 Yolov5算法
- 3.1 简介
- 3.2 相关技术
- 4 数据集处理及实验
- 5 部分核心代码
- 6 最后
1 前言
🔥 优质竞赛项目系列,今天要分享的是
🚩 基于深度学习YOLO抽烟行为检测
该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!
🥇学长这里给一个题目综合评分(每项满分5分)
- 难度系数:3分
- 工作量:3分
- 创新点:4分
🧿 更多资料, 项目分享:
https://gitee.com/dancheng-senior/postgraduate
1 课题背景
公共场合抽烟的危害很大,国家也相应地出台了在公共场合禁烟的政策。以前实行相关的政策都是靠工作人员巡逻发现并出言禁止,这样做效率很低下。计算机视觉领域发展迅速,而抽烟检测也属于一种计算机视觉目标检测的行为,可以采用目标检测的方法来实现。目前,目标检测在很多领域都取得显著成就,但是在抽烟检测领域方面进行研究却几乎没有。该研究可以有效节省成本,对公共场合禁烟政策的实行有很大的推动作用。
2 实现效果
左图为原图,右图为推理后的图片,以图片方式展示,视频流和实时流也能达到这个效果,由于视频转GIF大小原因,这里暂不演示。
3 Yolov5算法
3.1 简介
YOLO系列是基于深度学习的回归方法。该系列陆续诞生出YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5。YOLOv5算法,它是一种单阶段目标检测的算法,该算法可以根据落地要求灵活地通过chaneel和layer的控制因子来配置和调节模型,所以在比赛和落地中应用比较多。同时它有YOLOv5x、YOLOv5l、YOLOv5m、YOLOv5s四种模型。
具有以下优点:
- 在pytorch环境下编写;
- 可以很容易编译成ON⁃NX和Core ML;
- 运行速度很快,每秒可以达到140FPS的速度;
- 模型精度高;
- 集成了YOLOv3和YOLOv4的部分优秀特性,进行了推陈出新的改进。
3.2 相关技术
Mosaic数据增强
Mosaic数据增强技术采用了四张图片的随机缩放、随机剪裁、随机排布的方式对数据进行拼接,相比CutMix数据增强多用了两张图片。在目标识别过程中,要识别的目标有大目标、中等目标、小目标,并且三种目标的占比例不均衡,其中,小目标的数量是最多的,但是出现的频率很低,这种情况就会导致在bp时对小目标的优化不足,模型正确识别小目标的难度比识别中、大目标的难度要大很多,于是对于小目标来说很容易出现误检和漏检的情况。Mosaic数据增强技术做出改进后,上述的问题得到有效的解决。
该技术的优点是:
- 丰富了数据集,采用“三个随机”的方式对数据进行拼接丰富了检测的数据集,尤其是随机缩放增加了很多小目标,克服了小目标的不足,让网络的鲁棒性得到提高;
- 减少GPU的使用,在Mosaic增强训练时,四张图片拼接在一起,GPU可以直接计算四张图片的数据,让Mini-batch的大小减少了很多,这使得一个GPU就可以达到比较可观的效果。
自适应anchor
自适应anchor是check_anchors函数通过遗传算法与Kmeans迭代算出的最大可能召回率的anchor组合。在网络模型的训练过程中,网络在初始化的锚框的基础上输出预测框,然后与真实框groundtruth进行对比,计算两个框之间的差值,再根据差值进行反向更新,迭代网络参数,最后求出最佳的锚框值。自适应的anchor能够更好地配合网络训练,提高模型的精度,减少对anchor的设计难度,具有很好的实用性。
自适应图片缩放
为了提高模型的推理速度,YOLOv5提出自适应图片缩放,根据长宽比对图像进行缩放,并添加最少的黑边,减少计算量。该方法是用缩放后的长边减去短边再对32进行取余运算,求出padding。在训练时并没有采用缩减黑边的方法,该方法只是在测试模型推理的时候才使用,这样提高了目标检测的准确率和速度。
Focus结构
该结构采用切片操作,将特征切片成四份,每一份将当成下采样的特征,然后在channel维度进行concat。例如:原始608 608
3的数据图片,经过切片操作先变成304 304 12的特征图,再经过一次32个卷积核的卷积操作,变成304 304 32的特征图。
CSP结构
YOLOv5中的CSP[5]结构应用于两处,一处是CSP1_X结构应用于Backbone的主干网络中,另一处的CSP2_X结构应用于Neck中,用于加强网络的特征融合的能力。CSPNet主要从网络结构设计的角度解决推理中从计算量很大的问题。该结构的优点有:1)增强CNN的学习能力,使得模型在轻量化的同时保持较高的准确性;2)减低计算的瓶颈问题;3)减低内存的分险。
PFN+PAN结构
这个结构是FPN和PAN的联合。FPN是自顶向下的,将高层的特征信息通过上采样的方式进行传递融合,得到进行预测的特征图,而PAN正好与FPN的方向是相反的方向,它是自底向上地采取特征信息。两个结构各自从不同的主干层对不同的检测层进行参数聚合。两个结构的强强联合让得到的特征图的特征更加明显和清楚。
Bounding box的损失函数
Bounding
box损失函数[6]增加了相交尺度的衡量方式,有效缓解了当两个框不相交和两个框大小完全相同的两种特殊情况。因为当预测框和目标框不相交时,IOU=0,无法反应两个框距离的远近的时候,此时的损失函数不可导;两个框大小完全相同,两个IOU也相同,IOU_LOSS无法区分以上两种特殊情况。
nms非极大值抑制
在目标检测过程的后续处理中,对于大量的目标框的筛选问题,通常会进行nms操作,以此来达到一个不错的效果。YO⁃LOv5算法同样采用了加权的nms操作。
4 数据集处理及实验
数据集准备
由于目前针对吸烟图片并没有现成的数据集,我们使用Python爬虫利用关键字在互联网上获得的图片数据,编写程序爬了1w张,筛选下来有近1000张可用,以及其他途径获取到的,暂时可用数据集有5k张,
深度学习图像标注软件众多,按照不同分类标准有多中类型,本文使用LabelImg单机标注软件进行标注。LabelImg是基于角点的标注方式产生边界框,对图片进行标注得到xml格式的标注文件,由于边界框对检测精度的影响较大因此采用手动标注,并没有使用自动标注软件。
考虑到有的朋友时间不足,博主提供了标注好的数据集和训练好的模型,需要请联系。
数据标注简介
通过pip指令即可安装
pip install labelimg
在命令行中输入labelimg即可打开
5 部分核心代码
# data/smoke.yaml# COCO 2017 dataset http://cocodataset.org# Download command: bash yolov5/data/get_coco2017.sh# Train command: python train.py --data ./data/coco.yaml# Dataset should be placed next to yolov5 folder:# /parent_folder# /coco# /yolov5# train and val datasets (image directory or *.txt file with image paths)train: data\train.txt # 上面我们生成的train,根据自己的路径进行更改val: data\test.txt # 上面我们生成的test#test: ../coco/test-dev2017.txt # 20k images for submission to https://competitions.codalab.org/competitions/20794# number of classesnc: 1 #训练的类别# class namesnames: ['smoke']# Print classes# with open('data/coco.yaml') as f:# d = yaml.load(f, Loader=yaml.FullLoader) # dict# for i, x in enumerate(d['names']):# print(i, x)# model/yolov5s.yaml# parametersnc: 1 # number of classesdepth_multiple: 0.33 # model depth multiplewidth_multiple: 0.50 # layer channel multiple# anchorsanchors:- [116,90, 156,198, 373,326] # P5/32- [30,61, 62,45, 59,119] # P4/16- [10,13, 16,30, 33,23] # P3/8# YOLOv5 backbonebackbone:# [from, number, module, args][[-1, 1, Focus, [64, 3]], # 0-P1/2[-1, 1, Conv, [128, 3, 2]], # 1-P2/4[-1, 3, BottleneckCSP, [128]],[-1, 1, Conv, [256, 3, 2]], # 3-P3/8[-1, 9, BottleneckCSP, [256]],[-1, 1, Conv, [512, 3, 2]], # 5-P4/16[-1, 9, BottleneckCSP, [512]],[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32[-1, 1, SPP, [1024, [5, 9, 13]]],]# YOLOv5 headhead:[[-1, 3, BottleneckCSP, [1024, False]], # 9[-1, 1, Conv, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 6], 1, Concat, [1]], # cat backbone P4[-1, 3, BottleneckCSP, [512, False]], # 13[-1, 1, Conv, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 4], 1, Concat, [1]], # cat backbone P3[-1, 3, BottleneckCSP, [256, False]],[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]], # 18 (P3/8-small)[-2, 1, Conv, [256, 3, 2]],[[-1, 14], 1, Concat, [1]], # cat head P4[-1, 3, BottleneckCSP, [512, False]],[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]], # 22 (P4/16-medium)[-2, 1, Conv, [512, 3, 2]],[[-1, 10], 1, Concat, [1]], # cat head P5[-1, 3, BottleneckCSP, [1024, False]],[-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]], # 26 (P5/32-large)[[], 1, Detect, [nc, anchors]], # Detect(P5, P4, P3)]# 训练部分主函数if __name__ == '__main__':check_git_status()parser = argparse.ArgumentParser()parser.add_argument('--epochs', type=int, default=300)parser.add_argument('--batch-size', type=int, default=16)parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='*.cfg path')parser.add_argument('--data', type=str, default='data/smoke.yaml', help='*.data path')parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='train,test sizes')parser.add_argument('--rect', action='store_true', help='rectangular training')parser.add_argument('--resume', action='store_true', help='resume training from last.pt')parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')parser.add_argument('--notest', action='store_true', help='only test final epoch')parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')parser.add_argument('--weights', type=str, default='', help='initial weights path')parser.add_argument('--name', default='', help='renames results.txt to results_name.txt if supplied')parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--adam', action='store_true', help='use adam optimizer')parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%')parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset')opt = parser.parse_args()opt.weights = last if opt.resume else opt.weightsopt.cfg = check_file(opt.cfg) # check fileopt.data = check_file(opt.data) # check fileprint(opt)opt.img_size.extend([opt.img_size[-1]] * (2 - len(opt.img_size))) # extend to 2 sizes (train, test)device = torch_utils.select_device(opt.device, apex=mixed_precision, batch_size=opt.batch_size)if device.type == 'cpu':mixed_precision = False# Trainif not opt.evolve:tb_writer = SummaryWriter(comment=opt.name)print('Start Tensorboard with "tensorboard --logdir=runs", view at http://localhost:6006/')train(hyp)# Evolve hyperparameters (optional)else:tb_writer = Noneopt.notest, opt.nosave = True, True # only test/save final epochif opt.bucket:os.system('gsutil cp gs://%s/evolve.txt .' % opt.bucket) # download evolve.txt if existsfor _ in range(10): # generations to evolveif os.path.exists('evolve.txt'): # if evolve.txt exists: select best hyps and mutate# Select parent(s)parent = 'single' # parent selection method: 'single' or 'weighted'x = np.loadtxt('evolve.txt', ndmin=2)n = min(5, len(x)) # number of previous results to considerx = x[np.argsort(-fitness(x))][:n] # top n mutationsw = fitness(x) - fitness(x).min() # weightsif parent == 'single' or len(x) == 1:# x = x[random.randint(0, n - 1)] # random selectionx = x[random.choices(range(n), weights=w)[0]] # weighted selectionelif parent == 'weighted':x = (x * w.reshape(n, 1)).sum(0) / w.sum() # weighted combination# Mutatemp, s = 0.9, 0.2 # mutation probability, sigmanpr = np.randomnpr.seed(int(time.time()))g = np.array([1, 1, 1, 1, 1, 1, 1, 0, .1, 1, 0, 1, 1, 1, 1, 1, 1, 1]) # gainsng = len(g)v = np.ones(ng)while all(v == 1): # mutate until a change occurs (prevent duplicates)v = (g * (npr.random(ng) < mp) * npr.randn(ng) * npr.random() * s + 1).clip(0.3, 3.0)for i, k in enumerate(hyp.keys()): # plt.hist(v.ravel(), 300)hyp[k] = x[i + 7] * v[i] # mutate# Clip to limitskeys = ['lr0', 'iou_t', 'momentum', 'weight_decay', 'hsv_s', 'hsv_v', 'translate', 'scale', 'fl_gamma']limits = [(1e-5, 1e-2), (0.00, 0.70), (0.60, 0.98), (0, 0.001), (0, .9), (0, .9), (0, .9), (0, .9), (0, 3)]for k, v in zip(keys, limits):hyp[k] = np.clip(hyp[k], v[0], v[1])# Train mutationresults = train(hyp.copy())# Write mutation resultsprint_mutation(hyp, results, opt.bucket)# Plot results# plot_evolution_results(hyp)
6 最后
🧿 更多资料, 项目分享:
https://gitee.com/dancheng-senior/postgraduate
相关文章:

竞赛 深度学习YOLO抽烟行为检测 - python opencv
文章目录 1 前言1 课题背景2 实现效果3 Yolov5算法3.1 简介3.2 相关技术 4 数据集处理及实验5 部分核心代码6 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习YOLO抽烟行为检测 该项目较为新颖,适合作为竞赛课…...

cAdvisor监控Docker容器做性能测试
cAdvisor监控Docker容器做性能测试 缘起 当前有个服务做技术选型,服务要求比较高的性能,要做性能测试。部署的环境是容器话部署,但申请新的容器流程较长,于是我打算在流程走完之前简单评估下性能,来确定技术选型是否…...

记一次EDU证书站
如果文章对你有帮助,欢迎关注、点赞、收藏一键三连支持以下哦! 想要一起交流学习的小伙伴可以加zkaq222(备注CSDN,不备注通不过哦)进入学习,共同学习进步 目录 目录 1.前言: 2.信息搜集 3.漏…...
React高频面试题100+题,这一篇就够了!
1 - 5 题详解传送门>>>>>>>>>>>> 1. 如何在代码中判断一个 React 组件是 class component 还是 function component? 2. useRef / ref / forwardsRef 的区别是什么? 3. useRef和useState区别? 4. useEffect 的…...

mysql MVC jsp实现表分页
mysql是轻量级数据库 在三层架构中实现简单的分页 在数据库sql编程中需要编写sql语句 SELECT * FROM sys.student limit 5,5; limit x,y x是开始节点,y是开始节点后的需要显示的长度。 在jdbc编程中需要给出x和y 一般是页数*页码,显示的长度。 代…...

【微信小程序】数字化会议OA系统之首页搭建(附源码)
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《微信小程序开发实战》。🎯Ἲ…...

Leetcode——二维数组及滚动数组练习
118. 杨辉三角 class Solution { public:vector<vector<int>> generate(int numRows) {// 定义二维数组vector<vector<int>> num(numRows);for(int i0;i<numRows;i){//这里是给内层vector定义大小。默认是0,这里n是个数,不是值num[i].re…...

钢水包升降翻转液压系统比例阀放大器
钢水包升降翻转液压系统是一种用于控制钢水包升降和翻转的液压系统。该系统主要由液压泵、液压缸、控制阀和一些辅助元件组成。 钢水包升降翻转液压系统的液压泵将油从油箱中抽出,将油压力提高到一定值,然后通过控制阀将油分配到液压缸中。液压缸内的活…...
通达OA-通用版-V12,流程及表单自定义好用的类
通达OA-通用版-V12,流程及表单自定义好用的类 V1.0 V1.0 日期:2023年10月19日 新建类文件,将下面代码复制到文件中即可。 功能说明: 1、根据flow_id,可以获取流程表单相关的表名、及字段名。 2、根据run_id࿰…...
如何在vue中实现图片懒加载
1.什么是图片懒加载 概念当图片还未出现在浏览器的可视区,图片并不加载src所引入的图片资源。只有当图片出现在可视区时,才加载图片资源。 好处:当页面中需要许多图片进行展示。但是,在我们不可视区的图片我们可以进行图片懒加载…...

Mac 远程桌面软件
对于使用 Mac 计算机和笔记本电脑的企业来说,适用于 Mac 的远程桌面软件变得越来越重要,随着远程工作变得越来越普遍,IT 管理员和组织需要一种安全的方式来访问和修复问题、处理紧急任务以及监控远程工作站的状态,为了促进远距离协…...

EPLAN_005#宏边框、页宏、窗口宏/符号宏
一、宏边框 红边框不能用,变成了灰色 要在项目属性中更改位宏项目——才能使用宏边框功能 注意:创建宏边框时候要打开——显示隐藏元素 框选目标后,双击红边框的边——弹出红边框创建属性对话框——输入名称——更改变量ABC等 最后——自动…...

如何正确地使用ChatGPT(角色扮演+提示工程)
如何正确地使用ChatGPT 一、ChatGPT介绍二、准备工作2.1 获取ChatGPT环境2.2 确定使用ChatGPT的目标和需求 三、重要因素3.1 角色赋予3.2 提示工程 四、正确案例 一、ChatGPT介绍 可以查阅ChatGPT快速入门 二、准备工作 2.1 获取ChatGPT环境 国外的有OpenAI和微软NewBing等…...

MySQL服务安装与登录
(1)以管理员身份启动命令提示符: (2)定位到安装目录的bin目录下(根据自己的安装路径进行调整即可)。先输入“d:”,定位到d盘,输入cd空格文件路径(直接复制粘贴…...

论文阅读之《Kindling the Darkness: A Practical Low-light Image Enhancer》
目录 摘要 介绍 已有方法回顾 普通方法 基于亮度的方法 基于深度学习的方法 基于图像去噪的方法 提出的方法 2.1 Layer Decomposition Net 2.2 Reflectance Restoration Net 2.3 Illumination Adjustment Net 实验结果 总结 Kindling the Darkness: A Practical L…...

性能测试基础知识及性能指标
前言:最近公司接了个项目,领导开会突然来了句,让我出一份性能测试方案,后面性能测试工作交给我!我心里想之前面试没要求会这个啊(最少得加钱才能做吧~,没办法既然下达了指令,那就只能…...

ArcGIS笔记10_如何创建渔网?
本文目录 前言Step 1 确定渔网的精度单位Step 2 有底图时创建渔网的操作 前言 ArcGIS中的渔网是一个很好用的工具,它可以创建出规规整整的小格子,每个小格子都对应一个标注点,可以将原本散乱的数据规整化,如下图: Ste…...

Jmeter安装(快速入门)
大家好我是苏麟今天简单聊一下Jmeter . Jmeter Jmeter官网 : Apache JMeter - Download Apache JMeter 安装Jmeter Jmeter依赖于JDK,所以必须确保当前计算机上已经安装了JDK,并且配置了环境变量。 下载 : 官网下载 : 网盘自取 : 链接:…...
一个react前端项目中的配置文件作用解析
前端框架中用到的配置文件 .editorconfig, .gitignore, .npmrc, .prettierignore, .prettierrc, .umirc.local.ts, .umirc.ts, package-lock.json, package.json, README.md, tsconfig.json, typings.d.ts, webpack.config.js.editorconfig:用于定义代码编辑器的配…...
MAC 配置 Maven
Maven 是一个流行的 Java 项目管理和构建工具,它可以帮助我们管理项目依赖、构建和发布等过程。本文将指导您在 MAC 上配置 Maven 的详细步骤。 1、下载 Maven 首先,从 Maven 官方网站下载最新版本的 Maven 安装包。下载完成后,将其解压到您…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...