ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

构建夜晚红外飞行物检测数据集:从视频采集到YOLO格式的实战指南

2026/8/29 19:37:34 拓冰建站 浏览量
构建夜晚红外飞行物检测数据集:从视频采集到YOLO格式的实战指南 简介目标检测是计算机视觉的核心任务旨在定位和识别图像中的物体。其原理通常基于深度学习模型通过边界框回归和分类来实现。这项技术的价值在于赋能安防监控、自动驾驶和工业质检等关键领域。在安防监控特别是低空安全场景中夜间红外条件下的飞行物检测是一个技术难点。通用数据集难以应对红外图像纹理缺失、目标呈现为“热斑”以及小目标如无人机、鸟类检测的挑战。本文聚焦于构建一个面向实战的夜晚红外飞行物检测数据集详细阐述了从视频源筛选、关键帧提取、严格标注规范制定到针对红外小目标特性的数据增强策略如模拟热噪声、Mosaic增强的全流程。数据集最终包含7550张图像涵盖飞机、直升机、无人机和鸟类四类并提供VOC和YOLO格式旨在为低空安全监控等应用提供高质量、场景匹配的训练数据基础。1. 项目概述一个面向实战的夜晚红外飞行物检测数据集最近在做一个关于低空安全监控的项目核心需求是在夜间或低光照条件下对空域中的飞行物进行自动识别与告警。找了一圈公开数据集发现要么是白天的可见光图像要么类别不匹配要么就是数据量太小根本没法用。于是我决定自己动手丰衣足食从零开始构建一个专门针对“夜晚红外检测飞行物”的数据集。这个数据集最终包含了7550张标注好的图像涵盖了飞机、无人机、直升机、鸟类这四大类格式是经典的VOC同时也准备好了YOLO格式方便直接开箱即用。数据来源主要是从公开的红外监控视频中截取帧并做了一系列增强处理来提升模型的鲁棒性。今天我就把这个数据集的构建过程、技术细节以及踩过的坑完整地分享出来希望能给同样在做安防、环保监测或者低空目标识别方向的朋友们一些实实在在的参考。这个数据集的核心价值在于它的“场景特异性”。通用目标检测数据集比如COCO里也有飞机、鸟但那些都是在白天、可见光、高分辨率条件下拍摄的。而我们的应用场景是夜晚依赖的是红外热成像。红外图像中的目标其纹理、颜色信息几乎完全丢失目标呈现的是热辐射差异形成的“热斑”或“轮廓”这与可见光图像有本质区别。直接拿白天训练的模型去处理夜晚红外图效果会大打折扣甚至完全失效。因此一个高质量的、场景匹配的训练集是项目成功的基石。这个数据集就是为了填补这个空白而生的特别适合用于训练在红外监控视频流中实时检测飞行物的模型无论是用YOLOv5、v7、v8还是其他框架。2. 数据集构建的整体思路与技术选型构建一个数据集远不是简单收集图片然后打标签那么简单。尤其是对于“夜晚红外飞行物”这种特定场景从数据源头、标注规范到增强策略每一步都需要精心设计。我的整体思路可以概括为“视频溯源 - 关键帧提取 - 严格标注 - 数据增强 - 格式转换”这样一个闭环流程。2.1 为什么选择从视频截取而不是爬取图片这是第一个关键决策。很多人第一反应可能是去网上爬取飞机、无人机、鸟类的图片。但这样做有几个致命问题场景不匹配爬来的99%是可见光、白天、艺术照或特写图与我们的红外、夜晚、监控视角需求相去甚远。背景干扰网络图片背景复杂而红外监控背景相对单一主要是夜空、云层、建筑轮廓。版权与合规大规模爬取存在法律风险。而从公开的科研用红外监控视频或部分安防设备演示视频中截帧是更优选择场景保真视频本身就是在接近真实应用场景下拍摄的保证了数据分布的一致性。目标动态多样一段视频包含了目标飞行物的进入、运动、离开全过程能捕捉到不同姿态、大小、速度的目标丰富了样本的多样性。效率较高一段几分钟的视频就能提取出成百上千张有目标的帧效率远高于单张收集。注意务必确保所使用的视频源是允许用于科研和非商业/商业用途的。我主要利用了部分大学实验室公开的红外数据集视频片段以及一些安防厂商的技术演示视频已脱敏且获准用于研究。2.2 核心四类目标定义与挑战确定了飞机、无人机、直升机、鸟类这四类是经过实际需求考量的飞机主要指民航客机、小型通航飞机等。在红外图像中通常呈现为较大的、具有典型双引擎热源机翼两侧或机身整体发热的条状亮斑。直升机特点是顶部旋翼主旋翼和尾部旋翼尾桨在高速旋转时可能产生独特的热特征机身相对较短。无人机多旋翼无人机四轴、六轴等是重点。体型小热源主要来自电机和电池在红外图像中常表现为一个或几个紧密聚集的小亮斑与鸟类大小类似但热分布模式不同。鸟类通常是单只或成群的大型鸟类如鹰、雁。在红外下呈现为一个小的、椭圆形的热斑运动轨迹相对无规律。面临的共同挑战目标小尤其是无人机和鸟类在远距离监控画面中可能只占几十甚至几个像素。对比度低夜晚天空背景并非绝对冷黑可能有云层热辐射或城市热污染导致目标与背景温差不大对比度弱。类间相似性小型无人机和单只鸟类在大小和形状上极易混淆必须依赖更细微的热分布特征进行区分。2.3 标注格式为什么同时提供VOC和YOLO格式这是为了方便不同技术栈的研究者和开发者。VOC格式这是历史最悠久、支持最广泛的格式之一。它使用XML文件存储标注信息包含图片尺寸、目标类别以及边界框Bounding Box的左上角和右下角绝对坐标。很多传统的检测框架和工具链都原生支持VOC。提供VOC格式确保了数据的通用性和可追溯性。YOLO格式这是当前最流行的单阶段检测器如YOLO系列、SSD常用的格式。它使用TXT文件每行记录一个目标格式为类别索引 中心点x_center 中心点y_center 宽度width 高度height。这里的坐标和宽高都是相对于图片宽度和高度的归一化值0-1之间。直接提供YOLO格式可以让大家在训练YOLO模型时省去格式转换的步骤开箱即用。我是在标注时统一用LabelImg工具生成VOC的XML文件然后写了一个Python脚本批量转换为YOLO格式。这样一举两得。3. 数据采集与预处理的关键步骤3.1 视频源筛选与关键帧提取策略不是视频里的每一帧都值得保留。无目标的帧、目标过于模糊的帧、重复度极高的帧都应该被过滤掉。视频源标准分辨率不低于640x480确保目标有足够像素信息。必须是真正的红外热成像视频灰度或伪彩而不是低光可见光视频。场景包含夜空有飞行物活动。视频时长适中一般选择3-10分钟的片段以保证多样性。关键帧提取方法 我采用了一种结合间隔抽帧和运动检测的方法在效率和覆盖率之间取得平衡。基础抽帧首先对所有视频以每秒1帧1 FPS的固定速率进行抽帧。这能保证时间上的均匀覆盖。运动区域增强然后使用OpenCV的cv2.createBackgroundSubtractorMOG2()背景减除器对视频进行处理。这个算法能较好地适应缓慢变化的光照如云层移动并突出画面中的运动物体。对于背景减除后前景区域面积超过一定阈值例如画面总面积的0.1%的帧我会额外再抽取其前后各1-2帧。这样可以确保在目标出现、运动的关键时刻有更密集的帧被捕获丰富了目标的姿态和尺度变化。# 伪代码示例结合固定抽帧和运动检测的帧提取 import cv2 cap cv2.VideoCapture(night_ir_video.mp4) fps cap.get(cv2.CAP_PROP_FPS) extract_interval int(fps) # 每秒1帧 bg_subtractor cv2.createBackgroundSubtractorMOG2(history500, varThreshold16, detectShadowsFalse) frame_count 0 saved_count 0 while True: ret, frame cap.read() if not ret: break frame_count 1 # 策略1固定间隔抽帧 if frame_count % extract_interval 0: save_frame(frame, saved_count) saved_count 1 # 策略2运动检测触发额外抽帧 fg_mask bg_subtractor.apply(frame) # 计算运动像素比例 motion_ratio cv2.countNonZero(fg_mask) / (frame.shape[0] * frame.shape[1]) if motion_ratio 0.001: # 运动区域超过0.1% # 保存当前帧及前后帧 for offset in [-1, 0, 1]: target_frame_pos frame_count offset if target_frame_pos 0: cap.set(cv2.CAP_PROP_POS_FRAMES, target_frame_pos) ret, extra_frame cap.read() if ret: save_frame(extra_frame, saved_count) saved_count 1 cap.set(cv2.CAP_PROP_POS_FRAMES, frame_count) # 重置读取位置 cap.release()实操心得背景减除器的参数如history,varThreshold需要根据具体视频的噪声水平进行调整。如果视频背景热噪声大如热霾需要增大varThreshold来减少误检。可以先对一小段视频进行调试观察前景掩膜的效果。3.2 图像清洗与去重抽帧得到的是原始图像池里面必然存在大量无效或重复数据。无效图像过滤全黑/全白帧计算图像的平均像素值和标准差如果平均像素值接近0或255且标准差极小则可能是无效帧。目标过小帧虽然我们保留小目标但对于后续人工标注来说肉眼几乎无法辨认的目标帧没有标注价值。我会先用一个简单的“潜在目标区域”检测例如通过阈值分割寻找高亮连通区域如果最大连通区域面积小于20像素则暂时剔除该帧。注意这只是初步筛选避免标注员面对 impossible task。近似重复图像去重 连续帧之间变化可能很小。我使用图像哈希Image Hash技术具体是感知哈希pHash。pHash能捕捉图像的结构特征对亮度、对比度微小变化不敏感非常适合检测内容几乎相同的帧。from PIL import Image import imagehash import os def find_duplicates(image_folder, threshold5): hashes {} duplicates [] for filename in os.listdir(image_folder): if filename.endswith((.jpg, .png)): filepath os.path.join(image_folder, filename) with Image.open(filepath) as img: # 计算感知哈希 h imagehash.phash(img) # 检查是否有相似哈希 found_duplicate False for existing_hash, existing_file in hashes.items(): if h - existing_hash threshold: # 汉明距离小于阈值 duplicates.append((filename, existing_file)) found_duplicate True break if not found_duplicate: hashes[h] filename return duplicates对于识别出的重复帧组我只保留其中质量最高例如清晰度评价函数得分最高的一张其余放入待删除列表。经过清洗和去重我从近万张原始帧中得到了约8000张候选图像。4. 数据标注的规范、流程与质量控制标注是数据集中最耗时、也最容易出错的环节。建立清晰的规范和流程至关重要。4.1 标注规范制定我制定了一份详细的《红外飞行物标注指南》发给每一位标注人员并进行了培训。核心规范如下边界框Bounding Box原则紧密贴合框体必须紧贴目标的热辐射轮廓既不能过大包含太多背景也不能过小截断目标。完整包含对于飞机、直升机必须完整包含机身和主要热源如引擎。对于旋翼如果因运动模糊形成光晕框体应包含光晕的主要部分。对于“拖影”高速运动的物体在红外传感器上可能会有拖影类似运动模糊。标注时框体应包含拖影形成的连续亮斑区域。类别判定细则飞机 vs 直升机主要看是否有明显的、分离的旋翼热斑。如果顶部有明显的圆形或十字形亮斑主旋翼且机身较短则判为直升机否则为飞机。无人机 vs 鸟类这是难点。主要依据形状无人机多旋翼的热斑有时呈“X”或“H”形电机热源而鸟类更接近椭圆形或圆形。运动轨迹单张图难以判断时允许标注员查看前后几帧视频观察其运动方式。直线匀速的可能是无人机轨迹多变的多为鸟类。大小与高度结合场景先验知识但不过度依赖。不确定情况如果标注员无法确定类别标记为“困难样本”由我进行最终仲裁。特殊场景处理目标遮挡部分遮挡的目标仍需标注框体仅包含可见部分。多个目标重叠尽量为每个可见目标单独标注框。极小目标对于只有几个像素的点目标使用不小于3x3像素的框进行标注确保其在训练时能被有效学习。4.2 标注工具与流程使用LabelImg进行标注。它支持VOC格式输出界面友好。流程将清洗后的图像分发给2-3名标注员。标注员按照《指南》进行第一轮标注。完成一批后进行交叉验证标注员A检查标注员B的部分结果反之亦然。我作为仲裁者会抽查约10%的标注结果并集中处理所有“困难样本”。根据交叉验证和抽查中发现的问题更新《指南》并组织复盘统一标注标准。4.3 标注一致性检查与修正即使有规范不同人的标注仍有差异。我使用以下方法进行一致性检查和修正统计指标检查框体尺寸分布检查四类目标的宽高分布是否合理。例如发现某标注员标注的“鸟类”框体平均尺寸异常大就需要复查其是否将大型无人机误标为鸟。宽高比飞机通常宽高比较小长条形直升机次之无人机和鸟类接近1:1。异常的宽高比可能是错误标注的信号。可视化抽查编写脚本随机抽取几百张已标注图片将边界框和类别显示在图上进行快速人工浏览。这是发现系统性错误最有效的方法。基于预训练模型的辅助检查在标注中期我用已标注的部分数据训练了一个简单的YOLOv5模型。然后用这个模型去预测未标注或已标注的数据。对于模型高置信度预测结果与人工标注差异巨大的样本如IOU0.5且类别不同进行重点复核。这能高效地发现一些隐蔽的错误。5. 数据增强策略针对红外小目标的“对症下药”7550张标注数据对于深度学习模型来说尤其是要区分四个相似类别仍然可能面临过拟合风险。数据增强是提升模型泛化能力的利器。但增强不能乱用必须针对红外图像和小目标检测的特点来设计。5.1 基础空间与色彩增强这些是通用增强我谨慎地应用了以下部分水平翻转完全适用因为目标在水平方向是对称无区别的。随机旋转小角度限制在±15度以内。因为大角度旋转会导致目标姿态严重失真特别是对于飞机、直升机这类具有明确方向性的目标。随机缩放与裁剪模拟目标在不同距离下的尺度变化。这是最关键的增强之一。我会以0.8到1.2的比例随机缩放图像然后随机裁剪回原尺寸。这能极大地增加模型对于不同大小目标的识别能力。亮度与对比度调整红外图像的“亮度”对应温度。模拟不同环境温度、目标发热程度的变化。使用cv2.convertScaleAbs函数在合理范围内如亮度系数0.9-1.1对比度系数0.9-1.1随机调整。5.2 针对红外特性的高级增强这是本数据集增强的核心添加热噪声模拟红外传感器的热噪声。在图像上添加高斯噪声但噪声强度与像素值温度相关不更真实的模拟是添加与背景区域相关的噪声。我采用的方法是先估计图像背景的平均亮度和噪声水平然后添加与之匹配的高斯噪声。import cv2 import numpy as np def add_thermal_noise(image, mean_bg_intensity30, noise_sigma5): 为红外图像添加模拟热噪声。 image: 输入灰度图像 mean_bg_intensity: 模拟的背景平均强度影响噪声基底 noise_sigma: 噪声的标准差 h, w image.shape # 生成与图像背景强度相关的噪声基底 baseline_noise np.random.normal(mean_bg_intensity, 3, (h, w)).astype(np.float32) # 生成随机高斯噪声 random_noise np.random.normal(0, noise_sigma, (h, w)).astype(np.float32) # 合并噪声并确保值在0-255范围内 noisy_image image.astype(np.float32) baseline_noise random_noise noisy_image np.clip(noisy_image, 0, 255).astype(np.uint8) return noisy_image模拟热霾/大气衰减远距离目标在热霾中会对比度降低。我使用高斯模糊来模拟这种效应但只对背景区域或整个图像进行轻微模糊然后与原图进行加权融合降低整体对比度。def simulate_haze(image, haze_intensity0.2): 模拟热霾导致的对比度下降 blurred cv2.GaussianBlur(image, (15, 15), sigmaX10) # 将模糊后的图像模拟散射光与原图混合 hazy_image cv2.addWeighted(image, 1 - haze_intensity, blurred, haze_intensity, 0) return hazy_image局部热源干扰模拟画面中突然出现的其他热源如灯光、车辆对检测的影响。在图像的非目标区域随机位置添加一个小的、高亮的高斯斑点。5.3 针对小目标的增强策略小目标无人机、鸟是检测难点需要特别关照Mosaic 增强YOLOv4/v5引入的经典增强。将四张训练图像随机缩放、裁剪后拼接到一张图中。这能极大地增加小目标出现的上下文环境多样性并且让模型在一张图中看到更多目标尤其能缓解小目标样本不足的问题。我在应用Mosaic时会确保拼接的图片都是红外夜景避免不合理的上下文。Copy-Paste 增强将一些小目标实例随机复制粘贴到其他训练图像的合理位置天空中。这能直接增加小目标的样本数量。关键点是需要为粘贴的目标生成合理的边界框。粘贴时要进行颜色亮度调整使其与新的背景融合得更自然。避免将目标粘贴到不合理的位置如地面建筑上。多尺度训练这不是传统的数据增强但在训练过程中进行。在YOLO等框架中每隔一定迭代次数就随机改变输入图像的尺寸例如在320x320到640x640之间随机选择。这强迫模型学习在不同尺度下识别目标的能力。重要提醒数据增强应在训练阶段实时进行而不是预先处理并保存所有增强后的图片。这样能无限生成多样的训练样本。我使用的是YOLO框架内置的data augmentation配置在其基础上根据上述策略进行了定制化修改。6. 数据集划分、格式整理与交付6.1 数据集划分7550张图像我按照以下比例进行划分确保各类别在每一集中分布均衡训练集6000张 (约80%) - 用于模型参数学习。验证集1000张 (约13%) - 用于训练过程中监控模型性能调整超参数进行早停。测试集550张 (约7%) - 用于最终评估模型的泛化能力在训练过程中绝对不可见。划分时采用分层抽样确保飞机、直升机、无人机、鸟类在训练、验证、测试集中的比例大致相同。我使用scikit-learn的StratifiedShuffleSplit来实现。6.2 格式整理与结构最终交付的数据集文件夹结构清晰方便使用Night_IR_Flying_Objects_7550/ ├── Annotations/ # VOC格式的XML标注文件 (7550个) ├── JPEGImages/ # 所有图像文件 (7550张 .jpg) ├── ImageSets/ │ └── Main/ │ ├── train.txt # 训练集图片名列表 (不含后缀) │ ├── val.txt # 验证集图片名列表 │ └── test.txt # 测试集图片名列表 ├── labels_yolo/ # YOLO格式的TXT标注文件 (7550个) │ ├── train/ # 对应训练集的标签 │ ├── val/ # 对应验证集的标签 │ └── test/ # 对应测试集的标签 ├── class_names.txt # 类别列表: airplane, helicopter, uav, bird └── README.md # 数据集说明文档VOC转YOLO格式脚本核心import xml.etree.ElementTree as ET import os def convert_voc_to_yolo(xml_path, img_width, img_height, class_dict): tree ET.parse(xml_path) root tree.getroot() yolo_lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in class_dict: continue cls_id class_dict[cls_name] bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 转换为YOLO格式 (归一化的中心点x, y, 宽, 高) x_center (xmin xmax) / 2.0 / img_width y_center (ymin ymax) / 2.0 / img_height width (xmax - xmin) / img_width height (ymax - ymin) / img_height # 确保坐标在0-1之间 x_center max(0, min(1, x_center)) y_center max(0, min(1, y_center)) width max(0, min(1, width)) height max(0, min(1, height)) yolo_lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) return yolo_lines6.3 数据集使用指南与基准测试在README.md中我详细说明了数据集的结构、类别、统计信息如每类目标的数量、平均尺寸并提供了快速上手的示例。用于VOC格式训练用户只需按照标准VOC数据集目录配置路径即可。用于YOLO训练以YOLOv5为例只需创建一个data.yaml文件# data.yaml path: /path/to/Night_IR_Flying_Objects_7550 train: ImageSets/Main/train.txt # 或直接指向 images/train val: ImageSets/Main/val.txt test: ImageSets/Main/test.txt nc: 4 # 类别数 names: [airplane, helicopter, uav, bird] # 类别名称然后就可以开始训练了。我使用该数据集在YOLOv5m模型上进行了基准测试训练300轮输入尺寸640x640mAP0.5整体达到0.856。其中飞机0.92和直升机0.89较高无人机0.81和鸟类0.82相对较低这符合小目标检测难度更大的预期。推理速度在RTX 3080上每秒可处理约120张图像满足实时性要求。主要误检集中在无人机与鸟类的相互误检以及远距离小目标的漏检。7. 常见问题、避坑指南与未来优化方向7.1 标注阶段常见问题目标边界模糊红外图像中目标边缘有时是渐变的。解决以热斑的核心明亮区域为主框体包含大部分连续亮区即可。组织标注员对一批典型样本进行校准统一标准。类别判断困难解决设立“困难样本”通道由项目负责人根据前后帧视频信息仲裁。对于仲裁结果要补充到标注指南中形成案例库。标注效率低解决使用支持快捷键的标注工具如LabelImg并编写脚本自动预标注。例如用背景减除或简单阈值法得到疑似目标区域提供给标注员作为初始框标注员只需微调和选择类别效率可提升50%以上。7.2 数据增强的陷阱过度增强导致失真过大的旋转、扭曲会使红外目标的物理特性失真让模型学习到错误特征。避坑对红外图像谨慎使用几何形变类增强。缩放、裁剪、翻转是相对安全的。增强破坏上下文Mosaic增强时如果将飞机拼接到树林背景中这种不合理的上下文会干扰模型。避坑确保拼接的图像来自相似场景都是夜空或使用更智能的上下文感知增强算法但这更复杂。7.3 训练与评估中的注意事项小目标漏检策略在YOLO中可以调整模型结构使用更浅的特征图进行小目标检测因为浅层特征图分辨率高。同时在数据增强中更多地使用Mosaic和Copy-Paste。Anchor重新聚类使用K-means算法在自己的数据集上重新聚类Anchor框的尺寸使其更匹配数据集中目标的大小。对于本数据集聚类出的Anchor会包含更多小尺寸的框。类别不平衡数据集中飞机图片可能最多鸟类最少。策略在损失函数中使用类别权重给样本少的类别更高的权重。或者在采样时对少数类别的图片进行过采样。验证集过拟合如果增强只在训练集做而验证集是原始图像可能导致验证集指标虚高。避坑确保验证集和测试集是干净的、未经过增强的原始数据这样才能真实反映模型在真实场景下的性能。7.4 未来优化方向这个数据集是一个起点还有很大的优化空间增加数据多样性目前数据主要来源于固定视角的监控。未来可以补充更多不同季节夏夜、冬夜、不同天气晴空、薄雾、不同地理位置的夜间红外数据。引入时序信息当前是静态图像检测。飞行物的运动轨迹是极强的判别特征。可以构建一个视频片段数据集并标注每一帧中目标的ID支持多目标跟踪MOT任务。细分无人机类型将“无人机”类别进一步细分为“多旋翼”、“固定翼”、“直升机式”等对于低空安防应用更有价值。提供像素级分割标注边界框对于重叠物体处理不佳。未来可以增加实例分割的标注提供目标的精确掩膜支持更精细的分析。构建这个数据集的过程是一次从需求出发、以实用为导向的完整工程实践。它不仅仅是一堆图片和标签更包含了针对特定场景夜晚红外和特定任务小目标飞行物检测的解决方案思考。希望这份详细的拆解能帮助你理解如何构建一个属于自己的、高质量的专业数据集而不仅仅是停留在“下载-训练”的表面流程。在实际项目中高质量的数据往往比复杂的模型结构更能决定最终效果的上限。本文还有配套的精品资源点击获取