当前位置: 首页 > news >正文

【Dogfight论文复现】无人机视频中检测无人机的目标检测模型

在这里插入图片描述

论文名称:Dogfight: Detecting Drones from Drones Videos
论文地址:https://arxiv.org/pdf/2103.17242

博客内容:复现这篇文章的Dogfight模型,也就是再自己本地,NPS数据集上跑通这个模型的代码,得到模型,成功推理,并达到论文中的精度

数据集准备→环境搭建→模型实现→训练配置→推理验证→精度调优

一、数据集准备

获取

论文指出 NPS-Drones 原始标注不精确( bounding box 过大),重新处理了一下,在Drone-Detection/annotations/NPS-Drones-Dataset路径下。
在这里插入图片描述

数据划分:按论文设置,前 40 个视频为 “训练 + 验证集”(建议 9:1 划分训练 / 验证),后 10 个为测试集

二、仓库克隆与环境搭建

模型仓库

GitHub 仓库 mwaseema/Drone-Detection
论文第一作者 “Muhammad Waseem Ashraf” ,仓库用户名 “mwaseema” 对应论文作者邮箱前缀 “mohammadwaseem”

环境配置

# git clone https://github.com/mwaseema/image-segmentation-keras-implementation
# 也可下载ZIP,再unzipcd image-segmentation-keras-implementation
make

添加仓库路径到 PYTHONPATH

export PYTHONPATH="/root/autodl-tmp/Drone-Detection-main:$PYTHONPATH"

三、数据预处理

Videos to frames and annotations to masks

视频转帧与标注转掩码

  • 脚本路径:tools/video_to_frames_and_masks.py
  • 作用:将原始视频拆分为帧,并根据标注文件,利用边界框信息生成每个帧对应的生成二进制掩码(前景为目标无人机,背景为 0)
  • 使用:提供包含视频和标注文件的文件夹的绝对路径。还需要将foreground_in_mask的值设置为1(用于训练数据)或255(用于测试数据)

注意:作者改后的NPS数据集标签名称为Clip_002.txt,需要修改脚本,使能适应001,025这样的编号。

  1. 视频和标签文件夹路径
videos_folder = '/root/autodl-tmp/NPS-drone/Videos'
# annotations_folder = '/root/autodl-tmp/NPS-drone/Video_Annotation'# 修改后的标签
annotations_folder = '/root/autodl-tmp/Drone-Detection/annotations/NPS-Drones-Dataset'
  1. 帧保存间隔
    根据需求设置(默认每 4 帧保存 1 帧,训练数据可保留更多帧,设为 1 则保存所有帧)
save_frame = 4  # 例如:1表示保存所有帧,4表示每4帧保存1帧
  1. 掩码前景值
    如果处理的是训练数据,设为1;测试数据设为255:
foreground_in_mask = 1  # 训练数据用1,测试数据用255
  1. 输出目录
    指向你创建的输出文件夹(用于存放生成的帧和掩码):
frames_output_folder = '/root/autodl-tmp/NPS-drone/frames'
masks_output_folder = '/root/autodl-tmp/NPS-drone/masks'

运行脚本

cd ~/Drone-Detection/tools
python video_to_frames_and_masks.py

四、阶段一:Spatial (2D) stage

Generate image crops 生成图像裁剪

由于无人机目标较小,,使用tools/image_crops/generate_crops_of_images_by_dividing.py

我们的图像分辨率较高,但目标(无人机)非常小,因此我们对图像进行了 9 次重叠裁剪,对高分辨率帧生成重叠裁剪块(提升小目标检测精度)

  • 脚本路径:tools/image_crops/generate_crops_of_images_by_dividing.py
  • 该文件包含一个GenerateCrops类,其中有输入和输出数据的变量,为这些变量设置合适的值后运行代码即可。
  • “tools/image_crops” 目录下的代码中,提供了从给定图像中获取 9 个和 4 个小 patches 的实现。
  1. 修改上一步的两个路径和输出路径
