☰
深度学习与YOLO实战:监控场景下抽烟、打电话、玩手机行为识别
2026/10/9 6:22:00 网站建设 项目流程

这期项目我前后跑了两轮,一轮是在加油站场景做禁烟禁手机告警,一轮是在一家工厂的办公区做员工行为审计。踩了不少坑之后,想把这套“深度学习CNN人员行为识别 + YOLO目标检测”的完整思路梳理出来,重点聊聊公共场合下抽烟、打电话、玩手机、饮酒这四类行为到底怎么检测、怎么训练、怎么部署才不会翻车。

内容适合正在做监控场景行为分析、企业内部合规系统,或者拿图像识别方向做毕业设计的人参考。我会把技术选型、数据集构造、训练参数、部署联动和排查经验都写清楚,尽量做到你看完就能照着落地一套。

1. 项目定位与技术选型思路拆解

1.1 项目到底要解决什么问题

公共场合的人员行为识别,本质上是一个“违规行为自动发现”的问题。比如加油站、化工厂、厨房、商场监控、银行柜台,都有明确的行为规范,靠人盯屏幕根本盯不过来,一个保安同时看16路监控,注意力最多撑20分钟。这套系统要做的就是:通过摄像头画面,自动判断画面里的人是不是在抽烟、打电话、玩手机或者饮酒,一旦出现就触发告警。

这里有一个很关键的设计问题:这四类行为并不是同一粒度的检测任务。抽烟和打电话的目标特征相对明确——香烟是一个小目标,手机贴在耳边是一个组合特征;玩手机则要看手持姿态和低头动作;饮酒涉及杯子、酒瓶、仰头动作,环境干扰非常大。所以不能寄希望于某一个简单模型一次搞定,而是要按“目标检测 + 行为逻辑判定”两层来设计。

第一层用目标检测框架找出人以及关联物体,第二层通过物体位置关系、时序帧上下文确认行为。这也是为什么我会把YOLO作为核心检测器的原因。

1.2 为什么选择YOLO而不是其他目标检测方案

如果你查过目标检测的演进,会看到Faster R-CNN、SSD、YOLO、DETR这些路线。Faster R-CNN精度高但单帧推理在CPU上要几百毫秒,SSD速度上去了但小目标检测稀烂,DETR这类Transformer方案在监控这种密集小目标场景性价比不高。YOLO是速度与精度平衡得最好的路线,尤其是YOLOv5到YOLOv8这一代,工程化程度已经很高了,导出ONNX、TensorRT都是顺手的事。

很多人问CNN和YOLO到底什么关系。说白了,YOLO的骨干网络(backbone)本来就是CNN——YOLOv8用的是CSPDarknet结构,特征提取全靠卷积层堆叠;YOLO只是在CNN输出的特征图上加了检测头,把“分类”和“回归框”放到同一个网络里做端到端预测。所以标题里“深度学习CNN人员行为识别”“YOLO目标检测”其实是一条链路上的东西,不是两个并列的独立方案。

1.3 为什么不选姿态估计加行为识别的重型方案

我一开始犹豫过要不要上OpenPose加ST-GCN那种骨架行为识别。后来实践下来发现,在监控场景里这套方案有两个硬伤。第一个是遮挡和低分辨率——监控摄像头离人远,骨架点经常断,一下雨或者逆光基本废掉。第二个是算力成本——姿态估计模型参数量大,单路视频在边缘盒子上跑不满实时。

相比之下,目标检测出框、再用业务规则归类行为,鲁棒性反而更好。比如打电话,我不需要知道手臂关节在哪,只要在人的头部附近检测到手机目标,且持续若干帧,就判为打电话。这是把“理解行为”降维成“检测目标 + 位置校验”,工程上极其可行,而且可解释性强,运营人员看到告警截图时一眼就知道为什么报警。

2. 四类行为的检测难点与CNN识别要点

2.1 抽烟检测:小目标才是真麻烦

抽烟检测的核心目标是香烟和烟雾。香烟在监控画面里通常只有十几个像素,属于典型的小目标检测难题。这里有个生活化类比:你在一张全家福里找一个人手里的硬币,找不到不是因为不认识硬币,而是因为硬币太小、被手指遮挡、光线还差。

我试过两种路线。一种是把“嘴部附近有香烟状细长物体”作为检测条件,单独标注烟支,效果在距离5米内的近景还凑合;另一种是直接标注“手持香烟”的完整行为框,把烟、手、嘴部区域作为一个整体来学。实际表现是第二种明显更稳,因为模型学到的是组合特征,比只盯烟支更有上下文。提醒一下,嘴唇、潮湿的烟头在红外夜视下会形成小亮点,对小目标检测反而有帮助,但白天取景距离远了就完全不行。如果摄像头视角离人超过8米,建议放弃香烟本体的检测,只做“手到嘴部区域”的动作判断。

