每年都有工地因为“看着没事”出事:电焊火花溅到保温棉上,两三分钟不起眼,等冒了浓烟,现场早已尘埃落定。传统的人工盯守、烟雾传感器报警,在露天、半露天的施工现场始终有盲区。这也是我这套基于图像识别技术的建筑施工安全监测系统立项的直接原因——用摄像头把工地变成一块主动感知的场地,对场地烟雾明火、裸土未覆盖、工地土堆与水坑等场景做实时识别和自动报警。
这套系统落在了“智慧工地”与“智慧城市”的交汇点上,解决的不只是工地内部的动火安全,还包括被很多人忽略的环保合规问题:裸土不覆盖、渣土堆无苫盖、积水坑长期存在,这些在城市监管平台上都是扣分项。整篇文章我会把项目的技术选型、算法方案、数据标注、部署配置到误报排查的完整过程摊开讲,适合正在做智慧工地、安全生产监管相关项目,或者想了解视觉识别在工业场景落地的同学参考。
1. 项目背景与核心思路
1.1 从行业痛点拆解:为什么建筑施工安全监测盯上了机器视觉
我在工地现场蹲过很长时间,说几个真实感受:工地是一个“强动态、多目标、多遮挡”的场所,塔吊移动、人员走动、材料堆放、光影变化,画面里几乎没有静止的时候。传统传感器在这里表现得非常吃力,比如烟雾传感器装在室内能管事,但户外动火点、电焊烟尘、防水卷材加热产生的烟气,往往在传感器报警前就已经蔓延了。
另一个痛点是环保监管。建筑施工的裸土未覆盖问题是城市扬尘的主要来源之一,监管人员按图斑核查、无人机补拍,存在明显的滞后性。而土堆、水坑这类形态不规则的场景,依靠人力巡查效率极低,且雨后、夜间还会反复出现。
机器视觉在工地场景有一个天然优势:摄像头基础设施已经存在,现场基本都有塔吊球机、立杆枪机和围挡摄像头,只需要把视频流接入算法服务,就能在已有的资源上叠加出感知能力。不需要铺设大量物理传感器,也不需要工人改变作业习惯——这是项目能够低门槛推进的根本原因。
1.2 系统要识别的“四大目标”和我的方案取舍
这套系统的核心识别对象有四类:场地烟雾、明火、裸土未覆盖、土堆与水坑。前两者直接关系消防和生产安全,后两者主要面向环境保护监测。
很多人刚接触时劝我把四类目标做成一个大模型,统一识别。我实际做了对比后放弃了这个方案。原因是:烟雾、明火和裸土、水坑在视觉特征上几乎没有共性。烟雾是非刚体、半透明、无固定轮廓的目标,明火则有强烈的颜色特征和闪烁频率;裸土和水坑主要是地面语义分割问题,关注的是区域边界和大面积占比。把完全不同的任务硬套在一个检测头下,训练收敛慢,调参难度大,线上误报互相干扰。
最终方案是拆成两个任务:a) 目标检测任务负责烟雾和明火,b) 语义分割任务负责裸土、土堆和水坑。两个模型独立训练、独立部署,中间只共享同一路视频流和同一个告警平台。这个决策为核心效果——两类场景的识别率都做到了较高水平,且互不拖累。
2. 算法选型与模型训练细节
2.1 目标检测框架怎么选,为什么我最终落在YOLO系上
烟雾和明火这类目标对实时性要求较高,现场报警链路从视频帧进入算法到推送告警,理想延迟应该控制在3秒以内。目前主流的目标检测框架中,两阶段检测器精度高但速度偏慢,不适合多路摄像头并行推理;而单阶段的YOLO系天然适合工地这类多路视频流场景。
我用过的方案包括YOLOv5、YOLOv8和YOLO11,最终线上保留了YOLO11和YOLOv8两个版本并行对比。YOLOv8在公开数据集上表现稳定,部署资料也多,遇到问题容易查;YOLO11在烟雾这类小目标上召回率略好,但需要更新的部署工具链。如果团队还在追赶进度,我建议先上YOLOv8,把数据标注的功夫做扎实,比盲目上新模型更有收益。
还需要说明的是,工地场景的摄像头高度、角度、分辨率差异极大,模型泛化能力比算法结构本身更关键。同样是冒烟场景,塔吊球机上看到的和立杆枪机上看到的,尺度差异超过10倍。因此我用了多尺度训练策略,把输入图像缩放到640到1280像素区间随机变换,让模型见过不同距离下的目标形态。
2.2 烟雾与明火检测:最难的不是识别,而是“不像”
烟雾检测在CV领域是个公认的硬骨头。为什么难?三个原因:形变无规律、透明度叠加、背景复杂。烟雾没有固定的形状和纹理,它是在不断卷动、扩散的;同时烟雾是半透明的,背景里的塔吊、脚手架、建筑物会透过烟雾显示出来,模型学到的特征非常不稳定;工地背景中还有大量和烟雾低层特征接近的物体,比如灰白色的水泥墙面、扬尘和雾霾。
另一个更隐蔽的问题是时间上下文。单帧图像里,一团刚升起的水蒸气和远距离的烟气在视觉上很难区分。我在模型之外加了一个轻量级的时序校验层:连续多帧在同一区域都检测到烟雾目标,才触发报警。这个设计把因为单帧误判导致的告警量压低了至少一半。
明火检测相对烟雾要简单,但有它自己的坑。用RGB三通道特征直接训练,火焰和红色安全帽、红色围挡、橙色反光衣极度混淆。我实践下来效果最好的做法是融合HSV色彩空间特征:在HSV空间中提取高饱和度的红橙色区域,再配合帧间差分计算闪烁频率。火焰的闪烁频率大概在8到12赫兹区间,人工光源和红色物体则不具备稳定的高频闪烁特征,利用这一点可以筛掉绝大多数误检。
2.3 裸土未覆盖与水坑识别:地面语义分割的三种做法
裸土检测最初我尝试用目标检测框来做,效果很差。因为裸土不是一个“物体”,它是大片连续的地面区域,边界不规则且常常与硬化路面交错。框的形式要么只框了局部,要么把周边硬化路面也包了进来,算覆盖率时偏差很大。
后来换成语义分割方案,模型训练到多轮后,对“地面类”区域的分割稳定度明显提升。当前主要对比了两种语义分割框架:以DeepLabV3为代表的分割头和以SegFormer为代表的分支。从实际精度和推理速度来看,对工地这种场景,DeepLabV3配合轻量级主干可以做到速度和精度的平衡;SegFormer在细粒度边界上略有优势,但显存占用更高,多路视频并行推理时压力较大。
水坑识别有它独特的一面。水坑本质上是一个“颜色偏暗且有倒影”的地面区域,但雨后路面反光、未干透的混凝土表面、塑料膜覆盖物都会产生类似特征。我在分割输出的基础上,又加了两层判定:一是水面反射的天空颜色特征,水坑会反射天空光,在图像中呈现偏蓝或偏白的色相;二是位置上下文,水坑更容易出现在低洼区域、基坑底部和材料堆场边角,这些先验信息通过空间权重图辅助修正分割结果。
以下是我在项目中实际采用的检测目标与对应框架汇总:
| 检测目标 | 任务类型 | 框架方案 | 附加策略 |
|---|---|---|---|
| 烟雾 | 目标检测 | YOLOv8/YOLO11 | 多帧时序确认,多尺度训练 |
| 明火 | 目标检测 | YOLOv8 + HSV特征融合 | 闪烁频率判定,颜色空间过滤 |
| 裸土未覆盖 | 语义分割 | DeepLabV3/轻量骨干 | 面积占比统计,边缘处理 |
| 土堆/水坑 | 语义分割 | SegFormer/时空校验 | 反射特征、位置上下文辅助 |
3. 数据集准备与标注工程实操
3.1 数据从哪来,样本怎么配比
先回答大家最容易问的问题:“工地烟雾、水坑这种数据,去哪里找?”
我一共用了三个来源。第一是重点项目的自有摄像头历史录像,这是最可靠的资源,从监控系统中随机抽取不同季节、不同天气、不同时段的视频帧,保证了场景多样性。第二是公开的火灾烟雾数据集和物体分割数据集,用于补充通用目标形态。第三是合成数据,把从素材库中抠出的烟雾、明火叠到工地背景图上,再利用生成器变换透明度、尺寸和位置。
样本配比方面,我踩过一次坑。一开始正样本和负样本按照1比1配比,模型在训练集上效果极好,一上线就原形毕露。因为真实工地上绝大多数画面是正常的,负样本的多样性决定了模型的上限。后来调整为烟雾和明火正负样本约1比4,裸土、水坑这类分割任务由于背景占比高,正负像素比控制在1比10以内。
关于数据增强,工地场景伏笔藏在“被遮挡”和“光照变化”里。固定模板的随机翻转和色彩抖动远远不够,我额外加了三类增强:随机遮挡(模拟塔吊、脚手架挡住目标)、夜间亮度压缩(把白天样本压暗模拟夜间低照度)、混合样本(两张图拼接,模拟目标出现在不同位置)。
3.2 标注规范的坑:边界框、难例与争议标签
很多初学者以为标注只是画框,实际上标注规范直接决定模型能学到的边界。烟雾和明火的框不能贴着可见区域画死死的一圈:烟雾是扩散的,边界是渐变的,只框浓烟核心区域会导致模型对边缘淡烟完全不敏感。我要求标注员把边界框画到烟气可见范围的80%左右,留有一些过渡区域让模型学习“淡烟也是烟”。
更麻烦的是争议样本。比如远处烟囱冒白烟,画面里看起来和工地冒烟几乎一样,这时候标还是不标?我的处理原则是:只要目标出现在施工场地围挡范围内,就标为正样本;范围外的一律不标,宁可遗漏也不引入歧义。模型见过足够多“场内才报警”的样本后,自然而然地就会把注意力集中在场地内。
每次标注完成后,我还会做一次交叉审核,随机抽10%的标签让第二位标注员复核,标签一致率低于95%就返工。这个流程对提升模型精度的影响,比换任何更好的模型结构都大。
4. 部署架构与硬件配置参考
4.1 边缘计算盒子还是集中式GPU服务器
这个环节是项目扩展开后被迫重新设计的。最初我只接了两路摄像头,直接在GPU服务器上推理完全够用。后来项目点位从2路扩展到28路,再扩展到跨项目的大几十路,集中式方案的问题就暴露了:视频流全部汇聚到中心,对带宽占用很大,网络抖动时掉帧严重,告警延迟也不稳定。
现实中的折中方案是混合架构:每个工地现场布一台边缘计算盒子,负责该场地的8路视频流推理,只把告警截图和原始证据片段上传到中心平台;中心服务器负责模型更新、告警汇总和联动处置。边缘盒子选用的是带NPU加速的低功耗设备,单台支持多路1080P视频流同时推理,烟雾和明火模型经过TensorRT量化后单路推理延迟能控制在200毫秒以内。
算力估算可以用一个简单公式:单路视频按3帧每秒分析,每帧推理耗时约80毫秒,那么一路持续计算约占一个NPU核心的24%,8路就是192%,也就是一台设备需要至少2个核心同时工作,再加上预处理和后处理占用的CPU,留出40%的冗余更安全。
4.2 摄像头点位规划和参数设置
点位规划是决定系统效果上限的关键环节,算法反而是后端的兜底。烟雾和明火的监测点位要选在能覆盖动火作业区、材料堆放区、临建板房区的制高点,优先使用球机但需要定时巡航;裸土未覆盖和水坑的监测点位则要尽量平视或俯视地面,避免逆光。
摄像头参数上有几个必须注意的坑。一是码流设置,超低码流下烟雾的纹理细节会被压缩成一团糊,识别率急剧下降,建议码率设为4Mbps以上;二是帧率,不需要全程25帧全帧率分析,那会白白消耗算力,我设置为持续3帧每秒分析,触发告警后自动切换为10帧每秒抓拍取证;三是红外夜视模式下的画面颜色,夜间红外画面是灰白的,HSV颜色空间的火焰判定会失效,需要单独跑一个亮度增强后的二分类模型来处理夜间明火。
4.3 告警联动与留痕归档
识别出来只是第一步,真正有价值的是告警处置闭环。我的告警链路是这样设计的:边缘盒子检测到目标后,先本地保存前后各10秒的视频片段,然后以HTTP回调方式推送到告警平台,平台再根据事件类型触发不同处理动作。
烟雾和明火告警属于高优先级事件,平台同步推送短信和电话提醒给安全员,同时在现场联动声光报警器;裸土未覆盖和水坑告警属于环保整改事件,推送工单到环保专员账号,要求在限定时间内完成覆盖或排水处理,逾期会自动上报。这个“发现即留痕、告警即工单”的闭环,让系统从“能看到”变成了“能管住”。
所有告警事件的关键信息我统一按统一格式落库,包含:项目编号、点位编号、摄像头编号、事件类型、置信度、发生时间、截图路径、视频片段路径。这个格式后来对接某市监管平台时几乎没有改动,算是提前埋了一个好伏笔。
5. 环境保护监测场景的联合应用
5.1 裸土覆盖率和扬尘的联动判断
裸土未覆盖识别在环保监测中有一个独特的价值:它不仅是“发现问题”,还能帮助推导“扬尘从哪里来”。单纯靠空气质量微站测到的扬尘数据只能说明“超标了”,并不能说明扬尘来源。我把裸土分割结果按网格划分到对应的施工标段,生成一张“裸土热力图”,再叠加风向数据和扬尘监测仪数据,就能比较精准地锁定扬尘的主要贡献区域。
裸土覆盖率的计算也不是简单地把裸土像素数除以画面总面积就完事。需要考虑摄像头能看到的地面范围有限,我引入“有效地面区域”概念,通过预先分割出的地面可见范围作为分母。这个细节直接影响了环保检查时的数据可信度——第一次监管人员来核对时,就拿着系统生成的覆盖率报告和现场实测对比,误差在5%以内。
5.2 与监管平台对接的数据接口要点
智慧工地数据最终是要往上送的一回事。目前各地对施工工地的监管要求普遍包含扬尘在线监测、远程视频监控和裸土覆盖情况,数据接口格式也逐步标准化。我们对接时采用了一版比较通用的接口格式,每个告警事件包含:事件类型编码、经纬度坐标、项目编码、发现时间、现场照片URL、视频片段URL。
这里有一个容易踩的坑:图片和视频文件的存储必须有固定的公网访问地址,或者至少对监管平台单独开通访问通道。有段时间我们只上传了文件路径,监管平台无法直接拉取,导致“调阅不通过”的重复工单。后来把文件上传到对象存储并返回永久链接,问题才解决。另一个经验是事件类型编码要提前索要对方的字典表,别自己发明,否则上报后对方系统无法识别,对账混乱。
6. 常见问题与误报排查实战
6.1 雾霾和工地扬尘把烟雾识别带偏怎么办
这是上线第一个月被问最多的一个问题。工地摄影师们最怕雾霾天——整个画面灰蒙蒙的,和烟雾的视觉特征高度重叠。我的处理办法分三层:先把雾霾检测单独做成一个分类模型,识别到“当前天气为雾霾”时自动降低烟雾报警灵敏度;再在时序校验层拉长确认帧数,雾霾在画面里是静态的,烟雾是动态扩散的,多帧对比后可以区分;最后在推送层加“气象提醒”标签,如果当天有空气质量预警,系统直接推送“疑似霾天气疑烟雾,请人工复核”而不是直接报警。这样处理的直接效果是,雾霾天的误报率下降了约80%。
6.2 雨后临时积水与真水坑如何区分
水坑识别里最典型的误检是:前一天刚下过雨,工地上到处是临时积水,模型把这些水都识别成“水坑”,产生大量无意义的告警。后来我在算法逻辑里增加了一个“时效性判定”:同一个水坑区域如果持续存在于超过12小时,才判定为需要整改的长期积水;仅出现在雨后12小时内的临时积水,自动归入“可蒸发”类别,不产生告警。这个规则听起来简单,但很有效,因为环保整改针对的是长期积水隐患,而不是正常的雨水排放。
另一个水坑细节是“覆盖物”。项目现场常有塑料布、防尘网盖在土堆上,雨后这些覆盖物有积水洼,模型经常会把这些识别成水坑。我在数据标注阶段增加了大量“覆盖物上有反光”的负样本,并结合分割结果中反光区域与地面边缘的关系做修正后,这类误报基本消除了。
6.3 夜间的火点和灯光怎么区分
夜间明火检测是我后期迭代最多的方向。工地夜间照明的灯源复杂,车灯、镝灯、手电筒、警示灯都可能在画面中形成亮斑。前文提到的闪烁频率判定在夜间依然有效,因为灯光闪烁频率集中在50赫兹(交流电频闪)或完全不闪,而火焰有明显的随机高频闪烁特征。
我还在夜间单独跑一条推理分支:进入低照度模式后,优先识别画面中的“高亮区域”,然后对该区域做火焰特有的“颜色衰减分析”。火焰中心是亮白黄色,边缘过渡到橙红色;而钨丝灯通常为均匀的黄色,LED灯则偏冷白。结合这种颜色梯度特征,夜间的误报率比单靠火焰检测模型低了不少。
6.4 误报率压不下来的三个优化手段
如果经历了上述所有调优,误报率仍然偏高,我有三个压箱底的手段。第一是“区域白名单/黑名单”机制:在图像平面上画电子围栏,模型只在围栏内启用对应检测类别,比如围挡外道路上的汽车尾灯冒出的“热气”就不会被当成明火。第二是“置信度动态阈值”:对不同点位、不同时段应用不同的置信度门限,白天高一点,夜间低一点,点位画面干扰大的再高一点。第三是“人工反馈闭环”:告警推送后,如果安全员在平台上点击了“误报”按钮,这个样本会自动进入难例集,第二天自动加入增量训练。
这三个手段叠加后,我的项目实际告警准确率从初期的较低水平提升到了较高水平,而且人工反馈闭环让系统越用越准,因为每个工地都有自己独特的干扰目标。
写在最后的一点体会
项目做下来,最大的感受是:真正难的不是训练一个高精度模型,而是在真实工地上让它稳定运行。数据集的多样性、光照环境的变化、摄像头角度的偏差、现场施工节奏的变化,每一样都比模型结构更影响结果。我在实际部署中最后会刻意留出两个从未参与训练的摄像头点位做“盲测集”,每当模型更新后,就去统计盲测集上的表现。这种自我验证习惯,比任何指标报告都靠谱。
如果让我给正要启动类似智慧工地项目的同学一个建议,那就是先选两个点位跑通小闭环,再谈规模化。不要把第一个版本的目标定得太大全,识别烟雾明火和识别裸土水坑是两个完全不同的技术栈,把其中一条跑通、跑稳,比什么都重要。