class GenerateCrops:def __init__(self):# 输入路径:上一步生成的帧和掩码文件夹self.input_frames_folder = '/root/autodl-tmp/NPS-drone/frames'self.input_ground_truth_folder = '/root/autodl-tmp/NPS-drone/masks'# 输出路径:裁剪块保存的位置self.output_frames_folder = '/root/autodl-tmp/NPS-drone/crops/frames'self.output_ground_truth_folder = '/root/autodl-tmp/NPS-drone/crops/masks'

运行脚本:

cd Drone-Detection/tools/image_crops
python generate_crops_of_images_by_dividing.py

Training

  • 第一阶段2D空间模型训练代码目录:/root/autodl-tmp/Drone-Detection/train/spatial
  • train/spatial/config.py文件中设置配置变量的值,然后执行train/spatial/train.py文件开始模型训练。
  • 使用生成的裁剪块(帧 + 掩码)训练 2D 模型,学习单帧中无人机的空间特征(如位置、形状)。

核心输入

  • 裁剪后的单帧图:/root/autodl-tmp/NPS-drone/crops/frames(输入图像)
  • 裁剪后的掩码:/root/autodl-tmp/NPS-drone/crops/masks(监督标签,用于计算损失)
  1. 修改配置文件Drone-Detection/train/spatial/config
    修改路径,使指向之前生成的裁剪块