抽烟检测里烟雾也是重要线索,但我不建议主模型直接学烟雾特征。烟雾形状飘忽不定,标注成本极高,而且抽电子烟的烟雾和抽烟烟雾模型根本分不出来。烟雾可以留给后处理逻辑做二次确认,不作为主判定条件。

2.2 打电话与玩手机:看起来像,本质不一样

打电话和玩手机共享一个目标——手机。但二者在姿态上有明显差异:打电话时手机贴近耳朵、屏幕朝内、手部抬起;玩手机时手机在胸前或腹部高度、头部低垂、视线朝下。这个差异可以通过检测框的位置关系来数字化判定。

我在设计时定义了两个虚拟区域:耳部区域和胸腹区域。用人体检测框把人头位置估算出来,头部侧上方的矩形区域称为“耳区”,脖子以下到腰的矩形区域称为“手持区”。当手机框中心和耳区中心重叠时,判为打电话;当手机框落在手持区且持续超过1秒时,判为玩手机。注意,这两个规则不是用if-else硬写死,而是把这个相对位置作为额外通道输入到模型辅助分类,让CNN自己学习位置关系。不过实测下来,纯规则判定其实更可控,因为误报可以直接定位原因,而网络学到的隐式特征出问题时你根本不知道它到底在学什么。

还有一个特殊场景:司机打电话。方向盘区域的手持电话容易被方向盘、衣物遮挡,单纯目标检测漏检率会比较高。这个业务场景更推荐在驾驶员座位上方架设专门摄像头做近景识别,角度固定后检测难度会显著下降。

2.3 饮酒检测:从目标识别到行为联动的完整链路

饮酒是四类行为里最难的一类,因为酒瓶、酒杯、饮料瓶、保温杯在视觉特征上经常撞车。咖啡、奶茶、碳酸饮料跟啤酒鸡尾酒在目标检测层面几乎无法区分。我不建议模型去识别“酒”本身,而是应对“举杯饮酒”这个动作做检测。

具体来说,标注三类目标:容器(杯子/瓶子)、嘴巴区域、仰头动作。判定条件简化成:容器出现、容器与嘴部重合、头部后仰且容器倾斜,三个条件同时满足时判为饮酒。在餐厅、烧烤店这些场景,默认场景内大部分容器都是饮品,检测到举杯动作后按饮酒上报,由人工二次确认,准确率反而比试图区分酒与非酒要实用得多。

这个思路其实暴露了一个很值得说的点:行为分析系统不一定要“认出物体是什么”,它更关心“人的动作状态是什么”。这一整类项目都遵循同样的逻辑——目标检测负责找目标,行为理解负责判状态,CNN在中间把两者联通起来。

3. 数据准备与模型训练的实操记录

3.1 训练数据从哪里来、怎么标注

训练数据的质量和数量决定了这个项目的上限。我见过太多人上来就找公开数据集凑合,结果跑起来误报漏报双高,然后又开始疯狂调阈值,最后调没了。数据这关不过,后面全是白干。

我的做法分三路收集:

  • 公开数据集打底。COCO数据集里有人、手机、酒杯、瓶子这些类别,先用它做预训练,让模型认识基础目标。
  • 自采场景数据。在目标场景部署临时相机,连续录一周不同时段的视频,截帧筛选有效画面。这一路最关键,因为监控视角是俯视或斜视,跟COCO里那些平视生活照完全两个分布。
  • 网络爬取补充。搜刮监控视角下的抽烟、打电话、饮酒图片,用来补充口罩遮挡、夜晚红外、阴雨等长尾场景。

标注规范上踩过几次坑,分享四点:第一,打电话和玩手机必须分开打标签,不要全打“phone”;第二,香烟目标再小也要标,不要因为难标就放弃,不然模型更学不会;第三,打标签时如果目标被遮挡超过60%,可以放弃标注,硬标会教坏模型;第四,同一类行为在不同距离的表现差异很大,建议按近、中、远三个距离分层标注,避免模型只认识近距离目标。

工具我用的是LabelImg和LabelStudio,前者轻量适合单人标框,后者适合多人协作且支持视频帧标注。标注完成后要把数据转成YOLO格式:每个图片对应一个txt,每行是class x_center y_center width height,坐标值是相对图片宽高的归一化结果。

3.2 训练参数配置与CNN调优细节

我用的基准模型是YOLOv8n和YOLOv8s,分别在两轮试验里跑过。具体训练配置如下:

