无人机视角下小目标人群计数系统
本项目面向无人机俯拍场景下的密集人群计数与人体定位任务,采用 P2PNet(Point-to-Point Network)端到端检测框架,结合 VisDrone2020-CC 数据集完成模型训练,并集成为具备登录鉴权、系统首页总览、图片检测、批量检测、历史记录、模型管理、训练指标与数据集统计可视化等完整功能的桌面应用系统。
目录
一、数据集
1.1 数据集概述
本项目使用 VisDrone2020-CC(Crowd Counting 子任务)数据集。该数据集由南开大学 VisDrone 团队采集,图像均来自无人机在不同高度、角度、光照条件下的真实飞行拍摄,是目前最具代表性的无人机视角人群计数基准之一。
1.2 数据规模
| 统计项 | 数值 |
|---|---|
| 总序列数 | 112 个视频序列 |
| 训练序列数 | 82 个(带标注) |
| 测试序列数 | 30 个 |
| 每序列帧数 | 30 帧(固定) |
| 总图片数 | 3,360 张 |
| 总标注人头点数 | 362,727 个 |
| 图片分辨率 | 1920 × 1080 px |
1.3 图片特点
-
无人机俯视视角:拍摄高度在数十至数百米之间,人体在画面中呈现为极小目标(通常仅占 5~30 px 大小),且大量存在部分遮挡或完全遮挡现象。
-
多场景覆盖:广场、公路、体育场、居民区等多种场景,白天与傍晚均有采集。
-
密度差异显著:单帧人数从个位数到数百人不等,包含稀疏与极度密集两种分布。
1.4 标注格式
标注文件为纯文本格式(.txt),每行记录一个被标注人的信息:
frame_index, x, y
-
frame_index:帧编号(从 1 开始) -
x、y:人头中心在图像中的像素坐标
训练时将坐标归一化至 [0, 1] 范围,与模型预测值统一量纲。
1.5 数据增强
训练阶段对原始帧执行以下随机变换:
-
随机裁剪:从 1920×1080 中随机采样 512×512 的 patch,仅保留中心落在 patch 内的标注点;
-
随机水平翻转:以 50% 概率对 patch 及其对应标注点进行镜像翻转;
-
标准化:使用 ImageNet 均值与标准差对 RGB 通道归一化。
二、模型架构
本项目采用 P2PNet(Point-to-Point Network) 作为检测骨干,该方法无需密度图估计,直接以点坐标回归的方式进行端到端人群计数与定位。
2.1 整体结构
输入图像 (3 × H × W) │ ▼ VGG-16 BN Backbone ├── Block-8 → f₈ (256ch, 1/8 分辨率) └── Block-16 → f₁₆ (512ch, 1/16 分辨率) │ ▼ FPN Decoder └── 上采样 f₁₆ + 融合 f₈ → 统一特征图 (256ch, 1/8 分辨率) │ ▼ 分类头 (cls_head) → 每个 Anchor 的前景概率 定位头 (loc_head) → 每个 Anchor 的坐标偏移 │ ▼ Hungarian Matcher(训练时) └── 匈牙利二分匹配:将预测点与 GT 点一一对应 │ ▼ 损失函数 ├── Classification Loss:加权交叉熵(正负样本权重 1:10) └── Localization Loss:L1 Loss(仅对正样本计算)
2.2 Anchor 设计
每个特征图格子生成 row × line = 2 × 2 = 4 个均匀分布的锚点,特征步长 stride = 8,最终锚点数量 = (H/8) × (W/8) × 4。
2.3 骨干网络
使用在 ImageNet 上预训练的 VGG-16 BN 权重进行初始化,训练时以较小学习率微调骨干,以较大学习率训练预测头,实现分层学习。
三、训练过程
训练遵循深度学习的标准流程,分为以下阶段:
3.1 数据构建与加载
-
解析
trainlist.txt,枚举所有带标注的序列; -
读取对应
.txt标注文件,按帧号建立{frame_id: [(x, y), ...]}字典; -
构建
(image_path, points)样本列表; -
训练时随机裁剪 512×512 patch 并应用数据增强。
3.2 前向传播与损失计算
-
骨干网络提取两级特征
(f₈, f₁₆); -
FPN 融合特征,生成统一特征图;
-
分类头输出各锚点的二分类 logits,定位头输出坐标偏移;
-
将偏移加到锚点坐标上,得到预测点集;
-
匈牙利匹配:求解预测点与 GT 点的最优二分匹配(代价矩阵 = 分类代价 + 定位代价);
-
对匹配的正样本计算 L1 定位损失,对全部样本计算加权分类损失,两者加权求和得到
loss_total。
3.3 优化与调度
-
优化器:AdamW,骨干与预测头分别设置学习率;
-
学习率调度:Cosine Annealing,从初始学习率余弦衰减至
1e-7; -
梯度裁剪:
clip_grad_norm_阈值设为0.1,防止梯度爆炸。
3.4 断点续训
每 10 个 Epoch 保存一次完整 checkpoint(包含 model、optimizer、scheduler 状态),支持通过配置 CFG['resume'] 恢复训练。
3.5 最优模型保存
每轮训练结束后,若当轮平均训练损失低于历史最低值,则立即将模型权重保存为 best.pth。训练结束后强制保存 final.pth(含完整训练状态)。
四、训练参数
| 参数 | 值 | 说明 |
|---|---|---|
patch_size |
512 | 训练图像裁剪尺寸(px) |
batch_size |
6 | 显存约占 10 GB(RTX 3060 12G) |
num_epochs |
200 | 总训练轮数 |
lr(预测头) |
1e-4 | 分类/定位头学习率 |
lr_backbone |
1e-5 | VGG-16 骨干微调学习率 |
weight_decay |
1e-4 | AdamW 权重衰减 |
clip_grad |
0.1 | 梯度裁剪阈值 |
num_workers |
4 | DataLoader 并行进程数 |
save_every |
10 | 每 10 个 Epoch 保存一次 checkpoint |
val_threshold |
0.5 | 推理时置信度阈值 |
row × line |
2 × 2 | 每格子锚点布局 |
stride |
8 | 特征图步长(下采样倍数) |
| 调度策略 | Cosine Annealing | T_max=200, eta_min=1e-7 |
五、训练指标
5.1 损失函数
| 损失项 | 含义 |
|---|---|
loss_cls |
分类损失(加权交叉熵),衡量模型对"是否有人"的判断准确性 |
loss_loc |
定位损失(L1 Loss),衡量预测坐标与真实人头位置的偏差 |
loss_total |
loss_cls + loss_loc,模型优化的总目标 |
5.2 实际训练结果
| 指标 | 值 |
|---|---|
| 训练轮数 | 200 Epoch |
| 初始损失(Epoch 1) | 1.7523 |
| 最优训练损失 | 0.3451(历史最低) |
| 最终轮损失(Epoch 200) | 0.3587 |
| 最终学习率(预测头) | ≈ 1.06×10⁻⁷ |
损失从初始的 1.75 稳定下降至 0.35 以下,说明模型在训练集上充分收敛,对人头定位与分类的能力显著提升。
六、可视化图说明
通过 train_p2pnet/plot_metrics.py 可将 checkpoints/metrics.json 中记录的每轮训练数据生成以下可视化图表:
6.1 训练损失曲线(loss.png)
-
横轴:Epoch 轮次(1~200)
-
纵轴:当轮平均训练损失(
loss_total) -
含义:整体呈单调下降趋势,初期下降迅速(模型快速学习主要特征),后期趋于平缓(模型在细节上持续优化)。曲线的平滑程度反映了训练的稳定性。
6.2 学习率曲线(lr_head.png)
-
横轴:Epoch 轮次
-
纵轴:预测头当前学习率
-
含义:呈余弦退火形态,从
1e-4平滑衰减至近零。学习率在前期较大以快速收敛,后期降低以精细调整权重、避免越过极小值点。
6.3 总览图(overview.png)
将损失曲线与学习率曲线并排展示在同一画布中,便于对照观察二者的对应关系——学习率下降的阶段,损失通常也随之更稳定地收敛。
6.4 系统内置可视化
桌面端系统内置多处可视化展示:
-
系统首页:展示最近检测人数趋势、检测类型占比、训练损失趋势;当训练指标缺失时自动展示数据集规模概览;
-
图片识别页:展示单张图片检测置信度分布直方图;
-
指标展示页:展示训练损失曲线、学习率曲线、阶段损失柱状图;
-
数据集统计页:展示训练集 / 测试集占比、各序列标注人数柱状图、单帧人数分布直方图。
七、系统功能
系统采用 PyQt6 构建桌面端 GUI,整体界面采用浅色政务风配色,包含以下功能模块:
7.1 登录 / 注册
-
支持账号密码注册与登录,密码经 SHA-256 哈希后持久化存储;
-
默认内置账号:
admin/123456。
7.2 系统首页
-
登录后默认进入系统首页;
-
展示模型状态、累计检测次数、累计识别人数、平均置信度、平均耗时、训练轮数、最低损失、数据集图片数量等核心卡片;
-
展示最近检测人数趋势图、图片 / 批量检测类型占比图、训练损失趋势图;
-
读取
ui/data/history.json、train_p2pnet/checkpoints/metrics.json和VisDrone2020-CC目录生成运行总览; -
展示模型与训练摘要、数据集摘要和最近检测记录表。
7.3 图片识别页
-
支持打开本地图片(JPG / PNG / BMP / TIFF / WebP);
-
在后台线程执行 P2PNet 推理,UI 不阻塞;
-
检测结果以红色实心圆点标注在每个人头中心位置(高置信度偏纯红,低置信度偏橙红);
-
右侧展示检测人数、平均置信度、最高置信度、推理耗时等统计信息;
-
坐标详情表格支持查看每个点的精确坐标与置信度;
-
置信度分布直方图可视化检测置信度分布情况;
-
支持导出标注结果图(PNG/JPG)和坐标 CSV 文件。
7.4 批量检测页
-
支持选择图片文件夹,自动扫描当前层级图片文件;
-
复用 P2PNet 检测器逐张识别,后台线程执行,避免界面卡顿;
-
实时展示检测进度、成功数量、失败数量、总人数、平均置信度、总耗时;
-
表格展示序号、文件名、图片尺寸、检测人数、平均置信度、最高置信度、耗时、状态;
-
单张损坏图片不会中断批量任务,失败原因会记录在结果中;
-
支持导出批量检测结果 CSV;
-
批量完成后自动写入一条汇总历史记录。
7.5 检测历史页
-
每次图片识别或批量检测完成后自动记录;
-
支持关键词搜索、图片 / 批量类型筛选;
-
支持导出历史记录为 CSV;
-
点击记录行可查看详细信息,批量记录会展示图片总数、成功数量、失败数量、总人数、平均置信度和总耗时。
7.6 模型管理页
-
启动时自动尝试加载
train_p2pnet/checkpoints/best.pth; -
支持手动浏览并切换任意
.pth文件; -
支持调节推理置信度阈值,实时生效;
-
展示模型架构信息(参数量、骨干、解码器、训练数据集等)。
7.7 指标展示页
-
包含“训练曲线”“指标汇总”“数据集统计”三个 Tab;
-
读取
train_p2pnet/checkpoints/metrics.json,自动绘制训练损失曲线与学习率曲线; -
统计卡片展示最低训练损失、最终轮损失、训练总轮数、最小学习率;
-
指标汇总展示各阶段损失分布;
-
数据集统计直接读取
VisDrone2020-CC/trainlist.txt、testlist.txt、sequences/、annotations/,统计序列、图片帧、标注点与单帧人数分布; -
数据集统计页展示训练 / 测试占比饼图、各序列标注人数柱状图、单帧人数分布直方图和序列表格;
-
支持手动重新加载数据。
八、技术栈
| 类别 | 技术 |
|---|---|
| 深度学习框架 | PyTorch |
| 模型骨干 | VGG-16 BN(torchvision 预训练权重) |
| 匹配算法 | scipy.optimize.linear_sum_assignment(匈牙利算法) |
| 数据处理 | Pillow、NumPy |
| GUI 框架 | PyQt6 |
| 图表绘制 | Matplotlib(QtAgg 后端) |
| 样式系统 | QSS(Qt Style Sheets) |
| 数据持久化 | JSON、CSV 导出 |
九、项目结构
c186/ ├── VisDrone2020-CC/ # 数据集根目录 │ ├── sequences/ # 图像帧(112 个序列,每序列 30 帧) │ │ └── 00001/ │ │ ├── 00001.jpg │ │ └── ... │ ├── annotations/ # 标注文件(82 个序列有标注) │ │ └── 00001.txt │ ├── trainlist.txt # 训练序列列表 │ ├── testlist.txt # 测试序列列表 │ └── 数据集说明文档.md │ ├── train_p2pnet/ # 模型训练模块 │ ├── datasets/ │ │ └── visdrone.py # 数据集加载、解析、增强 │ ├── models/ │ │ ├── backbone.py # VGG-16 BN 特征提取 │ │ ├── decoder.py # FPN 特征融合解码器 │ │ ├── matcher.py # 匈牙利匹配器 │ │ └── p2pnet.py # P2PNet 主网络(前向、损失计算、推理) │ ├── utils/ │ │ └── misc.py # collate_fn、AverageMeter、MAE/MSE 计算 │ ├── checkpoints/ # 模型权重与训练日志 │ │ ├── best.pth # 训练损失最优权重 │ │ ├── final.pth # 最终轮完整 checkpoint │ │ ├── epoch_010.pth~200 # 每 10 轮定期保存 │ │ └── metrics.json # 每轮损失与学习率记录 │ ├── metrics_charts/ # 可视化图输出目录 │ │ ├── loss.png │ │ ├── lr_head.png │ │ └── overview.png │ ├── train.py # 训练主入口 │ └── plot_metrics.py # 训练指标可视化脚本 │ ├── ui/ # 桌面应用系统 │ ├── core/ │ │ └── detector.py # P2PNet 推理封装(预处理、后处理、绘点) │ ├── pages/ │ │ ├── home_page.py # 系统首页(运行总览与可视化大屏) │ │ ├── image_page.py # 图片识别页 │ │ ├── batch_page.py # 批量检测页 │ │ ├── history_page.py # 检测历史页 │ │ ├── model_page.py # 模型管理页 │ │ └── metrics_page.py # 指标展示页 │ ├── utils/ │ │ └── styles.py # 全局 QSS 样式表 │ ├── data/ # 运行时数据(用户账号、历史记录) │ ├── login_window.py # 登录 / 注册窗口 │ ├── main_window.py # 主窗口(侧边栏 + 页面堆叠) │ └── main.py # 应用入口 │ ├── requirements.txt └── README.md
十、启动教程
10.1 环境准备
推荐配置:
-
Python 3.9
-
CUDA 11.x 或更高(GPU 推理)
-
NVIDIA RTX 3060 12G 或同等显存(训练时)
安装依赖:
pip install -r requirements.txt
10.2 数据集准备
将 VisDrone2020-CC 数据集按以下结构放置(项目内已包含):
VisDrone2020-CC/ ├── sequences/ ├── annotations/ ├── trainlist.txt └── testlist.txt
10.3 训练模型
cd train_p2pnet python train.py
训练过程中每 10 个 Epoch 自动保存 checkpoint,每轮同步更新 checkpoints/metrics.json。 训练结束后自动保存 best.pth(训练损失最低)与 final.pth(最终状态)。
断点续训:在 train.py 中将 CFG['resume'] 设置为目标 checkpoint 路径,再次运行即可从该轮恢复。
10.4 生成可视化图表
cd train_p2pnet python plot_metrics.py
图表将输出至 train_p2pnet/metrics_charts/ 目录。
10.5 启动系统
cd ui python main.py
登录后默认进入系统首页,系统会自动尝试加载 train_p2pnet/checkpoints/best.pth,无需手动配置即可进行图片检测或批量检测。
十一、作者信息
| 项目 | 内容 |
|---|---|
| 作者 | Jay |
| 联系方式 | 微信:Jay8059 |
| 开发年份 | 2026 |
| 所属领域 | 计算机视觉 · 人群计数 · 无人机目标检测 |











更多推荐



所有评论(0)