# 1. 数据集根路径(根据你的裁剪块位置修改)
my_base_path = "/root/autodl-tmp/NPS-drone/crops"  # 裁剪块的根目录
dataset_base_path = ""  # 保持空,因为上面已包含完整路径# 2. 模型名称(自定义,用于保存权重文件夹)
model_used = "pspnet_drone"  # 例如:pspnet_50_drone_v1# 3. 训练集路径(指向裁剪块的帧和掩码)
dataset_links = {'train': {'annotations': os.path.join(my_base_path, 'masks'),  # 裁剪后的掩码文件夹'images': os.path.join(my_base_path, 'frames'),      # 裁剪后的帧文件夹'temp': os.path.join(my_base_path, 'weights', model_used),  # 模型权重保存路径},
}# 4. 训练超参数(根据需求调整)
n_classes = 2  # 背景 + 无人机(固定不变)
epochs = 100   # 训练轮次(可根据效果调整,如50、200)
batch_size = 3  # 批次大小(根据GPU显存调整,显存小则改小)
steps_per_epoch = 1024  # 每轮训练的步数# 5. 微调设置(若从零训练,保持默认)
is_finetune = False  # 是否使用预训练权重微调
old_weight_path = ''  # 若微调,填写预训练权重路径
  1. 直接执行 train_model.py 即可启动训练:
cd /root/autodl-tmp/Drone-Detection  # 进入代码库根目录
python train/spatial/train_model.py

说明:

  • 输出日志:终端会打印每轮训练的损失值(loss)
  • 权重保存:每轮训练结束后,模型权重会保存到 dataset_links['train']['temp'] 路径(即 /root/autodl-tmp/NPS-drone/crops/weights/pspnet_drone
  • 中断与续训:若训练中断,重新运行脚本会自动从最近保存的权重继续训练(依赖 keras_segmentation 的 checkpoint 机制)。
  • 训练完成后,权重文件会保存在设置的 temp 路径下,下一步可用于 test_model/spatial/test_and_score.py 进行模型评估

Testing

复制你想要在测试数据上进行评估的权重的绝对路径,将训练权重的绝对路径作为数组元素粘贴到test_model/spatial/checkpoint_paths.py文件中。在test_model/spatial/config.py文件中为现有变量添加配置值,然后运行test_model/spatial/test_and_score.py文件对测试数据进行评估。

五、阶段二:Temporal (3D) stage

时间3D模型训练用数据预处理

最终需得到两个关键文件夹(对应config.py中的路径):

  • dataset_base_path/train/i3d_features:存储视频时序片段的 I3D 特征(.npy格式)。

  • dataset_base_path/train/ground_truths:存储与 I3D 特征对应的时序标注掩码(二值图像,无人机区域为 1,背景为 0)。

  • 膨胀边界(扩大候选区域):tools/binary_mask_dilation.py

Step 3:去除无关大区域

膨胀后可能存在过大的候选区域(非无人机),需过滤。
tools/remove_small_big_boxes.py

# 输入Step 2.2膨胀后的掩码文件夹
input_mask_folder = os.path.join(dataset_base_path, "train", "motion_boundaries_dilated")  
# 输出过滤后的文件夹
output_mask_folder = os.path.join(dataset_base_path, "train", "motion_boundaries_filtered")  

Step 4:CRF 优化候选框(贴合无人机边界)
用条件随机场细化候选区域,使边界更精准。
tools/crf/crf_on_labels.py
运行脚本时指定参数

python tools/crf/crf_on_labels.py \--frames_folder "path/to/nps/frames"  # 2D处理时已生成的视频单帧(如drones_dataset/train/frames)\--labels_mask_folder "drones_dataset/train/motion_boundaries_filtered"  # Step 3输出的文件夹\--output_folder "drones_dataset/train/crf_output"  # CRF优化后的掩码输出路径\--save_boxes_as_json True  # 保存候选框为JSON(用于后续生成cuboids)

Step 5:转换候选框格式(适配 cuboids 生成)
将 CRF 输出的 JSON 候选框转换为 3D 模型所需的格式。
tools/boxes_list_to_patch_information_json.py

# 输入CRF生成的JSON候选框文件夹(Step 4中--output_folder下的JSON文件)
input_json_folder = "drones_dataset/train/crf_output"  
# 输出转换后的patch信息文件夹(用于生成cuboids)
output_patch_folder = "drones_dataset/train/patch_information"  

Step 6:生成固定尺寸 cuboids(时序片段)
NPS 数据集使用固定尺寸 cuboids,基于候选框提取连续视频帧片段。

使用脚本:tools/cuboids/volumes_with_tracking_of_generated_boxes_with_stabilization.py(README 明确 NPS 用此脚本)

# 原始视频帧文件夹(同Step 4的--frames_folder)
frames_folder = "path/to/nps/frames"  
# Step 5输出的patch信息文件夹
patch_information_folder = "drones_dataset/train/patch_information"  
# 输出cuboids的帧文件夹(连续帧片段,如5帧为一个cuboid)
output_cuboids_frames_folder = "drones_dataset/train/cuboids_frames"  
# 输出cuboids对应的标注掩码文件夹(后续作为ground_truths)
output_cuboids_masks_folder = "drones_dataset/train/cuboids_masks"  
# 固定尺寸设置(如224x224,根据I3D模型输入调整)
cuboid_size = (224, 224)  
# 时序长度(连续帧数,如5帧)
temporal_length = 5  

Step 7:提取 I3D 特征(3D 模型输入)

Motion boundaries运动边界

我们使用光流获取运动边界,以得到良好的候选区域。

  • 代码文件:
    • NPS数据集用:tools/optical_flow_motion_boundaries.py
    • FL-drones 数据集:tools/optical_flow_motion_boundaries_with_stabilization.py,这个脚本会在帧稳定化后生成运动边界。
    • 因为FL数据集的背景运动占主导地位,掩盖了无人机。为解决此问题,在生成运动边界前先进行运动稳定化处理。
  • 功能:为给定视频生成并保存运动边界,生成视频中动态区域的二值掩码(无人机为运动目标,掩码为白色)。

运行代码文件前,需提供包含视频的文件夹路径和运动边界的输出路径。

videos_folder = '/root/autodl-tmp/NPS-drone/Videos'
optical_flow_output_folder = '/root/autodl-tmp/NPS-drone/optical_flow'

Motion boundaries edges运动边界边缘

  • 稳定化后生成的运动边界在边缘处有较高的值,可使用以下代码去除
  • 脚本路径:tools/remove_motion_boundary_edges.py

Motion boundaries dilation运动边界膨胀

  • 对较细的运动边界进行膨胀,以得到能更好覆盖无人机的候选区域:
  • tools/binary_mask_dilation.py

Remove irrelevant candidate regions去除无关候选区域

  • 运动边界膨胀后,一些候选区域表现为较大的运动边界,无法准确代表无人机。可使用以下代码文件去除此类区域。
  • 文件中小框的阈值设为 0,以确保只去除大框
  • tools/remove_small_big_boxes.py

CRF on the candidate boxes候选框的 CRF 处理

  • 我们使用条件随机场(CRF)确保从运动边界获得的候选框紧密包围无人机
  • 脚本路径:tools/crf/crf_on_labels.py
  • 该代码文件接受以下参数:
    • --frames_folder:保存 png 格式视频帧的文件夹
    • --labels_mask_folder:设置为从候选区域中去除无关大框后得到的二值掩码所在的文件夹
    • --output_folder:设置为应用 CRF 后输出二值掩码的文件夹
    • --save_boxes_as_json:设为 true 可将应用 CRF 后的框保存为 JSON 文件

执行上述代码后,可使用以下代码文件将以 JSON 格式获得的框转换为下一步中使用的自定义格式:tools/boxes_list_to_patch_information_json.py

Generating cuboids生成立方体(Cuboids)

  • 对 NPS 数据集使用固定尺寸的立方体,
  • 对 FL-Drones 数据集使用多尺度立方体。

Fixed sized cuboids固定尺寸立方体

可使用以下脚本生成固定尺寸的立方体(用于 NPS 无人机数据集):tools/cuboids/volumes_with_tracking_of_generated_boxes_with_stabilization.py
该脚本将使用上一步生成的 patch 信息 JSON 文件。

Multi sized cuboids多尺寸立方体

可使用以下脚本生成多尺寸立方体(用于 FL-Drones 数据集):tools/cuboids/multi_scale_volumes_with_tracking_and_stabilization_using_masks.py

对于多尺寸立方体,真值、2D 检测结果等会随帧一起变换。这样无需使用逆矩阵将检测结果转换回来即可计算分数。
如果在稳定化方面遇到问题,可尝试降低用于视频稳定化的最大角点数量(在第 218 行)。

I3D features I3D 特征

我们使用 deepmind 的 kinetics I3D 模型(带预训练权重)从生成的立方体中提取特征。
I3D 的仓库地址为:deepmind/kinetics-i3d: 基于 Kinetics 数据集训练的视频分类卷积神经网络模型

我们没有从最后一层获取输出,而是从中间层获取特征(维度为 1x2x14x14x480)。这些特征在第 2 轴上取平均,然后重塑为 14x14x480,再输入到我们提出的时间流水线中。此外,我们只使用了 I3D 的 RGB 流,而非双流网络。

Training

对于时间阶段的训练,在train/temporal/config.py中设置值,然后使用train/temporal/train_model.py开始训练。

时间(3D)模型训练

/root/autodl-tmp/Drone-Detection/train/temporal

  1. 修改时序模型配置文件Drone-Detection/train/temporal/config.py,(主要是 I3D 特征和对应标注)
  • images 必须指向I3D 特征文件夹(时序模型依赖视频的时序特征,需提前通过工具提取,如 tools/features/extract_i3d_features.py,若未生成需先执行此步骤)。
  • annotations 对应时序标注掩码(需与 I3D 特征的时序顺序匹配)。
# 1. 数据集根路径(根据你的数据位置修改)
my_base_path = "/root/autodl-tmp/NPS-drone"  # 你的数据根目录
dataset_base_path = "temporal_data"  # 时序数据子目录(可自定义)# 拼接完整路径
dataset_base_path = os.path.join(my_base_path, dataset_base_path)# 2. 模型名称(自定义,用于保存权重文件夹)
model_used = "i3d_pspnet_drone"  # 例如:i3d_pspnet_v1# 3. 训练数据路径(关键:指向I3D特征和标注)
dataset_links = {'train': {'annotations': os.path.join(dataset_base_path, 'train', 'ground_truths'),  # 时序标注掩码文件夹'images': os.path.join(dataset_base_path, 'train', 'i3d_features'),       # I3D特征文件夹(需提前生成)'temp': os.path.join(dataset_base_path, 'temp', model_used, model_used),  # 模型权重保存路径},
}# 4. 训练超参数(根据GPU显存调整)
n_classes = 2  # 固定为“背景+无人机”
epochs = 100   # 训练轮次(可根据效果调整)
batch_size = 4  # 批次大小(显存不足则减小,如2)
steps_per_epoch = 1024  # 每轮训练步数# 5. 微调设置(若使用预训练权重)
is_finetune = False  # 是否微调(首次训练设为False)
old_weight_path = ''  # 若微调,填写之前保存的权重路径
  1. 运行脚本
cd /root/autodl-tmp/Drone-Detection
python train/temporal/train_model.py

Testing

复制你想要在测试数据上进行评估的权重的绝对路径,将其作为数组元素粘贴到test_model/temporal/checkpoint_paths.py文件中。在test_model/temporal/config.py文件中为现有变量添加配置值,然后运行test_model/temporal/test.py文件对测试数据进行评估。

NMS

使用 I3D 特征从时间阶段生成结果后,将预测结果通过 NMS 阶段:tools/nms/nms_generated_boxes.py

Results generation

可使用以下代码生成结果:test_model/temporal/results_generation.py
也可使用以下文件中的代码计算结果:tools/generate_annotations_and_scores.py

Temporal consistency

我们利用时间一致性去除检测结果中的噪声假阳性。相关代码在以下文件中:tools/video_tubes/remove_noisy_false_positives_by_tracking.py

http://www.dtcms.com/a/423421.html

相关文章:

  • 北京矿建建设集团有限公司 网站谷歌seo服务公司
  • 食品行业数字化转型实战:工艺优化解决方案中的四大核心模块详解
  • 【文件上传漏洞】绕过验证上
  • UDP的理解
  • 可信的昆明网站建设什么网站是免费的
  • 【gin框架读取参数的方式】
  • 南京建网站wordpress 主题demo
  • 铜陵高端网站建设seo优化关键词0
  • 济南教育论坛网站建设哪个平台查企业免费
  • asp连接数据库做登录网站完整下载辽宁城乡住房建设厅网站首页
  • golang可观测-无侵入式agent技术原理
  • Hive中map函数的基础知识及使用
  • 《法务RAG开发不踩坑:Kiln+LlamaIndex+Helicone的协同方法指南》
  • 五金外贸接单网站个人如何做购物网站 关于支付接口
  • 做小型企业网站多少钱浙江网站优化公司
  • 美团滑块-[h5Fingerprint] 加密分析
  • 华北水利水电大学信息工程学院赴郑州埃文科技有限公司交流
  • 如何申请域名网站注册怎么上传做 好的网站吗
  • 网站开发工程师要求php红色酒类食品企业网站源码
  • AI视频技术的边界:现状、限制与未来展望
  • 企业门户网站费用2345网止导航
  • 有自己的网站怎么做淘宝客济南网站建设系统
  • Android音频学习(二十一)——ALSA简介
  • Android 12 SplashScreen启动屏
  • 游戏开发难还是网站开发难装宽带需要多少钱一个月
  • Unity内嵌浏览器插件:3DWebView,显示不支持的音频/视频格式解决办法
  • 网站开发需求列表dw网页设计作业成品加解析
  • Coze源码分析-资源库-编辑插件-后端源码-IDL/API/应用服务层
  • JuiceSSH+cpolar:手机如何轻松远程连接内网虚拟机?
  • 模式组合应用-代理模式