参数设置值说明
输入分辨率640×640常规监控场景够用;若香烟目标太小可上1280
batch size16显存允许就调大一点,BN层更稳定
epochs200到150轮左右观察是否过拟合,可提前早停
初始学习率0.01用余弦退火降到0.0001
优化器SGDAdam收敛快但最终精度一般不如SGD
数据增强mosaic=1.0, hsv_h=0.015, fliplr=0.5默认增强够用,不要盲目加旋转
置信度阈值0.3~0.4训练完推理时再调
NMS IoU0.5默认值

这里重点讲讲为什么分辨率不建议无脑调大。有人觉得既然香烟是小目标,那就把输入调到1280,精度确实涨了一点,但推理耗时暴涨到原来的三倍,边缘设备上根本顶不住。后来我改用了一种折中方案:主模型用640输入做全画面检测,同时把画面切成四块,用同一个模型对每块区域做一次放大检测,把小块结果合并回去。这个做法类似于滑动窗口,利用率直接翻倍,两阶段合起来精度提升明显,代价只是多三倍推理耗时,在NVIDIA Jetson Orin这类设备上依然可以做到实时。

训练过程中我会盯三个东西。第一是box_loss和cls_loss曲线,如果二者都在稳步下降,说明模型在学;第二是验证集mAP@0.5,这是判断能不能上线的最重要指标;第三是混淆矩阵,重点看抽烟和打电话有没有互混。有一次我碰到模型把拿口红的手误判成抽烟,查看混淆矩阵才发现真值里口红类样本太少,模型学到的是“手部有细长物体就报警”,后来补充了大量口红、笔、筷子、香烟易混样本做难例挖掘,问题才消停。

数据增强上有一点心得:不要过度依赖mosaic增强。因为香烟这种小目标在mosaic切图之后经常被裁掉一半,反而影响学习。我最后把mosaic概率从默认的1.0降到0.5,配合复制粘贴增强(把小目标复制到其他位置),小目标的召回率提升非常明显。

3.3 类别不均衡的处理思路

四类行为的出镜频率完全不一样。抽烟和玩手机在场景里高发,打电话偶发,饮酒在非餐饮场景里基本不出现。如果不处理,模型会把饮酒类直接忽略。我除了做复制粘贴增强之外,还在损失函数上做了处理:YOLOv8里可以通过修改类别权重来给低样本类别更大的loss贡献,weights=[1.0, 1.0, 1.2, 2.0]这种思路,按实际样本比例反比设置。另外要注意,评估时别只看整体mAP,要把每个类别的AP分开看,尤其关注饮酒类的AP是否达到可用水平。

4. 部署链路与业务联动设计

4.1 从RTSP取流到告警输出的完整管线

模型训完之后,部署才是真正考验工程能力的部分。我的部署链路长这样:

  1. 摄像头RTSP流转拉流。推荐用FFmpeg或GStreamer拉流,海康、大华、宇视都兼容。
  2. 抽帧处理。不需要每帧都推理,一般5到10帧取一帧做检测即可。抽烟时一个动作持续数秒,5fps的检测频率足够。
  3. 推理加后处理。模型输出原始检测框,经过NMS去重之后,送入行为判定逻辑。
  4. 业务逻辑判定。单帧检测结果不可直接触发告警,因为抖动会造成误报。我用“连续N帧检测到同一目标ID”加“行为框与目标框位置稳定”作为去抖条件,N通常取3,目标ID用IoU追踪匹配跨帧。
  5. 上传告警事件。把行为类别、时间、截图、摄像头编号封装成事件,推送到MQTT或Rest接口。

说个抽帧频率的细节:玩手机的“低头”动作在单帧里就能稳定识别,但饮酒的“举杯仰头”有瞬时性,5fps可能会漏掉动作峰值。我的处理是把饮酒检测单独提到3fps,或者用短时缓存队列,把告警触发前的10帧画面存下来,行为判定确认后打包回传。这个思路也方便事后人工复核——截一个单帧利落,但完整短视频更有说服力。

4.2 算力选型与模型加速

部署硬件我主要用了两块。一块是NVIDIA Jetson Orin,适合改造监控箱体的边缘场景,功耗低,不用把视频回传中心机房;一块是服务器上的RTX 4090,适合集中式处理多路视频。

Jetson上跑YOLOv8,强烈建议导出TensorRT引擎做加速。官方提供的推理代码直接跑PyTorch模型,速度大约15到20毫秒一帧,但换成TensorRT FP16之后可以压到5毫秒左右,翻了三倍。导出时要注意输入尺寸和动态batch不要乱开,固定尺寸最省事。在导出ONNX再转TensorRT时,YOLOv8的输出层是有个1×25600×4+80的结构,后处理脚本要配套改,这一步网上教程写的少,实际卡住很多人。我直接建议用ultralytics里的model.export(format="engine", half=True, dynamic=False, imgsz=640),一条命令搞定,省得手写解析。

