尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

航拍人体检测数据集构建与YOLO训练实战

航拍人体检测数据集构建与YOLO训练实战 1. 航拍人体检测的难点与整体方案规划1.1 航拍视角为什么让检测变难了先把结论放在前面航拍人体检测和普通地面摄像头的人体检测看起来都是“找人在哪里”但本质上是两个难度级别的问题。我最初接触这个项目时也以为只是换了个数据来源实际跑下来才发现坑比想象中多得多。地面视角的人体检测目标通常在画面里占据较大面积人形特征清晰——有脸、有四肢、有明确的轮廓。航拍视角完全不是这样。以校园操场为例无人机在80到120米高度拍摄时一个成年人的身高在画面里可能只有20到40个像素姿态特征基本消失只剩一个带颜色的“小点”或“小团块”。这就是典型的小目标检测问题而小目标恰恰是YOLO系列模型最不擅长处理的情况之一。再加上航拍视角是俯视的人体的头部、肩部成了最主要的可见特征侧面轮廓和步态信息几乎不存在模型能学到的判别特征非常有限。操场场景还有另一个麻烦——背景高度结构化。跑道线条、足球场白线、篮球场边线都是规则的几何纹理和人的外形在特征上有一定相似性容易产生误检。还有个容易被忽略的点航拍画面中人的密度变化极大。课间操时几百人密集聚集体育课时三三两两分布运动会时人群呈队列排列。不同密度下的检测策略完全不一样——密集场景需要模型有更强的区分邻近目标的能力稀疏场景则考验模型对小目标的召回率。所以做这个数据集本质上是在同时解决三个问题小目标特征不足、俯视视角姿态变化、密集与稀疏场景并存。任何只针对单一问题的方案都很难真正落地。1.2 数据集的任务定位与使用场景做任何数据集之前先想清楚它服务于什么任务。校园操场航拍人体检测数据集的核心任务是给定一张无人机拍摄的操场俯视图输出画面中每个行人的边界框和类别标签。类别这里就一个——person不需要区分学生、老师、运动的人、站着的人那是更高阶的精细化任务。这个数据集能解决的问题包括但不限于以下几类校园安防场景的异常聚集检测比如课间操人数统计、大型活动人流密度评估体育课堂教学的自动化考勤通过航拍画面快速统计某块场地上的活动人数操场区域的安全预警检测到人员进入跑道、草坪等禁入区域时触发告警作为通用航拍小目标检测的基准数据用来验证和改进小目标检测算法。目标使用人群也有明确的画像做目标检测方向研究的同学、学校信息化部门的技术人员、安防类产品研发工程师以及刚入门YOLO想找一份真实场景数据练手的初学者。这个数据集的好处在于场景单一、类别单一你不需要处理复杂的多类别平衡问题可以把精力集中在检测精度和小目标优化这两个核心点上。1.3 为什么选YOLO系列而不是其他检测方案当前主流的目标检测方案无非三类两阶段检测器Faster R-CNN为代表、单阶段检测器YOLO系列、SSD、基于Transformer的检测器DETR系列。我选YOLO不是因为它最先进而是因为它最适合这个项目。YOLO的核心优势是速度与精度的平衡。航拍场景往往需要实时或准实时的处理能力——无人机在飞画面在变如果检测一帧需要几百毫秒整个系统的实用性就大打折扣。YOLOv8在GPU上推理一帧640x640的图像通常只要几十毫秒精度在某些场景下甚至不输两阶段检测器。另一方面YOLO的生态成熟度极高。从数据标注到训练再到部署几乎每个环节都有成熟工具链支持。你不用像用DETR那样自己写一堆配套代码也不用像Faster R-CNN那样额外配置区域提议网络。对于这个项目来说YOLO是最不折腾的选择。需要说明的是最近YOLO系列衍生出不少改进版本——比如引入Transformer结构、改进检测头efficient head、优化损失函数等。这些改进在某些特定数据集上确实能提升几个点的mAP但如果你的基础数据质量不过关模型结构再花哨也白搭。这个项目里我优先保证数据质量模型选型保守但可靠训练出来之后再根据瓶颈决定要不要上改进结构。2. 数据采集方案与预处理细节2.1 拍摄方案设计飞多高、怎么飞、什么时间拍数据采集是整个项目的地基这一环偷懒后面全得还债。我分享一下实际拍摄时的方案设计你可以直接照抄。飞行高度我主要采集了60米、80米、100米、120米四个高度层的数据。为什么要设置不同高度因为不同高度对应不同的目标尺度——60米高度下人体大约占40到50像素120米高度下可能就缩到15到25像素了。模型在推理时会遇到各种尺度训练数据必须覆盖这个尺度范围。如果你只在一个高度采集训练出来的模型换个高度就严重掉点。拍摄角度绝大多数镜头采用垂直俯拍云台角度-90度因为这才是真正意义上的航拍视角。但我也混入了少量45度到60度倾斜角度的画面原因是实际飞行中无人机不可能全程保持完美垂直风力、飞行姿态都会导致镜头角度偏移。加入这些数据能提升模型的鲁棒性。拍摄时间选择晴天上午10点到下午4点之间光线稳定的时段。这个时段的影子不会太长太散人体的轮廓在画面中更清晰。我分别在春秋两个季节拍摄因为季节不同学生穿的衣服颜色深浅差异很大深色衣服在俯视视角下对比度低是天然的困难样本。飞行航线采用“井”字形和“回”字形航线组合。井字形覆盖操场全域回字形加强边缘区域。有一点容易被忽视——操场边缘的看台、围栏、树木会产生大面积阴影人体一旦进入阴影区域可见度急剧下降。航线设计时特意让无人机在操场上空悬停拍摄多张尽量降低阴影干扰。设备选择我用的是一台消费级四轴无人机搭载1英寸传感器的相机有效像素2000万。有预算的话可以用带机械快门的机型能减少运动模糊。普通消费级无人机的电子快门在快速飞行时拍摄运动目标容易产生拖影影响标注精度。2.2 数据筛选与抽帧策略航拍视频素材原始量很大但并不是所有帧都适合直接作为训练数据。我按照以下优先级做了筛选剔除模糊帧无人机晃动、目标运动造成的模糊帧直接丢弃。判别方法很简单放大到100%看人体边缘边缘轮廓不锐利的一律不要。剔除重复帧悬停拍摄的连拍序列中相邻帧内容高度相似全部保留会造成数据冗余还会导致训练集和验证集之间信息泄漏——因为你可能把同一个人的同一姿态既放进了训练集又放进了验证集评估指标虚高。悬停时每5秒抽一帧。保留困难样本逆光画面、阴影区域、人群密集时段是困难样本占比控制在总量的20%到30%。这类样本前期标注痛苦但后期对模型鲁棒性的提升立竿见影。视频抽帧我用OpenCV做的每隔N帧抽一帧配合手动筛选。写了个简单脚本统计清晰度指标低于阈值直接输出到待删除列表人工确认后统一清理。2.3 图像预处理从原图到训练图的必经之路拍摄和抽帧得到的原始图像还不能直接进模型有几个预处理步骤非常关键。去畸变无人机相机尤其是广角镜头画面边缘的桶形畸变比较明显。人体目标如果出现在画面边缘边界框会略微偏移真实位置。用相机标定工具做一次畸变校正能减小误差但也不必做得太精细——YOLO训练时会做随机裁剪和缩放轻微的畸变影响有限。几何校正航拍画面不是严格正射投影操场跑道看起来可能会略微倾斜。虽然YOLO对旋转目标有一定鲁棒性但为了标注更准确我会用地面控制点做几何校正把画面修正为正射视角。亮度归一化不同时间段拍摄的图片亮度差异很大直接在原图上训练模型会学到亮度特征而不是人体特征。我没有统一做直方图均衡化而是依赖YOLO训练时的随机光度扰动来处理这一问题只在光照极端不均的画面上了做了局部提亮。注意预处理做到“够用”就好不要过度处理。你把图片磨得再干净实际部署时还是要面对各种脏乱的现场画面。训练数据的处理和部署时的一致比追求训练时数据完美重要得多。3. 标注规范与质量控制3.1 类别设计为什么只标person一类这个数据集最初也纠结过要不要区分“学生”“老师”“运动员”等子类别后来我果断放弃了。原因有两个第一航拍俯视视角下区分人的身份几乎没有可靠的外观依据。老师和学生穿的衣服不同但俯视时只能看到肩膀和头顶颜色和发型是仅有的线索误标率高得离谱。强行标注会导致大量噪声标签而噪声标签对训练的影响比缺少标签还要致命——模型会学到错误的特征映射。第二YOLO的定位是通用目标检测器类别分的越细同类样本越少小目标的检测难度反而增大。一个person类把所有样本集中在一起类别内特征一致性高模型学起来更专注。3.2 标注规则这些细节不统一会毁掉整个数据集标注是数据质量的生命线。我制定了一套明确的标注规则所有标注员必须遵守宁可慢一点也不能不统一。遮挡目标遵循“能看见就标”的原则。人体被树木、栏杆遮挡超过50%的不标注遮挡30%到50%的标注可见部分遮挡小于30%的按完整人体标注。为什么这样定因为航拍画面里遮挡很常见如果所有被遮挡的人都不标模型在部署时就永远学不会检测被遮挡目标。但完全看不见的部分又没法准确框定所以50%是个合理阈值。边界截断目标目标在图像边缘身体只露出一部分时标注露出的部分不刻意去补全看不见的区域。有人喜欢外推估计完整身体这会让边界框带有大量猜测成分不同标注员估计出来的框五花八门严重影响训练稳定性。密集人群目标几个人挤在一起时按各自可见区域分别标注不要用一个框框住一群人。这一点尤其重要——YOLO的一个预测框只能对应一个目标你把一群人标在一个框里模型训练时不知道该往哪个目标回归损失函数直接混乱。边界框贴合度航拍人体在画面中通常是一个椭圆形区域头和肩的可视部分占主体我要求边界框紧贴像素边缘上下左右留出不超过3像素的边距。框太大模型学到的目标位置偏了框太小边框截断了特征区域影响收敛。3.3 标注质量检验怎么避免标注员的“手滑”标注质量检验是很多人忽略的环节。我来说说我用的笨办法但确实有效。二次审核所有标注结果由第二个标注员独立审核重点检查三类错误——漏标画面里明显有人但没标、错位框偏移超过目标尺寸的三分之一、误框框住了树影、设备等非人物实体。一轮审核下来通常5%到8%的框需要修改。抽样计算一致性从所有图片中随机抽20%进行双重标注计算两个标注员标注结果的IoU平均值低于0.8就要重新培训标注员。这是Verification环节虽然麻烦但能确保你的数据集不是“一次性标签的堆积”。可视化检查定期把标注结果叠加在原图上检查。我发现两个很典型的问题——一是操场边缘的看台座椅被当成人体标注二是跑道的白线弯道部分被误识别为人体的手臂。这些问题光看数字指标发现不了必须人眼过一遍。标注工具我用的是LabelImg和X-AnyLabeling两种。LabelImg是老牌工具重度使用也不卡顿适合大批量标注X-AnyLabeling支持半自动标注对于背景干净的画面可以先用预训练模型生成候选框再人工修正能提升两到三倍效率。4. YOLO模型训练与评估过程解析4.1 数据集结构与划分最终数据集包含了大约8000张有效标注图片共标注了约12.5万个人体实例平均每张图15.6个目标。图片分辨率统一调整为1280x1280保持原始宽高比的不变。数据集目录结构是最基础也是最标准的YOLO格式dataset/ ├── images/ │ ├── train/ # 约6400张 │ ├── val/ # 约1200张 │ └── test/ # 约400张 ├── labels/ │ ├── train/ # 与images/train一一对应的txt标注文件 │ ├── val/ │ └── test/ ├── data.yaml └── README.md每个标注txt文件的格式是YOLO的标准格式class_id x_center y_center width height其中x_center、y_center、width、height都已经归一化到0到1之间。这里有个常见的低级错误——有人直接用了像素坐标忘了归一化训练时损失函数直接崩掉。我用Python脚本统一校验过所有标注文件确保坐标值严格落在0到1区间。划分策略上有一点要特别说明划分数据集前先把同一航次拍摄的图片归到同一时间簇再按簇划分训练验证集。这样能避免同一个人的相似姿态出现在训练集和验证集里评估结果更真实。4.2 训练配置关键参数怎么定YOLOv8是最稳妥的选择推理快训练资源要求低对中小型数据集适配性好。如果你算力充足也可以试试YOLOv9或YOLOv10但就这个项目的规模来说v8已经完全够用。几个关键参数的设定逻辑如下输入尺寸imgsz我用了1280x1280而不是默认的640x640。原因很直接——这个数据集的目标普遍较小40像素的人体在640x640的输入下只剩20像素几乎不可见。增大输入尺寸能有效保留小目标的细节特征。代价是训练时间大约翻倍显存占用也明显增加。如果你的GPU显存只有8G建议用640x640起步后期再尝试微调上1280。批大小batch根据显存动态设置16到32之间。batch太小BN层统计不稳定小目标检测的精度波动很大。batch太大又容易显存溢出。如果你是新手记住一个原则batch不要低于8。训练轮数epochs100到150轮。这个数据集不算大100轮左右就能看到明显的收敛趋势。但航拍小目标训练的收敛速度慢建议训练时观察mAP50曲线连续20轮不再上升就早停。学习率和优化器默认的SGD配合余弦退火调度即可初始学习率0.01。学习率设置太高会出现震荡太低了收敛太慢。出现过训练过程loss为NaN的情况把学习率降到0.005后恢复正常。4.3 训练过程监控与评估指标解读训练过程中不要光盯着训练集loss。YOLOv8的训练日志里包含了训练集和验证集的多个指标准确理解这些指标才知道怎么调整策略。precision精确率预测为正的框中有多少是真正的人体。这个指标高说明误检少。操场跑道的白线、看台座椅等误检会直接拉低它。recall召回率所有真实人体中有多少被成功检测出来。这个指标低说明漏检多。航拍小目标最容易在这个指标上翻车——小目标特征少模型容易直接忽略它们。mAP50IoU阈值0.5下的平均精度均值是业界最常用的综合指标。它同时考虑了precision和recall数值越高越好。这个数据集上我最终达到的mAP50在0.88左右属于一个可用的水平。mAP50-95IoU从0.5到0.95每隔0.05计算一次的平均AP。这个指标更严格对边界框的定位精度要求更高。小目标在这个指标上通常比大目标低10到15个百分点属正常现象。训练时的日志截图我就不放了但我建议你把每个epoch的指标都记录下来画成曲线。曲线出现剧烈波动说明训练不稳定出现平台期说明模型容量或数据多样性到了瓶颈。4.4 推理参数与部署要点训练完模型后推理时的参数也不是用默认值就行的。我实际部署后的经验如下置信度阈值conf设为0.25比较合适。设太高会漏检大量小目标设太低会出现成片的误检。这个值需要在验证集上扫一遍画出PR曲线后选择曲线拐点对应的值。NMS IoU阈值iou设为0.45。航拍场景里人群密集每个人的框挨得很近NMS阈值太高会把相邻不同的人的框合并掉阈值太低又去不掉重复检测。0.45是我实测比较保守的选择。还有一个部署时的技巧如果推理设备是CPU输入尺寸建议降到640x640同时开启模型量化推理延迟可以从几百毫秒降到几十毫秒精度损失在3%以内。这是一个可以接受的性价比权衡。注意部署到实际系统时别忘了做一次真实航拍画面的回验。训练集来自特定的操场、特定的光照条件换一个操场、换一个季节精度一定会有下降。通用性的问题往往是后续扩展中最大的坎也是我下一节要展开的重点。5. 常见问题与效果提升实战5.1 我在训练过程中踩过的坑我整理了一张问题排查表把这次项目里遇到的高频问题都列了出来按问题现象、根本原因、解决方法的顺序给你直接照着排查就行。问题现象根本原因解决方法训练loss不下降一直在高位震荡学习率过高或标注文件坐标越界降低学习率至0.005检查标注文件是否包含0到1范围外的数值mAP50不错但mAP50-95很低边界框定位精度不足常见于标注框贴合度不够回溯检查标注框收紧框边距至3像素内增大输入尺寸小目标漏检严重输入尺寸太小或训练数据中小目标占比不足imgsz提到1280增加高海拔拍摄图片占比使用TTA操场白线被误检为人体背景特征与前景特征混淆增加背景样本数量适当降低置信度阈值使用更大感受野的模型参数验证集指标高但实际飞行效果差训练集与验证集划分时泄漏按时间簇划分数据集确保同一航次图片同时进入训练和验证模型预测结果背景中有大量零星误检NMS阈值过低或数据集背景多样性不足提高NMS IoU阈值至0.45增加无关人员、围观群众的负样本训练时GPU显存溢出batch过大或输入分辨率过高降低batch或开启梯度累积BN层训练崩溃loss变成NaN学习率过高或某些batch内目标数量过少降低学习率保证batch内目标实例数不少于85.2 小目标检测效果的三板斧这个数据集最核心的难点就是小目标。从我踩过的坑里总结出三个有效的提升手段按效果从大到小排列第一招提高输入分辨率。这是最简单也最直接的方法。1280x1280对比640x640小目标的mAP能提升5个点以上。代价是显存和训练时间翻倍。如果显存不够你可以考虑用滑动窗口把大图切成几个小块分别推理最后合并结果。这个方案精度损失小只是推理代码要自己写。第二招多尺度训练。YOLOv8默认训练时就带有一定的多尺度增强你可以手动设置scale0.5到1.5的范围让模型见到的目标尺寸变化更丰富。实测多尺度训练比固定尺寸训练在最终测试集上能提升2到3个点。第三招测试时增强TTA。推理时对同一张图片做水平翻转、缩放等变换将多个结果融合后再输出。TTA在小目标检测上效果尤其明显能稳定提升2个点以上。缺点是推理时间成倍增加不适合对实时性要求极高的场景。5.3 数据集扩展与标注效率提升的进阶思路如果你后续想继续优化这个项目有几个方向值得投入半自动标注先用训练好的模型对新增航拍视频做预标注人工只负责修正漏检和误检。这一步能把标注效率提升3倍以上。但要小心——预标注的框存在系统性偏差如果直接拿来训练模型会惯性地学习到这些错误。人工修正时必须严格把关不能图省事直接全盘接受。跨场景迁移单一操场的数据集泛化能力有限。建议后续补充不同学校、不同布局操场、不同季节的数据。这个扩展成本和收益比是所有方向里最高的。我的实际体验是每增加一个新操场的拍摄数据模型在新场景下的mAP能提升8到12个百分点。加入负样本把操场周边道路、建筑屋顶、树木区域的航拍图作为负样本加入训练集。这些图片里没有任何行人YOLO在训练时会把它们当作背景学习对减少误检有明显帮助。负样本占比建议控制在10%以内太多了会压偏模型对正样本的学习。异常帧处理大风天无人机抖动、强反光水面、雨雾天气的画面这些“脏数据”在前期被我剔除了。但如果你专门想要一个鲁棒性强的模型可以单独保留一部分这类帧作为测试集看看模型在恶劣条件下的底线在哪里。这不影响训练但能给你提供很清晰的改进目标。结尾一点个人的经验之谈做这个项目最大的体会是航拍人体检测不是算法问题而是数据工程问题。我在算力、模型结构上花的时间加起来不到一周但在数据采集、清洗、标注规则设计上投入了一个多月。最终效果的差异也恰恰来自这里——同样的YOLOv8结构用粗糙数据训练和用高质量数据训练mAP能差出15个百分点以上。如果你也在做类似的数据集项目我的建议非常简单动手之前先把标注规则写清楚发给所有人对齐一遍飞行拍摄时多飞几个高度、多覆盖几个时间段别怕麻烦第一次训练时先跑一个50轮的小实验快速暴露问题再决定要不要大规模训练。这个数据集后续有很多可以玩的方向——加上跟踪模块做人群轨迹分析接上密度估计算法做人数统计甚至可以做行为识别在航拍视角下判断跑步、行走、聚集等状态。每一步都会有新的坑但每一步也都能带来实打实的价值。希望这篇整理能帮你少走一些弯路祝你的模型早日收敛。
返回列表