无人机视角下小目标人群计数系统(全套源码+数据集)
本项目面向无人机俯拍场景下的密集人群计数与人体定位任务,采用 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-4 → f₄ (128ch, 1/4 分辨率)
├── Block-8 → f₈ (256ch, 1/8 分辨率)
└── Block-16 → f₁₆ (512ch, 1/16 分辨率)
│
▼
三尺度注意力 FPN Decoder
└── 下采样 f₄ + 融合 f₈ + 上采样 f₁₆ → 统一特征图 (256ch, 1/8 分辨率)
│
▼
分类头 (cls_head) → 每个 Anchor 的前景概率
定位头 (loc_head) → 每个 Anchor 的受约束坐标偏移
│
▼
Hungarian Matcher(训练时)
└── 匈牙利二分匹配:将预测点与 GT 点一一对应
│
▼
损失函数
├── Classification Loss:Focal Loss(缓解前景稀疏与类别不均衡)
└── Localization Loss:SmoothL1 Loss(仅对正样本计算)
2.2 Anchor 设计
每个特征图格子生成 row × line = 3 × 3 = 9 个均匀分布的密集锚点,特征步长 stride = 8,最终锚点数量 = (H/8) × (W/8) × 9。定位偏移使用 tanh(raw_offset) × cell_size × offset_scale 进行约束,减少无人机场景中小目标坐标漂移;推理阶段通过点级半径去重降低重复计数。
2.3 算法优化点
- 三尺度注意力特征融合:在原有
/8、/16特征基础上引入/4浅层细节特征,并加入轻量通道/空间注意力,提高小目标与遮挡人体的响应能力。 - 密集锚点与约束回归:锚点从
2×2提升到3×3,增强候选点覆盖密度;通过tanh约束偏移范围,降低异常点预测。 - Focal + SmoothL1 损失优化:分类分支使用 Focal Loss 处理前景稀疏问题,定位分支使用 SmoothL1 提升异常匹配下的训练稳定性。
2.4 骨干网络
使用在 ImageNet 上预训练的 VGG-16 BN 权重进行初始化,训练时以较小学习率微调骨干,以较大学习率训练预测头,实现分层学习。
三、训练过程
训练遵循深度学习的标准流程,分为以下阶段:
3.1 数据构建与加载
- 解析
trainlist.txt,枚举所有带标注的序列; - 读取对应
.txt标注文件,按帧号建立{frame_id: [(x, y), ...]}字典; - 构建
(image_path, points)样本列表; - 训练时随机裁剪 512×512 patch 并应用数据增强。
3.2 前向传播与损失计算
- 骨干网络提取三级特征
(f₄, f₈, f₁₆); - 三尺度注意力 FPN 融合特征,生成统一特征图;
- 分类头输出各锚点的二分类 logits,定位头输出受约束坐标偏移;
- 将约束偏移加到锚点坐标上,得到预测点集;
- 匈牙利匹配:求解预测点与 GT 点的最优二分匹配(代价矩阵 = 分类代价 + 定位代价);
- 对匹配的正样本计算 SmoothL1 定位损失,对全部样本计算 Focal 分类损失,两者加权求和得到
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 | 推理时置信度阈值 |
val_ratio |
0.15 | 从带标注训练序列中划分验证集 |
row × line |
3 × 3 | 每格子锚点布局 |
stride |
8 | 特征图步长(下采样倍数) |
offset_scale |
1.0 | 约束偏移缩放系数 |
nms_radius |
4 px | 推理点级去重半径 |
focal_alpha / gamma |
0.75 / 2.0 | Focal Loss 参数 |
smooth_l1_beta |
0.01 | SmoothL1 定位损失参数 |
| 调度策略 | Cosine Annealing | T_max=200, eta_min=1e-7 |
五、训练指标
5.1 损失函数
| 损失项 | 含义 |
|---|---|
loss_cls |
分类损失(Focal Loss),衡量模型对"是否有人"的判断准确性 |
loss_loc |
定位损失(SmoothL1 Loss),衡量预测坐标与真实人头位置的偏差 |
loss_total |
加权后的总损失,模型优化的总目标 |
val_mae |
验证集平均绝对计数误差 |
val_mse |
验证集均方根计数误差 |
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_optimized/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_optimized/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_optimized/best.pth; - 支持手动浏览并切换任意
.pth文件; - 支持调节推理置信度阈值,实时生效;
- 展示模型架构信息(参数量、骨干、解码器、训练数据集等)。

7.7 指标展示页
- 包含“训练曲线”“指标汇总”“数据集统计”三个 Tab;
- 读取
train_p2pnet/checkpoints_optimized/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/ # 旧版模型权重与训练日志
│ ├── checkpoints_optimized/ # 优化版模型权重与训练日志
│ │ ├── best.pth # 训练损失最优权重
│ │ ├── final.pth # 最终轮完整 checkpoint
│ │ ├── epoch_010.pth~200 # 每 10 轮定期保存
│ │ └── metrics.json # 每轮损失、验证指标与学习率记录
│ ├── metrics_charts/ # 旧版可视化图输出目录
│ ├── metrics_charts_optimized/ # 优化版可视化图输出目录
│ │ ├── 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_optimized/metrics.json。
训练结束后自动保存 best.pth(训练损失最低)与 final.pth(最终状态)。
断点续训:在 train.py 中将 CFG['resume'] 设置为目标 checkpoint 路径,再次运行即可从该轮恢复。
10.4 生成可视化图表
cd train_p2pnet
python plot_metrics.py
图表将输出至 train_p2pnet/metrics_charts_optimized/ 目录。
10.5 启动系统
cd ui
python main.py
登录后默认进入系统首页,系统会自动尝试加载 train_p2pnet/checkpoints_optimized/best.pth,无需手动配置即可进行图片检测或批量检测。
本项目为个人原创,结构清晰,功能完整,适合计算机视觉方向课程设计、毕业设计和项目演示使用。有定制化需求可以评论或私信作者。
作者原创项目地址:michael-jay.pages.dev/projects.html
浙公网安备 33010602011771号