4.3 告警联动与隐私合规的平衡

告警不能只弹屏,要有完整的处理闭环。我的方案是:识别到违规行为后,系统自动截图并裁剪行为人区域,打上行为标签和时间水印,推送到值班群;同时调用现场IP喇叭播放语音提示,比如加油站场景直接播放“本区域禁止吸烟,请立刻熄灭烟头”。这个联动动作要迅速,等管理者赶到现场,烟早就抽完了。

隐私合规也要重视。按照公共场合视频监控的使用规范,检测结果只做事件化呈现,不保存原始视频流;人脸可以打马赛克,只保留人体框和行为证据。技术上完全可行,在检测框后加一个人脸检测模块,检测到人脸区域直接高斯模糊,再进入后续流程。做合规系统的底线是监控不是为了整人,而是为了把风险行为管理起来,这个定位一定不能偏。

5. 常见问题与排查技巧实录

5.1 高误报场景的成因与对策

误报是我被运营方吐槽最多的问题。拿手边的水瓶当饮酒、拿口红当香烟、抱臂姿势但手里刚好有手机被当成玩手机,这些误报几乎都来自样本外的相似目标。对策就一条:做负样本采集和难例挖掘。把误报截图积累下来,按周打标签,加入训练集的背景类或增加易混类标注,持续迭代,两周后误报率至少能降一半。

再说一个特殊的误报场景:弯腰系鞋带。手部在低处,从特定角度看特别像低头玩手机。这种用纯目标检测很难避免,我的解决方式是加姿态先验——结合人体框的宽高比变化判断人是站立状态还是弯腰状态。实测下来弯腰状态人手部到头部距离和玩手机的位置关系有明显区别,自定义规则把这类样本过滤掉之后,误报率明显下降。

5.2 光线、遮挡与运动模糊的应对

夜间红外模式下,手机屏幕是画面里的高亮点,目标检测还比较友好;但红外的颜色信息几乎丢失,饮酒检测看的是液面和瓶身形状,误检概率会上升。我的做法是给夜间场景单独训练一版模型,用红外视频做数据增强和微调,不要和图日模型混用。

运动模糊是另一个大坑。人在走动时接电话、边走边抽烟,检测框经常拖影。在处理端可以把抽帧的曝光时间调小,或者用视频流隔帧取不同时刻做“去模糊融合”,但工程实施复杂。我先用了一个更简单的办法:只在这些高频行为多发区用更密的抽帧策略,比如出入口、走廊尽头这些位置,命中率提升明显。

5.3 多路视频并发的瓶颈优化

我踩过一个印象很深的坑:64路监控全部接入,GPU直接被打满,推理队列越堆越长,告警延迟从2秒涨到40秒。后来做了两点优化。一是路由分流,把64路分为4组,每16路一个推理进程,进程间用共享队列通信,理论上可以水平扩展;二是ROI区域过滤,很多摄像头画面里只有一个小角落是管控区域,用坐标框把非管控区域裁剪掉,检测量直接降70%。

另一个建议是根据业务优先级分级处理。加油站枪位附近是最高优先级,通道、停车场是低优先级,高优先级满帧检测,低优先级降采样到1fps。这样既保证了核心区域零漏检,又不会把整机算力打爆。

5.4 训练部署便于复用的速查表

我把这两轮项目里沉淀的常用参数整理成了一张速查表,适合做同类项目的同学直接抄作业:

问题现象排查方向
小目标漏检香烟检测率低提高输入分辨率、滑动窗口切图、降低mosaic概率
类别互混打电话/玩手机混淆检查混淆矩阵、补充姿态差异样本、细化标注边界
夜间误报红外下误检率升高单独训练夜间模型、增加屏幕高亮点样本
告警抖动同一行为反复触发连续N帧确认、IoU目标追踪、设置冷却时间
推理延迟GPU占用过高抽帧降频、TensorRT加速、ROI裁剪、任务分片
饮酒不识别酒杯/水瓶不分改检测举杯动作、不分类酒水容器、结合区域业务规则

这张表不是理论推演,是实实在在踩出来的。如果你正在做类似的项目,建议直接把它打印出来贴工位上,遇到问题先对表排查,能省下大量瞎折腾的时间。

最后再分享一点个人体会:公共场合行为分析这类项目的落地难点从来就不在模型结构,而在数据分布、场景适配和业务规则的交叉处。不要迷信某个最新的YOLO版本能让所有问题消失,真正管用的还是把数据吃透、把判定逻辑设计得可解释、把部署链路打磨到稳健。这套方法我后面还在扩展,比如把检测到的行为结果按时间线做轨迹分析,用来发现更长期的行为规律,这又是另一个有意思的话题了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询