无人机视角下做行人检测,和普通监控摄像头完全是两码事。地面摄像头拍行人,目标大、角度平、光照可控,模型随便跑;无人机挂载的相机是俯视视角,人的头部和肩部占了画面绝大部分,同时整幅画面里的目标数量可能非常多,地面一辆车、一排树都能把行人挡住大半。之前我用YOLOv5跑过一版,遇到小目标密集场景时漏检明显,后来借着YOLOv8发布,我把整套系统重新做了工程化落地,从模型训练到TensorRT加速,再到最终的实时监控平台,前后踩了不少坑。这篇就把完整的实战过程写出来,包括数据怎么处理、训练参数怎么调、模型怎么部署到Jetson设备上、监控平台怎么搭,以及我遇到过的各种奇怪问题。
这套方案的目标很简单:一架搭载摄像头的无人机,把视频流实时传回地面站,地面站或机载边缘设备上跑YOLOv8检测行人,检测结果叠加在实时画面上推送监控大屏,同时把告警事件(比如闯入特定区域的行人)自动记录下来。整个系统的价值在于解决两个痛点:一是无人机替代人工巡逻,效率高、覆盖面大;二是实时性,不是拍完回来再看视频,而是边飞边看边报警。适合做安防巡检、大型活动现场保障、应急救援搜救等场景,如果你正在做类似的无人机视觉项目,这篇的实操经验可以直接参考。
1. 整体架构设计与技术选型
1.1 为什么选择YOLOv8而不是其他模型
我做选型时对比过几个方向。一类是两阶段的Faster R-CNN系列,精度高但推理速度太慢,无人机平台本身算力有限,还要考虑续航,每帧多花几十毫秒都会显著影响一块电池能巡检的面积,直接排除。另一类是YOLOv5和YOLOv8,这两者都是单阶段检测器,速度足够,但YOLOv8在几个关键点上更契合我的需求。
先看检测头的改进。YOLOv8换成了Anchor-Free结构,不再需要预设Anchor Box。无人机俯拍视角下行人的尺度变化非常极端——同一帧画面里,近处的行人可能占200×400像素,远处的可能只有20×30像素。Anchor-Based方法需要针对这种尺度分布专门聚类Anchor,不同飞行高度还得重新算;Anchor-Free用中心点加回归的方式,对不同尺度目标的适应性天然更好。我实测下来,在无人机视角数据集上,YOLOv8s的mAP比YOLOv5s高出3到4个百分点,这个差距在密集小目标场景下尤其明显。
另一个原因是模型的部署生态。YOLOv8官方代码库直接支持ONNX导出,而且从训练到导出到推理的完整链路做得非常顺滑。我用它导出TensorRT引擎的时候,不需要做太多额外的模型转换工作,对Jetson这种边缘设备来说,这一步节省了大量调试时间。
整个系统架构分三块:数据与模型训练、模型压缩与部署、实时监控平台。模型训练在PC端完成,部署目标是一块Jetson Orin NX 16G模组,监控平台跑在同一个设备上,通过RTSP接收无人机图传的推流,检测结果输出到Web前端。这样的好处是整套系统高度集成,只需要给无人机和地面站供上电就能工作,不依赖外部服务器。
1.2 系统各模块的技术选型
视频流接入这块,我选的是GStreamer配合RTSP协议。无人机图传通常以RTSP流方式输出,GStreamer负责拉流、解码、抽帧,再把帧数据送到推理管线。这里有一个关键考量:解码性能和延迟。GStreamer可以利用Jetson平台的硬件解码器(NVDEC),把CPU负载降到最低,让出更多算力给模型推理。如果用OpenCV的VideoCapture拉RTSP流,默认走的是软件解码(FFmpeg),在4K分辨率下CPU占用率能飙到70%以上,这会让推理延迟明显变大。
推理引擎我选了TensorRT。YOLOv8导出的ONNX模型经过TensorRT转换后,在Jetson Orin NX上能把FP16精度下的推理速度做到单帧12毫秒左右,而直接用ONNX Runtime推理则需要35到40毫秒。对于实时监控场景来说,这个差距直接决定了用户体验——前者能跑到每秒80帧以上(受解码帧率限制实际稳定在30帧),后者勉强只能跑25到30帧,一有波动就开始卡顿。
监控平台的数据通道我用的是WebSocket。检测结果不是简单地输出到控制台,而是要实时推送到浏览器端的监控页面。WebSocket全双工通信天然适合这种场景:后端每处理完一帧,就把检测框坐标、类别、置信度、时间戳打包成JSON推给前端,前端用Canvas叠加到视频画面上。相比HTTP轮询,这种方式的实时性和带宽效率都好太多。
1.3 系统工作流程梳理
整套系统的工作流程分成这样几条链路:
第一是视频流链路。无人机相机输出RTSP流,Jetson上的GStreamer管道负责拉流和解码,每帧解码完成后放进一个环形缓冲区,推理线程从这个缓冲区取帧。
第二是推理链路。推理线程拿到帧后,先做预处理(Resize到640×640、归一化、通道变换),然后送入TensorRT引擎执行推理,拿到检测框、类别和置信度。这里的后处理要去掉低置信度的框,再做NMS(非极大值抑制)去重。
第三是业务链路。如果检测到行人,就把检测结果和原始帧关联起来:一是叠加检测框标注后推送到Web前端显示,二是当有行人进入预设的警戒区域时触发告警,截取当前帧保存到本地并推送告警消息。
第四是存储链路。正常的视频流不做全量保存(太占空间),只做事件触发的片段录制。发生告警时,从前置缓冲区里取出告警前10秒的帧序列,合成MP4文件保存。这是监控系统常见的预处理策略,既能留存关键证据,又不至于把一块256G的固态硬盘几天就写满。
2. 数据集准备与模型训练实战
2.1 训练数据的构成与标注
训练数据是决定模型上限的关键。YOLOv8官方预训练权重是在COCO数据集上训出来的,COCO里包含“person”这个类别,但COCO里的行人绝大多数是水平或接近水平视角拍摄的,直接用来推理无人机俯拍画面效果很差。好在用预训练权重做迁移学习时,模型已经具备了通用的特征提取能力,只需要少量无人机视角的数据微调就能收敛得很好。
我这里训练数据的构成是三部分:第一部分是公开的无人机视角行人检测数据集,比如VisDrone和UAVDT,前者包含大量不同高度、不同光照条件下拍摄的俯视行人画面,后者侧重交通场景;第二部分是自己采集的无人机视频,在不同的飞行高度(30米、50米、80米)、不同的场景(广场、园区道路、停车场)拍摄,然后抽帧标注;第三部分是用COCO数据集中的人头、行人上半身样本做补充,增强模型对人头肩部特征的敏感性。
自采数据的标注是件耗时的工作。我用的是LabelImg工具,标注时统一规则是:“行人”类别只标注完整可见或者大部分可见的人体,严重遮挡超过70%的不标注;多个行人挨在一起时严格按照实例边界框标注,不刻意区分每个人的粘连。这个标注规则的统一性非常重要,标注标准不一致会让模型学到的特征混乱。
最终数据集的情况大概是:VisDrone和UAVDT的公开数据筛选后选用了约8000张图片,自己采集标注了约3000张图片,总共11000张左右,按照8:1:1划分训练集、验证集和测试集。
2.2 数据增强策略与训练参数
无人机视角的行人检测有一个反复出现的问题:小目标占比极高。实测统计下来,30米以上高度拍摄的画面里,行人目标面积占整幅画面的比例通常不到1%,换算成640×640的输入尺寸,很多目标只有20×20像素甚至更小。模型对这种极小目标的特征提取能力很有限,所以数据增强的手段必须针对性设计。
我在训练里使用了Mosaic增强和Copy-Paste增强的组合。Mosaic是YOLO系列常用的增强方法,四张图拼接成一张,增加小目标出现次数并提升模型的尺度鲁棒性。Copy-Paste是把小目标行人图像块随机粘贴到其他训练图上,增加小目标的密度和多样性。这套组合用下来,模型对稀疏小目标的召回率提升非常明显。
训练参数上,我用的YOLOv8s作为基础模型,输入的图片尺寸是640×640,批次大小设为32,初始学习率0.01,使用SGD优化器。总共训练了300个epoch,在前50个epoch使用了Warm-Up策略,让学习率从0.001线性增长到0.01,避免模型在初始阶段剧烈震荡。这里有一个经验之谈:YOLOv8默认的训练配置是基于COCO的,直接拿来训无人机数据,mAP可能只有50出头,但只改一个数据增强参数可能就会涨2到3个点,所以不要迷信默认配置。
训练过程中的损失函数曲线需要关注三个部分:边界框回归损失(Box Loss)、分类损失(Cls Loss)、置信度损失(DFL Loss)。这三个损失在前50个epoch快速下降,之后缓慢收敛,300个epoch后基本平稳。我用早停机制监控验证集mAP,连续30个epoch不上升就停止训练,避免过拟合。
2.3 训练效果评估与分析
训练完成后,我用测试集做了详细评估。YOLOv8s在这个自建数据集上的mAP@0.5达到了88.6%,mAP@0.5:0.95达到64.2%。对比一下直接用COCO预训练权重不做微调时的表现,mAP@0.5只有61.3%,说明迁移学习加自建数据微调的效果是决定性的。
逐尺度分析测试结果有个有趣的发现:在30米高度拍摄的画面中,模型对中等尺度(大于40×40像素)的行人目标检测精度接近95%,但对小于20×20像素的目标,召回率只有70%左右。小目标漏检和误检的主要原因是特征太少和背景干扰——在俯视视角下,有人穿着颜色接近地面的衣服时,模型很容易漏检。
针对这个短板,我又做了一轮迭代。一个办法是测试时开启多尺度推理,在FP32和FP16两种精度下分别处理原始分辨率的0.8倍、1倍、1.2倍三种尺度,融合结果后再输出。效果确实有提升,mAP@0.5涨了接近2个点,但代价是推理时间几乎翻倍,实时性受影响。另一个更实用的办法是改用YOLOv8m模型作为基线,参数量和FLOPs虽然变大,但在Jetson Orin NX上配合TensorRT同样能跑到25毫秒以下,而小目标召回率提高了5个百分点。最终为了实时性优先,我折中选择YOLOv8s并重点优化数据侧的增强策略和部署阶段的预处理逻辑。
3. 从PyTorch到TensorRT的部署优化
3.1 模型导出与精度验证
训练完毕后,先要对模型做导出。YOLOv8官方代码提供了直接的导出命令,支持导出ONNX格式。这里有一个关键参数是动态输入还是静态输入。TensorRT对动态输入的支持比较麻烦,如果输入尺寸固定为640×640,引擎可以做一些内存布局上的优化,推理速度更快。我日常使用都是固定输入尺寸,所以导出时直接固定shape。
导出的命令大致是这样。
yolo export model=/path/to/best.pt format=onnx dynamic=False opset=12导出成功后,ONNX模型还要做一次精度验证。从PyTorch到ONNX的转换可能因为算子实现差异导致精度微降,我一般用Python脚本分别跑PyTorch模型和ONNX模型的推理,对比同一批图片的检测结果,确认mAP差距在0.5个百分点以内才继续下一步。
ONNX转TensorRT时,有两个关键参数要调。动态形状会影响引擎生成时间,FP16精度则直接决定推理速度和精度平衡。TensorRT的FP16模式在某些极端情况下会让极小目标的置信度出现0.1到0.2的波动,但常规测试中影响不大,加上可以用后处理卡阈值来兜底,我最终还是选了FP16。
这里有一个坑:ONNX模型里如果带有一些不支持的操作符(比如某些版本的Focus层展开方式),转换成TensorRT时可能会报错或者生成错误引擎。我用的YOLOv8没有这个问题,但如果从更老的YOLO版本迁移过来,转换前需要用ONNX GraphSurgeon手动处理一下不兼容的节点。
3.2 TensorRT引擎的构建与加载
构建TensorRT引擎的方法有两种:用trtexec命令行工具,或者写Python代码调用TensorRT Python API。用命令行工具简单直接,但部署时灵活性差,而且无法嵌入到自己的应用逻辑中。我更推荐用Python API在应用启动时动态构建引擎,方便统一管理日志和错误处理。
import tensorrt as trt logger = trt.Logger(trt.Logger.INFO) builder = trt.Builder(logger) network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser = trt.OnnxParser(network, logger) with open("model.onnx", "rb") as f: parser.parse(f.read()) config = builder.create_builder_config() config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 30) config.set_flag(trt.BuilderFlag.FP16) plan = builder.build_serialized_network(network, config) with open("model.trt", "wb") as f: f.write(plan)引擎构建完成后的序列化文件可以保存在本地,后续启动时直接加载,省去重新构建的时间。在Jetson设备上,一次引擎构建大概需要30到60秒,这在开发阶段可以接受,但如果做产品发布,建议在安装时预生成引擎文件,避免用户等待。
加载引擎并用它做推理时,输入输出的张量布局需要和模型对齐。YOLOv8的输入是NCHW布局的RGB图像,归一化范围是0到1,输出是一个1×84×8400的张量,其中84是4个边界框坐标加80个类别分数,8400是三个不同尺度特征图上的候选框总数。在后处理时,要把这个张量分解成边界框和类别分数,然后做阈值筛选和NMS。这些逻辑用NumPy实现就行,TensorRT只负责前向推理。
3.3 Jetson平台上的推理管线优化
Jetson Orin NX模组的CPU部分是8核Arm Cortex-A78AE,GPU是Ampere架构,算力在边缘设备里属于第一梯队。但就算算力充裕,推理管线设计不好照样会卡顿。我最初的实现是每帧图像从解码到推理串行执行,延迟在30毫秒左右,但CPU使用率不稳定,偶尔会掉到20毫秒以下,偶尔飙升到45毫秒以上。后来改成生产者消费者模型:解码线程持续把帧放入队列,推理线程从队列取帧,队列满时丢弃最新帧而不是阻塞解码线程。这样处理后,帧率稳定在30FPS,CPU占用率也降了下来。
预处理和后处理的耗时也值得关注。在Python环境里,把一张1080P的BGR图像缩放到640×640再做归一化,用OpenCV实现大概要4毫秒;NMS如果用纯Python实现,候选框多时会拖到6到8毫秒。这些时间加起来,即使TensorRT推理只有12毫秒,整条链路的帧率也会被拖到30FPS以下。我的做法是把预处理和后处理都用NumPy的向量化操作重写,NMS直接调用一个用Cython优化的版本,整体预处理加后处理的耗时压缩到不到5毫秒。
对于部署形态,我有两种选择:一种是把模型部署到Jetson设备上,该设备放在地面站端,接收无人机图传的RTSP流;另一种是把设备直接挂在无人机上,实现机载实时处理。考虑到系统主要用于安防监控场景,地面站部署是主流方式,既不影响飞行续航,又便于管理维护。
4. 实时监控平台的实现
4.1 RTSP视频流接入与画面处理
视频流接入部分用的是GStreamer管道,核心命令大致是:
gst-launch-1.0 rtspsrc location=rtsp://drone_ip:554/live ! decodebin ! videoconvert ! video/x-raw,format=BGR ! appsink在实际代码里,我会用OpenCV的VideoCapture配合GStreamer后端来接收帧:
cap = cv2.VideoCapture("rtspsrc location=rtsp://drone_ip:554/live ! decodebin ! videoconvert ! video/x-raw,format=BGR ! appsink", cv2.CAP_GSTREAMER)这里有几个细节需要注意。第一,格式一定要显式指定为BGR,因为GStreamer默认输出可能是RGBA或其他格式,OpenCV后续处理时容易搞混通道顺序。第二,如果RTSP流的编码格式是H.265,Jetson的硬件解码器可以正常处理,但前提是GStreamer插件库里包含了对应插件。第三,网络不稳定时RTSP流经常断流重连,这段逻辑必须单独处理。
针对断流重连问题,我写了一个简单的重连机制:检测到帧读取超时(比如连续5秒没有新帧),就销毁当前视频捕获对象,等待1秒后重新创建并连接RTSP地址,最多重试5次。这套逻辑还配合一个看门狗线程,定期检查视频捕获是否仍然健康,异常时自动拉起重连流程。实测下来,在弱网环境(信号强度低于-75dBm)下,原来平均每3分钟就要手动重启一次系统,现在可以稳定运行数小时。
4.2 检测结果叠加与前端展示
监控前端我选的是Web方案,跑在本机或局域网内的浏览器里。后端用FastAPI提供HTTP接口和WebSocket接口,前端是一个简单的单页应用,用Canvas渲染视频帧和检测框。
具体流程是:后端解码线程拿到原始帧后先做一次推理,推理结果通过WebSocket实时推送到前端,前端拿到检测框数据后在Canvas上叠加绘制。视频画面本身也是后端推过来的——使用Motion JPEG(MJPEG)格式,把每帧JPEG编码后通过HTTP流式输出到浏览器。这种方式的好处是兼容性好、实现简单,不需要复杂的WebRTC协商流程。缺点是需要额外的编码开销,但在局域网环境下完全够用。
这里有一个渲染性能的细节:如果检测结果通过WebSocket推送,每帧一条消息,一秒30条消息对于WebSocket来说毫无压力,前端Canvas绘制检测框也非常快。但如果推理结果直接在后端用OpenCV画好框再整体推图像,JPEG编码和传输带宽会比没有检测框时高不少。所以我的最终方案是:后端不画框,只传输原始画面和检测框数据,前端负责把框画到画面上。这样对带宽的占用是最小的。
告警功能的实现逻辑是这样的:在监控页面里可以预设多个多边形警戒区域,前端会把区域顶点坐标发给后端,后端在推理时判断每个行人检测框的中心点是否落在警戒区域内。如果检测到有行人闯入,就触发告警:推送一条WebSocket消息到前端弹窗提醒,同时把当前帧保存到本地磁盘,帧文件名带上时间戳和告警ID。
4.3 数据存储与告警录像
告警录像的存储设计是我花了不少心思的部分。监控系统如果对全量视频流做连续录像,按1080P@30FPS的H.264编码估算,每小时需要1.5GB左右的存储空间,一个8小时的飞行任务会产生12GB数据。如果只是做安防巡检,这个量级对于移动硬盘还能接受,但如果要常态化部署,存储压力会迅速变大。
我的方案是只录事件。后端始终维护一个环形缓冲区,容量是10秒的帧序列(约300帧),新帧不断写入,旧帧不断丢弃。当检测到告警事件时,把当前缓冲区里的300帧连同后续的5秒新帧一起提取出来,用H.264编码合成MP4文件。这样一条告警录像的长度是15秒,覆盖了行人进入警戒区前后的关键画面,既省存储空间,又保留了证据链。
合成MP4的编码操作如果放到主推理线程会卡顿,我的做法是开一个专门的存储线程,告警触发时把帧序列放入队列,存储线程负责编码和写盘。这样即使同时发生多个告警,主流程的推理帧率不会受到明显影响。
对于告警事件,除了保存录像,还可以在Web界面里按照时间、区域、置信度进行历史检索。我把检测结果统一写入SQLite数据库,字段包括时间戳、检测框坐标、置信度、是否告警、视频文件名。这套数据量不大,SQLite完全够用,比上MySQL或PostgreSQL省事得多,而且部署时不用额外启动数据库服务。
5. 实际部署中的问题排查与性能优化
5.1 常见问题排查实录
把这套系统从开发环境搬到真实的无人机作业现场时,我遇到了不少预料之外的问题。这里整理几个最典型的,按“现象—原因—解决”的方式列出来。
第一个问题是画面撕裂和卡顿。原因是无人机图传使用的5.8GHz模拟/数字链路带宽有限,RTSP流的实际码率不稳定,加上Jetson上的解码器和推理线程竞争CPU资源。解决方式是用GStreamer管道直接设置drop-on-latency=true,允许解码器丢弃延迟过高的帧,同时把解码器输出和推理线程的队列深度设为2——超过2帧就直接丢掉最旧的帧。这样的策略虽然会偶尔丢帧,但避免了积压导致的整体延时加剧。
第二个问题是告警误报率偏高。主要原因是模型对穿着迷彩服、深色衣服的行人容易漏检,对树木、电线杆等竖直物体容易误检。解决方式是在后处理阶段增加一个“目标面积占比”的过滤条件:检测框面积小于整幅图面积的万分之五的直接忽略,因为在这个飞行高度下不可能是真实行人;大于某个阈值且宽高比严重畸形的也过滤掉。
第三个问题是长期运行内存泄漏。我最初用Python写推理服务时,每处理一帧就创建一个新的推理上下文,运行几个小时后内存占用从1.2G涨到6G以上,系统开始频繁触发交换分区,帧率直线下降。排查发现是TensorRT的execute_v2返回的张量没有及时释放,Python垃圾回收机制处理不了CUDA显存。解决方式是把输入输出缓冲区在启动前一次性分配好,推理过程反复复用同一块显存,不再新建临时对象。
下面这张表列了我遇到的其他几个问题以及对应的排查思路,方便对照参考。
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 模型推理速度慢 | TensorRT引擎未启用FP16 | 构建引擎时开启FP16标志 |
| 画面长时间无数据显示 | RTSP断流未重连 | 增加断流检测和自动重连机制 |
| 告警延迟高 | 推理线程阻塞在写盘操作 | 将磁盘编码和写盘移到独立线程 |
| 前端画面模糊 | MJPEG压缩质量过低 | 调整JPEG编码质量参数到85以上 |
| 夜间漏检严重 | 可见光相机成像质量差 | 切换或融合红外热成像输入源 |
5.2 性能调优的量化指标
整个系统优化完成后,我最终在Jetson Orin NX 16G上做了完整的性能基准测试。输入是1080P@30FPS的RTSP流,模型是FP16精度的YOLOv8s,最终测得的端到端延迟(从帧到达解码器到检测结果推送到前端)稳定在33到38毫秒之间,前端看到的实时性是完好的。
细分各环节的耗时是这样的:视频解码约3毫秒,预处理约3毫秒,TensorRT推理约12毫秒,后处理约2毫秒,WebSocket消息序列化与推送约2毫秒。在Jetson上这套链路的总耗时基本在25毫秒上下,换算成帧率约35到40FPS,超出视频源本身的30FPS,说明管线没有成为瓶颈。
对于算力更紧张的部署目标,比如Jetson Nano或树莓派类设备,也有几条降级路径。一是把输入分辨率降到416×416,推理速度能提升接近一倍,代价是mAP下降4个点左右;二是限制推理的采样频率,每2帧只推理1帧,避免逐个帧做推理;三是用更小的模型YOLOv8n,推理延迟会从12毫秒降到7毫秒左右。方案没有绝对的好坏,完全取决于业务对精度的容忍度。
夜间作业是无人机安防的常见需求,我在这套系统中预留了红外热成像视频流的接入方案。由于红外图像的颜色通道和可见光不同,后处理逻辑需要做适配,但整体架构不用变。这里只提一句:如果业务对夜间检测有强需求,建议额外训练一个针对红外图像的检测模型,而不是直接复用可见光模型,两者特征分布差异很大。
5.3 关于部署形态的一些思考
这里额外聊几句部署形态的选择。在开发这套系统时,我们考虑过三段式部署方案:机载部署、地面站部署、云中心部署。这三种方案各有优劣,不能一概而论。
机载部署的优点是时延最低。检测直接在无人机上完成,不需要经过图传链路把画面传回地面再推理,特别适合对响应时间要求极高的场景,比如无人机避障或者应急搜救。缺点是算力受限于机载平台,而且增加重量和功耗会影响续航。
地面站部署是当前的主流做法。算力可以做得很强,部署多块Jetson甚至显卡都没问题,模型可以用更大的版本,检测精度更高。缺点是画面必须经过图传链路回传,RTSP流本身有编码传输延迟,整条链路的端到端延迟会比机载部署高。我实际测试下来,1080P的画面从机载传感器到地面站解码器的延迟大约是100到150毫秒,对于安防监控来说完全可以接受。
云中心部署适合多机多站点的大规模作业。所有无人机都把视频流推送到中心推理集群,监控画面集中管理。但这种方案对网络的要求很高,在偏远地区或野外作业场景常常不现实。
我在最终的工程项目里选择了地面站部署,理由很直接:系统要处理的画面最差也是一路1080P@30FPS,地面站的算力充足;整套系统随地面站移动,不需要额外架设云端服务;断网情况下系统依然可以正常工作,只把告警数据保存在本地。
6. 经验总结与复用建议
这套系统从模型训练到部署上线,前后经历了两轮迭代。第一轮用YOLOv5做原型,验证了无人机视角下行人数检测的可行性,但小目标和密集场景的精度达不到业务要求。第二轮全面切换到YOLOv8,结合数据增强和TensorRT优化,把精度和实时性都拉到了可交付的水平。
我个人在实操中的体会是,无人机行人检测项目最大的坑往往不在模型本身,而在数据工程和部署链路。模型选型在YOLOv8这个级别基本已经进入了“能用”的区间,剩下真正拉开差距的是你如何解决俯拍视角的数据分布问题、如何把模型高效地塞进边缘设备、如何在弱网环境下保证流媒体链路的稳定性。如果你是从零开始做类似项目,我建议先按这个顺序推进:确认数据采集方案能覆盖你要飞的高度和场景,把标注标准定死,然后再投入训练和部署优化。
最后再分享一个小技巧。在做模型部署验证时,别只盯着mAP或者FPS这种宏观指标,一定要针对你的典型场景做切片测试。比如你主要飞30米高度,就单独统计这个高度下的小目标召回率;你主要在广场场景飞,就单独统计这个场景下的误检数量。宏观指标会掩盖局部的严重短板,而局部的短板恰恰是无人机巡检项目交付验收时最容易出问题的点。
这套系统的后续扩展方向也很明确。一是加入行人重识别(ReID)模块,让系统能追踪同一个行人在多架无人机画面之间的连续活动轨迹;二是加入飞行路径规划联动,检测到告警事件时自动调整无人机位置进行目标跟踪;三是把检测结果接上应急联动系统,告警信息直接推送短信或者语音通知。每一步扩展都建立在当前这套稳定的推理和监控底座上,这也是我把工程化部署部分认真写出来的原因。