1. 场景本身比算法更复杂:禁航区防爆监控到底要解决什么问题
先泼一盆冷水:很多人一听到“AI船舶识别”,第一反应是“调一个目标检测模型,把船框出来就行”,但真把一个项目落到智慧港口的禁航区防爆场景里,你会发现算法只占很小一部分,真正难的是把“识别结果”变成“可信的报警事件”。乐迪信息这个项目,就是典型的水陆交界的复杂场景——水面反光、船舶尺度跨度大、天气变化频繁、现场又是在防爆区,所有东西都要按石化码头级别的安全标准来设计。所以我想把这次项目总结的重点放在“场景约束如何反过来决定算法和硬件方案”上。
先说清楚禁航区这个背景。很多港口的危险品泊位、LNG码头、油品装卸区周边都会划出禁航水域,非作业船舶、外来船只不得驶入。传统方式是靠人盯屏幕,值班员盯着几十路视频,很容易疲劳漏看,尤其是夜间、雾天、海浪比较大的时候,一条小渔船不开AIS(船舶自动识别系统)悄悄摸进来,在监控画面里可能就十几个像素,人眼真的看不出来。但这类船只一旦靠近危险品泊位,风险是很实在的——碰撞、火源、恶意破坏都有可能。所以项目要解决的第一个问题,是“全天候、低漏报地把闯入禁航区的船舶找出来”,而不是简单的“有船报警”。
防爆监控又是一个独立的约束维度。港口危险区域的摄像机、接线箱、支架,都必须有防爆认证,防爆等级通常是Ex d IIC T6 Gb这一类,外壳要能承受内部爆炸并且阻止火焰蔓延到外部环境。普通安防摄像头根本无法进场,现场布线也要按照防爆穿线管、防爆接线盒标准来做。这个约束直接影响后面的一个关键决策:AI计算是放在前端摄像机里,还是放在后端机房?大家习惯性觉得边缘AI一定好,但防爆摄像机内部空间极小,高算力模块的散热和防爆认证很难同时满足,所以项目实际采用的是“防爆摄像机采集+就近防爆箱内边缘计算盒子”的分体方案,这个后面细说。
我始终觉得,做智慧港口AI项目,第一步不是选算法框架,而是把“场景边界”画清楚。禁航区监控和普通道路监控差别很大:道路目标出现在固定车道、角度相对可控,而水面船舶朝向任意、尺度从几米的小艇到两百米的大船都有,背景又有波纹、反光、浪花这类天然噪声。如果一开始不把这些约束写进技术方案,后面每一条都会变成坑。
1.1 禁航区监控的“业务逻辑”和“识别逻辑”要对齐
禁航区报警不能“见船就报”。港口本身有大量合法作业船舶,拖轮、引航艇、交通艇、施工船每天都在活动。如果AI把正常作业船也报成闯入,值班员很快就会被误报淹没,最终连真报警也懒得看了。所以这套系统必须支持几种业务规则:
- 按区域设防:禁航边界用多边形画出,只有船舶检测框的中心点或关键点进入该区域才触发研判;
- 按航向研判:目标是否正在朝禁航区或危险泊位靠近,如果只是平行经过边界外围,可以只记录不报警;
- 按AIS/雷达信息融合:开启AIS且航迹正常的船舶,默认放行;无AIS或AIS与视觉识别不匹配的,才进入重点跟踪;
- 按船型区分:渔船、快艇这类小型船只是主要防范对象,货轮、客轮有固定靠离泊计划,需要和白名单比对。
这些业务规则看起来是软件逻辑,实际上每一条都要倒推给视觉算法。比如“中心点进入区域才报警”,意味着检测框的质量必须稳定,不能忽大忽小,否则中心点会抖。为此我们后来在检测后加了一个轻量跟踪器,用历史轨迹平滑位置,再判定是否进入禁航区,误报一下子降了很多。这就是“识别逻辑”和“业务逻辑”对齐的例子。
1.2 防爆场景下,AI不是单点能力而是一条链路
防爆监控的链路包括:防爆摄像机采集视频,通过光纤或网线传到防爆箱内的边缘计算盒子做识别,识别结果和告警信息再通过网络传到后端平台,与AIS、雷达数据做汇总,最后在监控大屏和值班终端上展示。这个链路里每一环都是短板,任何一个环节掉链子,AI再准都没有意义。
举个例子,防爆摄像机一般会配雨刷、加热玻璃、遮阳罩,这些功能在普通摄像机里是选配,在防爆场景里基本是标配。因为海面盐雾会腐蚀镜头镀膜,温差大时镜片起雾,雨天雨滴会直接干扰检测算法。所以项目在做设备选型时专门对比了几家防爆摄像机厂商,最后选择了支持双光谱(可见光+热成像)的型号,热成像通道在夜间识别船舶有不可替代的优势。这一点不是炫技,是水质图像在夜间真的很难靠补光解决——普通白光补光会吸引飞虫、产生水面反光,红外补光又会暴露监控位置。而船体和海水在热成像下有天然温差,船体轮廓非常清晰,虽然热成像分辨率低导致船型分类困难,但用来做“有没有目标”的初筛非常可靠。
2. 算法选型与系统架构:为什么不是“套个YOLO”就完事
模型选型这部分,我直接说结论:项目最终以YOLOv8作为主检测框架,集成ByteTrack做多目标跟踪,同时在前后端做了3个关键增强——高分辨率输入、多尺度推理、AIS融合修正。这个组合未必是业界最前沿的,但一定是最适合当前项目条件的。
YOLO系列不是唯一选项,但在这个场景有天然优势:单阶段检测速度快、部署生态成熟、移动端和边缘端都有现成的部署工具链。我们用过的替代方案包括:
- 两阶段检测器,比如Faster R-CNN系列:精度高,但推理速度在边缘盒子上很难跑到实时,而且小目标检测的提升并不像想象中那么明显;
- 基于Transformer的DETR系列:在大场景遥感图像里表现不错,但对边缘设备算力要求高,量化部署麻烦,项目周期内不太敢用;
- 专门做旋转框检测的模型:适合船舶靠泊角度变化大的近距离场景,但禁航区远距离监控里,水平框已经够用,旋转框反而增加标注和部署成本。
所以最终选了YOLOv8系列里的中档模型,配合TensorRT做INT8量化,在边缘盒子上实测能达到20到30帧每秒的推理速度。这里有个很多人容易忽略的细节:监控场景并不需要每一帧都做检测。我们改成了“抽帧检测+跟踪补帧”的策略——每3帧检测一次,中间帧用跟踪器预测位置,既保证报警延迟在1秒以内,又降低了边缘设备的负载和发热,在防爆箱这种密闭环境里,少发热就是少故障。
2.1 输入数据的选择:可见光、热成像、还是融合
双光谱摄像机的数据,在算法设计上就必须想清楚。最直观的做法是可见光和热成像分别跑一个模型,再把结果融合,但这样计算量翻倍,边缘盒子吃不消。我们实际用的方案是:
- 白天优先用可见光通道识别,因为船型、船名清晰,检测和分类的置信度都高;
- 夜间自动切换或并行使用热成像通道做检测,热像图里船舶目标显著,误检率低;
- 可见光和热成像的检测结果在跟踪层做融合,不要求在像素级对齐,而是用空间位置和运动轨迹匹配。
这里有个经验:不要迷信“多光谱像素级融合”,工程上稳定可靠的往往是决策级融合。可见光框出一个目标,热成像框出同一个目标,两者中心点距离小于一定阈值,就认为是同一个目标,然后取置信度高的一路结果输出。这种融合方式实现简单,后续排查问题也更直观。
2.2 小目标检测是最大的算法难点
禁航区监控的一个硬骨头是远距离小目标。港口禁航边界可能离摄像头几百米到几公里,一条7米长的渔船在2公里外,画面里大概只有30×15像素。YOLO类模型对这种小目标天生不友好,下采样倍数大,小目标的特征在深层特征图里基本丢了。
我们做了四件事来缓解:
- 输入分辨率从默认640×640提升到1280×1280,虽然推理速度下降,但小目标特征更完整;
- 推理时对画面按区域分块检测,对远岸、航道中部等易出现小目标的区域做滑窗放大,这个“感兴趣区域放大”的收益非常明显;
- 把近景和远景分成两个模型或者两条推理路径,近景用普通分辨率,远景用放大后的裁切图;
- 在损失函数上加大了小目标的权重,对应地重新设计了锚框或使用无锚框头的尺度分配策略。
说到底,小目标检测没有银弹,最有效的手段还是“让模型看见更大的目标”。所以后来我们干脆建议现场调整摄像机安装位置和焦距,把重点防范区域在画面里放大,算法的压力一下就小了很多。这也是一个很典型的经验:很多识别问题可以通过改变成像条件来解决,不一定非得堆模型。
2.3 跟踪器不是可选项,是必需品
单帧检测结果直接拿来报警,会有两个问题:一是单帧误检导致瞬时误报,二是同一艘船被重复计数或者轨迹断掉。我们接入了ByteTrack跟踪器,对检测框做数据关联,实际效果比DeepSORT更稳,而且省去了单独训练ReID模型的成本。跟踪输出给上层业务带来几个关键信息:
- 轨迹:知道船从哪里来、往哪去,可以判断是否只经过禁航区边缘;
- 速度:快艇和货轮的速度差异很大,可以作为目标分类的辅助特征;
- 持续帧数:一个目标被连续跟踪超过10帧且确实进入禁航区,才触发报警,有效过滤闪烁误检。
ByteTrack的处理逻辑并不神秘,核心就是按分数分高、低两组做匹配,再用IoU和运动预测关联。工程落地时我们需要调整两个参数:最大跟踪丢失帧数(默认30帧就够了)和检测置信度阈值。置信度阈值这里有个矛盾点——设高了漏检多,设低了误检多,我们的经验是先设低一点,通过跟踪和后续业务规则去过滤,而不是把置信度当唯一的过滤手段。
3. 数据标注、模型训练与边缘部署的实施细节
这个项目的数据部分,坦白说是我觉得最枯燥但最关键的环节。市面上公开的船舶检测数据集大多是近景开阔水域的船舶,和港口禁航区这种带岸基、带作业机械、带复杂背景的场景差异很大,所以必须采集一批现场数据。
我们以某沿海港区为目标场景,连续采集了两周不同时段、不同天气的视频,然后抽帧清洗。标注类别没有做得太细,只有五类:货船、渔船、客船、快艇、其他船只。这里不细分船型的原因很实际——热成像下很多船只有轮廓没有细节,标注员也很难判断,细分类别只会把模型搞糊涂。倒是在属性上做了细分:单体、遮挡、远距、小目标、雨天、夜间、雾天,这些属性不是模型输出,而是用来做数据分层和模型评估的。
标注规范里有一个值得分享的细节:船的检测框需要包含船体和部分水线区域,但不包含明显的大片浪花。一开始标注员总习惯把快艇后面拖出的白色尾迹包进去,后来发现这会让模型学到一个错误的“快艇特征”,等浪花大的时候就疯狂误检。所以我们在标注规范里明确写了“浪花不属于目标”,并且用小图示例规范了边界。
3.1 模型训练的关键参数和评价指标
训练过程用的是常规的YOLOv8训练流程,但有几个参数值得单独拿出来讲。
- 图像分辨率:训练时直接使用1280×1280,和部署时保持一致,避免训练部署分辨率不一致带来的精度损失;
- 训练轮数:我们控制在300轮左右,冻结骨干前100轮,先用预训练权重稳定特征提取层,再放开全网络微调;
- 数据增强:启用了Mosaic、MixUp、随机透视,但对水面场景关闭了大幅度的色彩抖动。因为水面颜色变化会导致模型过度依赖颜色特征,而实际它应该更依赖形状和轮廓;
- 类别不平衡:渔船和快艇样本少但重要,做了过采样和复制粘贴增强,同时给这几类加了更高的loss权重。
评价指标方面,除了常规的mAP@0.5,我还强烈建议看两个指标:小目标AP(AP-small)和不同距离段的漏检率。很多模型整体mAP好看,但小目标AP一塌糊涂,应用到现场才知道问题。我们把测试集按照摄像头画面中的目标像素高度分了档:大于80像素、30到80像素、小于30像素,分别统计漏检率,这样模型哪里不行一目了然。
模型训练完之后,还需要做一次“困难样本分析”。我们把所有漏检和误检样本汇总出来,按场景先验分类。漏检集中在中远距离小目标,这么修:加针对性的放大推理路径。误检集中在浪花、浮标和港口机械,这么修:加掩码约束、增加负样本、在报警逻辑里加禁区排除。这个过程很耗时,但比盲目换模型框架有效多了。
3.2 边缘部署:防爆箱里的算力怎么安排
部署这件事,在防爆场景里比在普通机房麻烦得多。我们用的边缘盒子是一台内置GPU的设备,整机有宽温设计,能扛-20℃到70℃的环境温度,但这还不够,因为防爆箱体是完全密闭的,散热基本靠壳体自然散热。GPU满负载跑模型的发热量非常大,在夏天南方港口的日照下,箱内温度能到80℃以上,设备降频甚至死机。
后来我们采取了三层措施:
- 硬件层:在防爆箱内加装了隔热带和散热板,箱体外侧增加遮阳罩,虽然还是被动散热,但实测温度能降10℃以上;
- 系统层:限制了GPU功耗,把最大功耗调低,性能损失可以接受,但温度可控很多;
- 应用层:就是前面提到的抽帧检测策略,把平均推理负载降下来,避免长时间全速运行。
模型转换这一步,我们用TensorRT做了FP16和INT8两种量化。FP16的精度损失几乎可以忽略,INT8则需要校准数据集,校准样本最好覆盖白天黑夜各种场景,不然量化后某个特定时段的检测精度会莫名下跌。这个坑我们踩过一次:一开始只拿白天数据做校准,结果夜间热成像检测在INT8下小目标漏检明显,后来把夜间数据重新加入校准集,问题才解决。
部署后的接口设计也要提一下。边缘盒子对外只做三件事:接收RTSP视频流、输出结构化目标信息、上传报警事件。结构化信息包括目标编号、类型、置信度、检测框坐标、轨迹点、速度、温度通道的检测结果。这样做的好处是后端平台不关心算法细节,只需要消费标准格式的数据,后续换算法版本不影响平台。
3.3 报警规则的工程化调优
报警规则在项目里经过了好几轮调优。第一版很简单:船进入禁航多边形就报警。结果值班员一天收到几百条报警,因为很多船只是从禁航区边缘擦过,或者是一艘合法拖轮拖着货船经过,系统不知道两者关联,把它判断成两条船。
后来我们增加了几个维度:
- 停留时间:目标进入禁航区并停留超过30秒才触发预警;
- 航向夹角:目标航向和禁航区边界的夹角小于一定角度且快速通过,视为过境,不报警;
- 目标关联:检测框距离AIS目标位置较近且航行方向一致时,自动关联为合法目标;
- 速度辅助:速度低于0.5节且长时间在水面静止的目标,可能是锚泊船或漂流物,单列一类事件,而不是直接告警。
这样一来,报警量少了很多,而且每条报警都带上了目标和场景信息。值班员做到“接收报警—查看目标轨迹—远程广播喊话—派遣巡逻艇”的闭环,可信度才真正建立起来。
4. 现场常见问题与排查技巧实录
这一类项目,上线前三个月基本是在和误报作斗争。我把我们的问题记录整理成几个有代表性的案例,希望能帮你避开同样的坑。
4.1 浪花和尾迹误检:跟AI说清楚“船”不是“水”
最常见的问题是快艇尾迹被识别成船。白色浪花在可见光图像里形态和船体非常像,尤其在阳光照射下,尾迹亮度和船身几乎分不出来。我们最初版本的模型在下午时段误检率特别高,后来查了标注数据,发现确实有大量样本把尾迹包进了船框。
解决思路有三条,缺一不可:
- 重新清洗标注,浪花全部不算目标;
- 加入带尾迹的负样本,让模型知道“有白色拖尾区域但不一定有船”;
- 在跟踪层用运动模型做筛选:船是有固定航向的,而浪花是扩散和消散的,轨迹特征差异很大。
此外,颜色特征不可靠,我们尝试在预处理阶段减小饱和度权重,发现效果一般,真正有用的还是让模型更多地依赖船体轮廓和上下文关系。
4.2 夜间识别:热成像不是万能的,但离了它万万不能
夜间识别是整个项目里最难啃的骨头。刚开始我们只用可见光加红外补光,结果远处船舶的黑影很容易被漏掉,而且镜头附近有飞虫时,补光灯就像一个“误检生成器”——飞虫在近景里被检测成大目标,远岸的渔船反而看不见。
引入热成像通道后,情况明显改善。但热成像也有自己的问题:
- 热成像分辨率低,船型和细节很难判断,所以夜间报警我们主动降低分类置信度要求,优先保证检出,不让分类任务拖累检测;
- 夏天海面和船体温差小,热对比度低,需要对着热像图做增强,拉大温差显示范围;
- 雨水在热成像里表现为冷点,导致船体轮廓断裂,后期算法上用了图像形态学闭运算做连接,简单但有效。
另外一个夜间特有的坑是“灯光倒影”。港口周围有很多照明灯、作业灯,灯光在水面的倒影会被模型当成亮点目标。应对方式是给每个摄像机画一个“灯光区屏蔽掩码”,这些区域不做检测或者降低检测权重。
4.3 防爆合规和运维的矛盾
防爆环境下的一个隐性矛盾是:设备越智能,现场维护越困难。普通摄像机坏了,直接拆下来换,但防爆摄像机拆装都要断电、办作业票、安排专人监护,一次维护可能要折腾半天。所以我们的做法是尽量在设备层面做冗余:
- 每个关键监控点最少两路视频覆盖,一路故障时另一路还能用;
- 边缘盒子支持双网口,主网断时自动切换备用链路;
- 算法模型升级尽量远程操作,通过管理平台灰度发布,减少现场人工介入。
还有一个小经验:防爆箱的进线口密封非常重要。海边的盐雾会沿着电缆进入箱体腐蚀端子,导致供电不稳定。现场曾出现设备频繁重启,排查了很久,最后发现是电缆接头在防爆格兰头里没有完全密封,盐雾渗入引起短路。后来所有进线口都重新做了密封处理,并且每月巡检一次箱体内湿度,问题就不再出现。
4.4 算法迭代的版本管理和回归测试
最后说一个常常被忽略的工程问题:算法怎么持续迭代而不搞乱现场。
我们建了一套简单的“影子模式”机制。新模型先在真实视频流上离线跑一遍,生成结果和线上模型对比。对比指标包括:目标数量差异、检测框重合度、报警事件重合率。只有误检下降、漏检不增加、报警事件基本一致,新模型才允许上线。这样做的原因是,现场值班员已经习惯了现有报警逻辑,模型一换,同样的画面可能报警时间变了、目标ID变了,他们会以为系统坏了。影子模式避免了很多这类“假故障”投诉。
另外,每次上线前要在固定的测试视频集上跑回归。我们准备了一个包含2000张现场图像的回归测试集,覆盖白天、黑夜、雨天、雾天、顺光、逆光、大小目标等场景。模型改动再小,也必须过这一关,防止“修了一个误检,带崩了另一个时段”的情况。
5. 一些实际操作中的体会
项目做完之后,我最大的感受是:AI船舶识别在智慧港口防爆监控里,真正值钱的部分不是模型精度提高了几个点,而是“让值班员真的敢相信这套系统能帮他盯住禁航区”。技术指标再好,如果误报把值班员搞到麻木,系统也等于白做了。
所以我特别想强调一条经验:报警逻辑的调优优先级一定要高于算法精度的调优。很多项目组一上来就死磕mAP,觉得模型涨了两个点就赢了,但现场的问题是“船很多、虚警也很多”。我们后来用业务规则和跟踪逻辑过滤掉的误报,比提高模型置信度阈值过滤的多得多,而且误报的“可解释性”更强——值班员能看到轨迹、能看到关联的AIS信息、能理解为什么报警,而不是面对一个黑盒模型。
如果这个项目后续再扩展,我觉得可以往两个方向走:一是把雷达数据接入形成视觉、AIS、雷达三源融合,目标身份确认会更可靠;二是对船舶行为做更长时序的分析,比如异常滞航、危险接近、夜间关闭AIS航行这类行为预警,从“识别目标”升级到“理解行为”。这些方向技术上都在逐步成熟,但核心难点还是在场景理解和工程落地。
最后再分享一个非常小但很实用的技巧:给每个摄像机建立一张“现场基准图”,记录正常天气下该视角的水面背景、灯光位置、岸线轮廓。模型出问题时,把故障图和基准图对比,能很快判断是光照变化、天气问题还是模型真的抽风了。这个小动作帮我们省了大量现场排查时间,建议做类似项目的人都提前做起来。