机场飞鸟检测数据集制作与YOLO训练实战全流程
发布时间:2026/10/17 16:00:11 锦皓数字建站

机场跑道尽头塔台的对空目视需要靠人的肉眼扫视跑道中线延长线而飞鸟群往往在起飞决断速度V1之前突然闯入一次鸟击轻则让航班返航检修重则直接中断起飞。这些年智慧交通项目里机场飞鸟检测始终是雷声大、雨点小的领域——不是需求不刚性而是能用的数据太少。大多数公开数据集要么是野外鸟类分类要么是无人机航拍的远景鸟群落到机场跑道场景里目标尺度、背景纹理、光照条件全对不上。我最近整理并复现了一套面向机场场景的飞鸟检测数据集VOC和YOLO两种标注格式齐备共1500张图片单类别bird正好覆盖跑道、滑行道、停机坪、草地围界等机场典型区域。这篇文章就把这套数据集的制作思路、格式转换细节、模型训练实测结果和落地踩坑记录一次讲清楚。适合正在做智慧机场、低空安防、鸟击防范相关项目的开发者参考也适合刚接触目标检测数据集制作的同学当一份完整实操手册。1. 机场鸟情监测到底难在哪为什么通用检测数据集不够用机场鸟击防范不是简单的看到鸟就赶走而是一个包含探测、识别、追踪、驱离、评估的完整闭环。飞鸟检测模型在这个闭环里承担的是眼睛角色——持续对视频流做实时目标检测把鸟的位置、数量、运动趋势交给后端决策系统。但机场场景对视觉检测的挑战和普通自然场景完全不同。1.1 目标小、对比度低、背景复杂三重困境叠加我在跑通用数据集比如COCO里的bird类训练出来的模型时一到机场实测就明显露怯。最大的问题是目标尺度。机场跑道视野开阔一架无人机或高清球机覆盖的视场里一只中等体型的鸟往往只占几十个像素。以1920x1080的画面为例一只翼展60厘米的鸟在200米距离上大约只占16x8像素到了400米距离直接缩到4x2像素基本就是一两个点。通用检测模型在小目标上的召回率本来就弱尤其是YOLO系模型下采样倍数高小目标特征经过多次池化后几乎被抹平这是第一道坎。第二道坎是对比度。清晨逆光、雾天、雨天、跑道道面反光都会让鸟和背景的灰度差变得极小。暗色鸟在柏油跑道上一体化白鹭在阳光直射的混凝土道面上也可能直接过曝。模型如果没见过这些低对比度阳性样本推理时就会出现大量漏检和误检——把道面接缝阴影当鸟、把排水沟盖板上的反光点当鸟的情况我实测经常发生。第三道坎是背景干扰。机场围界区域的草地里鸟在觅食时姿态低伏和草丛、碎石、灌木的纹理纠缠在一起停机坪上有大量地面标志线、廊桥阴影、地勤车辆这些都会制造伪目标。一个扎实的机场飞鸟检测数据集必须把这些脏样本包含进来而不是像很多公开数据集那样只挑了干净背景的鸟。1.2 为什么1500张够用先定场景覆盖再谈样本数量很多做数据的朋友一上来就问多少张够其实这问题问错了方向。对单类别目标检测来说决定性因素是场景覆盖度和目标形态多样性而不是绝对数量。1500张对这个任务来说是一个经过权衡的起步量级如果纯做简单场景500张就能过拟合得很漂亮如果要覆盖不同时段、不同天气、不同机场区域、不同鸟种姿态1500张能基本保证每个关键场景类型有80到120张的支撑配合数据增强后足够把模型压到可用的过拟合区间。我这套数据集在场景分布上是这么拆的跑道及跑道中线延长线约420张重点覆盖远景小目标、逆光、道面干扰滑行道与联络道约280张覆盖中景目标、地面标志线干扰停机坪与廊桥区域约260张覆盖人造物密集背景、阴影干扰围界草地区域约300张覆盖低姿态觅食鸟、草丛遮挡进近下滑道视景模拟塔台视角约240张覆盖天空背景、云层干扰这个分布不是拍脑袋定的而是围绕实际部署场景反推的。机场视觉系统一般部署在塔台、跑道两侧立杆、围界安防这几个位置每个位置的视角特征差异极大如果只按有鸟就行随便采模型很容易在某个特定视角上过拟合换个机位立刻崩。1.3 单类别设计是刻意的先把有没有鸟做到极致你可能注意到这套数据集只有bird一个类别。这不是偷懒而是面向机场鸟击防范的务实选择。鸟击风险决策的核心指标是鸟类活动强度而不是具体是哪种鸟。模型先输出目标框和置信度后续再结合人工观察或高分相机联动确认鸟种。单类别能让模型的容量全部用在找鸟这件事上减少类别间混淆带来的召回损失。当然如果现场有特定的重点防范鸟种比如体型大、集群活动的雁鸭类可以在后续阶段扩展为多类别。但从数据集制作的顺序上讲我强烈建议先把单类别的检测精度做到极致再考虑类别细分。步子迈太大容易两头都做不好。2. 从采集到标注1500张机场飞鸟图片的数据生产全流程数据集的含金量不取决于张数而取决于每张图背后是否认真处理过。很多团队拿现成网络图拼一个数据集训练时指标好看一部署就露馅。下面完整复述我制作这套数据集的流程每一步都有可复现的细节。2.1 图像来源与筛选标准宁要脏乱差不要干净美这里要说明一个原则机场场景的飞鸟检测数据集真实部署机位的视角优先级远高于图像美学。我采集时优先关注这样几类来源机场围界安防摄像机、跑道边监控杆位的实拍视频抽帧确保视角和部署一致塔台模拟视景和飞行模拟器视景生成的合成帧用于补充极端天气和远景小目标具备EXIF地理信息的鸟类摄影素材中筛选出的机场环境背景帧补充特定鸟种形态公开数据集里符合机场视角特征的图片做迁移补充但会逐一过人眼检查筛选标准有三条铁律一是画面中必须存在标注价值的飞鸟目标纯空背景不留二是背景纹理必须具有机场特征或低空开阔特征避免引入城市街景、森林等与部署环境偏差过大的上下文三是不使用任何侵犯隐私或违反拍摄伦理的图像涉及人员面部、车牌等信息的直接排除。实际筛完大约淘汰了接近四成的候选图。淘汰原因最多的是目标过小到完全无法辨认——小于10x10像素的鸟即便标注了对模型训练也只会贡献噪声不如舍弃。2.2 标注规范怎么画框、怎么处理遮挡和多目标标注是一个很容易被低估的环节。VOC格式下每张图对应一个XML文件每个目标是一个bndboxbounding box。我使用的标注规范如下框体紧贴目标可见部分不包含超出轮廓的余量若鸟翅展开包含翼尖遮挡超过60%的目标不标注遮挡在30%到60%之间的正常标注并保留画面中有多只鸟时全部标注包括远景极小目标前提是肉眼可辨认单只鸟被树枝、围网部分遮挡时只画可见部分的框不臆测被遮挡的范围低对比度目标以边缘过渡区域的中线作为框边界这套规范不是随便定的。我记得早期做标注时标注员习惯性往框里加呼吸空间导致同一个目标在不同图里的框大小波动很大训练时anchor匹配乱七八糟。后来统一按贴框原则重标了一遍mAP直接提升了3到4个点。标注工具我用了开源的LabelImg操作路径简单打开图片目录选择PascalVOC格式用矩形框画出目标保存即生成同名XML文件。批量标注时建议开启自动保存避免中途崩溃丢失进度。1500张图断断续续标了一周多单人完成每天大约标200到250张。2.3 质量控制二次审核与争议样本处理标注完成后不能直接转格式进训练必须做一轮完整的质量审核。我用的是双人交叉抽检法让另一个同事随机抽检20%的图片重新标注并与原标注计算IoUIoU低于0.6的图片全部打回重标。这轮审核下来大约有7%的图片需要修正大多数问题是低对比度下框体偏大或偏移。另一类需要单独处理的是争议样本也就是连人眼都拿不准的目标。比如远景中一棵枯树形状疑似鸟、跑道道面上的深色塑料袋、草地里的石头反光。我建了一个hard-example子目录单独存放这类图片。实操中我的策略是争议目标不标注但整张图保留在训练集里作为负样本背景。这样模型既不会学习到错误的鸟特征又能借助这些图像学会压制误检——这个技巧对机场场景尤其重要因为误检在塔台告警系统里比漏检更招人烦。2.4 数据增强有限的1500张怎么变成无限训练流训练阶段不能只靠原始图片。我这套数据集在训练时做了比较克制的在线增强组合避免过度扭曲破坏机场场景的几何特征随机水平翻转概率0.5机场左右视角不对称场景少翻转安全HSV色域微调亮度扰动±0.3饱和度±0.3色相±0.02模拟不同光照随机仿射变换旋转±5度、缩放0.8到1.2保持目标相对尺度变化Mosaic增强按YOLO训练常规策略做的四图拼接但限制了拼图来源必须同属于同一场景类型比如都是跑道场景避免不同背景纹理混搭导致模型学到错误的上下文关联这里特别想提醒一点机场场景的鸟检测增强不要用大幅度的随机裁剪和透视畸变这类变换会破坏地平线关系——机场图像里鸟的分布和地平线位置有强相关性模型如果学了乱七八糟的几何畸变实地部署时对目标位置的估计会变差。3. VOC和YOLO格式互转从标注XML到可直接训练的txt标签数据集的交付价值很大程度上体现在格式完备性上。当前主流检测框架里VOC格式XML标注适合用LabelImg标注和部分传统检测器YOLO格式txt标注则是YOLOv5/v8等现代框架的默认输入。两者需要严格对应的互转脚本不能有半点偏差。3.1 两种格式的结构差异和坐标换算关系VOC格式的bndbox是像素绝对坐标结构如下annotation folderimages/folder filenameairport_001.jpg/filename size width1920/width height1080/height depth3/depth /size object namebird/name bndbox xmin356/xmin ymin214/ymin xmax410/xmax ymax251/ymax /bndbox /object /annotation而YOLO格式存储的是归一化后的中心点坐标和宽高0 0.199479 0.215278 0.028125 0.034259换算公式很简单x_center (xmin xmax) / 2 / width y_center (ymin ymax) / 2 / height box_width (xmax - xmin) / width box_height (ymax - ymin) / height注意YOLO格式的x_center、y_center、width、height全部是0到1之间的浮点数。很多人第一次写转换脚本容易忘记除以图像宽高导致训练时报all box coordinates should be positive之类的错就是归一化出了问题。3.2 完整转换脚本VOC转YOLO如果你拿到的是VOC格式标注转YOLO直接跑下面这个Python脚本就行。脚本会读取XML和对应图片尺寸输出每张图的txt标签文件。import os import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, output_dir, classes): tree ET.parse(xml_path) root tree.getroot() img_width int(root.find(size/width).text) img_height int(root.find(size/height).text) lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in classes: continue cls_id classes.index(cls_name) bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) x_center (xmin xmax) / 2.0 / img_width y_center (ymin ymax) / 2.0 / img_height w (xmax - xmin) / img_width h (ymax - ymin) / img_height lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) txt_name os.path.splitext(os.path.basename(xml_path))[0] .txt with open(os.path.join(output_dir, txt_name), w) as f: f.write(\n.join(lines)) if __name__ __main__: classes [bird] # 你要训练的类别名列表 xml_dir Annotations out_dir labels_yolo os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(xml_dir): if xml_file.endswith(.xml): voc_to_yolo(os.path.join(xml_dir, xml_file), out_dir, classes)注意事项如果XML里出现超出图像边界的框比如目标在画面边缘被截断转换前要裁剪到有效范围否则训练时会报错或影响anchor匹配。稳妥起见在转换脚本里加一个clip操作把xmin、ymin、xmax、ymax限制在0到图像宽高之间。3.3 反向转换YOLO转VOC以及格式自检方法反过来如果你拿到的是YOLO格式标注想要转成VOC也提供一个脚本思路def yolo_to_voc(txt_path, img_width, img_height, output_dir, classes): with open(txt_path, r) as f: lines f.readlines() annotation { folder: images, filename: os.path.basename(txt_path).replace(.txt, .jpg), size: {width: img_width, height: img_height, depth: 3}, objects: [] } for line in lines: parts line.strip().split() cls_id int(parts[0]) x_center float(parts[1]) y_center float(parts[2]) w float(parts[3]) h float(parts[4]) xmin int((x_center - w / 2) * img_width) xmax int((x_center w / 2) * img_width) ymin int((y_center - h / 2) * img_height) ymax int((y_center h / 2) * img_height) # 越界裁剪 xmin max(0, xmin) ymin max(0, ymin) xmax min(img_width, xmax) ymax min(img_height, ymax) annotation[objects].append({ name: classes[cls_id], bndbox: [xmin, ymin, xmax, ymax] }) # 生成XML并写入文件这里省略XML序列化代码做完转换之后有个特别重要的动作格式自检。转换脚本跑完不等于格式正确。我每次都会写一个校验脚本统计每个txt文件的目标数量、坐标范围、归一化值是否在0到1之间并随机抽几张图把box画出来人眼确认。坐标范围错误是训练失败的头号杀手这一步不能省。顺便说一句交付数据集时除了图片和标签我还额外生成了一份classes.txt和数据划分清单。YOLO训练时还需要一个数据集配置文件data.yaml内容大致是train: images/train val: images/val nc: 1 names: [bird]这份文件别看简单路径写错或类别名和标签对不上训练器会直接报错或者静默地用错标签检查起来非常费劲。4. 用这套数据集训一个能用的飞鸟检测模型数据集的最终价值要透过模型体现。我拿这套VOCYOLO格式的1500张机场飞鸟图片跑了一轮完整的YOLOv8训练把配置和结论分享出来。4.1 数据划分与训练配置数据划分上我采用了比默认7:2:1更保守一些的方案训练集1050张、验证集300张、测试集150张。这里特意说明一下验证集和测试集我都是按场景源分组划分的而不是简单随机划分。比如某一路监控的视频抽帧抽出的50帧要么全部进训练集要么全部进验证集不能打散混入。理由是避免同一段视频的相邻帧同时出现在训练集和验证集里导致验证指标虚高——这个细节很多人忽略但实际影响很大。训练命令用的是YOLOv8的标准APIfrom ultralytics import YOLO model YOLO(yolov8s.pt) results model.train( dataairport_bird.yaml, epochs100, imgsz1280, batch16, devicecuda, patience20, augmentTrue )图像尺寸我选了1280而不是默认的640原因很直接机场飞鸟是小目标在640分辨率下很多鸟只有一二十像素特征太弱。放大到1280推理虽然会有速度和显存开销但对小目标召回率的提升非常明显。如果你的部署硬件算力有限可以采用一个折中方案训练时用1280导出模型时用onnx的dynamic shape部署推理按输入分辨率640同时叠加TTATest-Time Augmentation来弥补。4.2 实测指标分布不是所有场景都表现得一样好完整训练100轮后模型在测试集上的最终指标如下场景类型精确率Precision召回率Recall平均精度mAP0.5跑道远景小目标0.820.710.76滑行道中景0.910.880.90停机坪人造物背景0.880.850.87围界低姿态目标0.840.790.82天空背景进近视角0.930.900.92整体0.870.830.85最弱的还是跑道远景小目标这一栏召回率只有0.71。换句话说每10只远处的小鸟会有将近3只漏检。这个数字在机场场景里是不能接受的因为远处的鸟往往是下一批飞向跑道的关键前哨。针对这个短板我在后续迭代里做了几件事对远景小目标图片做过采样复制等效提高这类样本在训练集中的权重把训练分辨率提升到1536对极小目标有边际改善尝试在模型neck部分插入更浅层的特征融合让检测头获得更高分辨率的特征这几项改进大约能把远景召回率从0.71提升到0.78左右但代价是推理帧率下降15%到20%。工程上如何取舍取决于现场告警系统的实时性要求。4.3 推理实测1080p视频流下的表现把训练好的模型导出成TensorRT engine后我在一张消费级显卡上对航拍机场模拟视频流做了推理测试。视频分辨率1920x1080模型输入1280关闭TTA测得的FPS约为42帧单帧平均延迟约24毫秒。这个速度对塔台辅助告警或围界安防的多路视频流接入来说是够用的——通常一路视频分配30到50ms的推理预算已经算宽松了。推理时我额外加了一个最小置信度自适应逻辑当单帧检测出的目标数量少于2个时把置信度阈值从默认的0.25动态下降到0.15减少远端极小目标的漏检当检测目标多于5个时把阈值回升到0.3压制背景误检。这个规则算不上多么高级但实测能在一个月时段的视频回放里减少大量无效告警。4.4 模型部署形态挂到机场现有视频监控系统上的思路数据集和模型最终要落到业务系统里。机场的安防设备现状是海康、大华等厂商的监控摄像头和NVR已经铺开新建一套单独的AI识别系统成本高且周期长。更实际的做法是利用现有的视频流接入网关把模型封装成一个HTTP推理服务通过ONNX Runtime或TensorRT加载对外提供REST接口。业务流程是NVR通过RTSP拉流视频抽帧程序按固定间隔比如每3秒一帧把帧POST给推理服务推理服务返回鸟目标框和置信度后端联动电子围栏和告警大屏。这个链路里最难的反而不是模型精度而是视频流延迟和帧同步问题。RTSP拉流到实际推理帧之间往往有几秒的系统延迟对高速飞行的鸟来说这几秒可能导致目标已经飞出了上一帧的预测范围。所以在部署层面我更推荐在靠近摄像头的边缘节点直接做推理而不是经过中心化的流媒体服务器转发。5. 机场场景落地时的四类坑实测踩过才明白训练指标好看只是第一步真正考验数据集和模型的是现场环境。我把实际踩坑的几个典型场景整理出来这些经验在纯实验室里很难获得。5.1 场景坑雨雾天气导致的目标特征肉眼不可辨机场安防系统遇到雨天镜头上有水珠远景目标直接糊成一片。我在实测中遇到过一个极端案例雨天黄昏一群鸽子降落在跑道道肩上模型完全没有输出——人眼在原始画面里也只能隐约看到灰度略深的色块。这类图片在数据集中严重不足即便是1500张的规模雨雾样本也就占了几十张。解决问题的方向不是单纯堆雨雾图片而是利用图像增强手段模拟雨雾条件下的退化效果。我在训练集中离线生成了三类退化样本高斯模糊模拟雾天、随机水珠纹理叠加模拟镜头雨滴、降低全局对比度模拟阴雨光线。这三类增强显著提高了模型在雨雾天的鲁棒性实测召回率从不足0.5提升到0.65左右。5.2 指标坑mAP不能直接当现场告警质量标准mAP衡量的是检测框的定位精度和分类置信度排序但机场现场告警关心的是事件级指标——每次鸟群闯入是否被捕获、每个告警是否可信。我在实际评估中改用了一套现场口径的统计方法以目标是否进入跑道安全区为事件统计事件级检出率和误报率而不是单纯看每一帧的mAP。这两套指标经常出现背离模型mAP为0.85但事件级漏报依然集中在快速移动的鸟群上原因在于单帧检测可能偶尔失手而事件跟踪环节把丢失目标的轨迹接续逻辑做得不够好。如果你在做机场项目建议提前和业务方对齐事件级指标的定义否则算法团队和用户方会在验收时鸡同鸭讲。5.3 生态坑飞鸟检测不能只靠光学摄像头这是我特别想提醒的一点视觉检测模型做得再好也只是鸟击防范体系里的一环。机场现场通常还需要雷达探测、声学驱鸟设备、生态调查通过控制草地昆虫和啮齿动物减少鸟类觅食吸引力等多手段协同。视觉模型适合做已进入视场目标的精细定位但探测距离和全向覆盖能力天然受限。如果用户方的预期是用AI完全替代人工瞭望这个预期本身就需要修正。我参与的某次项目汇报中客户希望模型能提前10秒预警鸟群进入跑道。10秒对于视频检测的感知距离来说完全覆盖不了最终是通过接入机场场面监视雷达的航迹数据和视觉目标做跨源融合才勉强达到了客户的期望。技术方案上没有问题但沟通成本非常高提前说明边界比事后补救要好得多。5.4 合规坑机场数据不是想采就能采最后必须提一句数据合规。机场属于重点安全防范区域图像采集涉及空防安全、个人隐私和涉密管理要求。这1500张数据集的制作我在采集阶段规避了所有涉及运营敏感信息的画面不使用任何包含旅客面部、行李牌、航班号、机坪内部实时运营状态的原始监控录像。如果你的项目需要从实际机场获取数据务必先走完内部数据合规审批流程和机场方签订数据使用协议明确数据使用范围、存储方式和销毁期限。数据合规这件事出问题的代价远大于技术收益。6. 数据集的后续扩展方向与版本迭代建议一套数据集交付并不意味着项目结束针对机场飞鸟检测这个持续演进的任务我在实践中有几个明确的迭代方向。6.1 多视角数据融合双球机枪机协同标定数据的价值目前这套数据集的标注是基于单视角的。机场现场部署中往往是多台相机对同一片空域或同一段跑道有重叠视场如果能给重叠视场的多张图片标注同一批目标的跨视角关联ID就能训练出具备跨视角目标匹配能力的模型这对目标的连续跟踪和三维定位非常有价值。不过跨视角标注成本很高我建议在下一版数据集中以小规模试点的方式推进先标注50到100组重叠视角图像验证价值后再扩大。6.2 时空信息增强让模型利用目标运动趋势静态图像检测无法表达鸟在往跑道方向飞这个运动特征。机场场景的检测任务从本质上看是一个视频时序任务我在最新一轮试验中尝试把连续5帧的目标检测结果送入一个轻量的时序模型输出目标的运动趋势分类接近/远离/盘旋/静止。这个方向的效果比单纯提升单帧检测精度更明显因为塔台告警需要的是趋势而不是此刻位置。数据集层面如果需要支撑这个方向标注格式要从单帧box扩展到轨迹ID和时间戳复杂度会上一个台阶。6.3 恶劣天气合成数据的权重提升前面说到雨雾样本是当前数据集的短板。接下来的版本迭代里我计划增加合成恶劣天气样本的比例从当前的少量增强提升到10%到15%覆盖雾天、雨天、逆光、雪天如果项目涉及高寒地区机场等场景。合成数据的优势在于可以精确控制退化程度批量生成大量样本劣势在于容易产生域偏移。我的经验是合成样本与真实样本按3:1混合使用效果最好合成比例太高反而会拉低真实场景下的表现。6.4 开放评测基准给行业一个可对标的机场鸟情难度榜最后想聊一个更大的设想。目前飞鸟检测在学术界和工业界都没有统一评测基准很多团队各做各的指标不可比。如果这套数据集后续能够整理出一个标准化的评测脚本和排行榜体系让业内团队在相同的训练集/测试集划分下提交推理结果对推动整个机场智慧化进程会很有价值。当然这件事需要多方协作不是单靠一个数据集就能做成但至少我们要在发布时给出清晰的评估口径和基线结果让别人有可复用的对标依据。我在整理这套数据集的过程中最大的体会是数据集的良心取决于你在标注规范、场景覆盖和边界样本处理上花的心思而不是漂亮的封面图。对机场飞鸟检测这种安全敏感的场景来说多一张低对比度、小目标、有争议的困难样本比多一百张干净美观的普通样本更有价值。最后想跟你分享一个小技巧如果你打算自己采集构建数据集开工前先花半天时间围绕部署机位蹲点观察目标的光照、尺寸和运动模式分布这会比任何标注工具的使用技巧都更能提高最终模型的上限。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。