UAVCrack — 无人机路面裂缝分割权重
2026 VLP 挑战赛参赛作品 · 赛道 D(UAV-Crack)
代码仓库:Tom713134/UAVCrack-Crack-Segmentation
模型说明
ResNet-34 U-Net 做无人机航拍路面裂缝的二值语义分割。裂缝仅占全图 1–5% 像素,且呈细长结构(X4 变焦下宽度仅 2–3 px),因此方案在初始化、损失、集成、后处理四层做了针对性设计。
| 项 | 值 |
|---|---|
| 架构 | ResNet34-UNet(ImageNet 预训练编码器,解码器从零训练) |
| 参数量 | 24,429,281 |
| 输入 | (1, 3, 384, 672) float32 —— 需先归一化并 pad 到 384 行 |
| 输出 | (1, 1, 384, 672) logits —— 裁回 378 行后 sigmoid |
| 损失 | CAL(δ=0.5, γ=0.2, λ=0.5) + 0.5 × Dice |
| 集成 | 5 个随机种子(101/202/303/404/505)概率平均 |
| 后处理 | 连通域面积过滤(a≥50) → 置信度门控细化(λ=0.05, r=1) |
| 训练数据 | UAV-CrackX 1177 张(全量,清洗掉 23 张标签噪声) |
| 训练配置 | 30 epoch, batch 10, AdamW, lr 3e-4 余弦退火至 1e-6, AMP |
关键设计
- 输出层 bias 初始化为 −4:σ(−4) ≈ 0.018,直接对齐裂缝的先验占比,避免训练初期被背景主导。
- CAL 损失的 $p^\gamma$ 负类加权:γ=0.2 让梯度集中到难分的裂缝邻域像素,而非大片易分背景。
- 几何 ×5 确定性视角:
(1.0, 0°)、(0.85, −10°)、(1.15, +10°)、(1.0, 0°, 翻转)、(0.90, +5°, 翻转),统一覆盖 X4/X8/X16 三种表观宽度。 - 门控细化而非骨架重建:只在预测掩膜边界 1 px 带内把阈值从 0.20 提到 0.25,核心区不动。硬骨架重建会让 1 px 细缝直接消失(实测 X4 崩到 22.45)。
指标
内部 confirm 集(193 张,micro 聚合,有 GT):
| 方案 | Crack IoU | P | R |
|---|---|---|---|
| 单模型 | 64.5796 | 79.08 | 77.89 |
| 5-seed 集成 | 65.3719 | 76.65 | 81.63 |
| + 面积过滤 | 65.4060 | — | — |
| + 门控细化 | 65.5053 | 77.3 | 81.3 |
分变焦(5-seed 集成):
| 变焦 | Crack IoU | P | R | 说明 |
|---|---|---|---|---|
| X4 | 63.24 | 70.34 | 86.24 | 瓶颈,画粗 2 px |
| X8 | 66.23 | 78.00 | 81.44 | 平衡 |
| X16 | 66.04 | 80.38 | 78.73 | 略漏检 |
集成增益经 2000 次配对 Bootstrap 检验:**+0.7935**,95% CI [+0.538, +1.045],是全部实验里唯一统计显著的正向改进。
注意:以上均为内部留出集结果,非 VLP 官方盲测分。官方 val 与训练集存在 96.5% 的帧级重叠,官方分会偏高,不可直接对比。
文件
ckpt/seed{101,202,303,404,505}.pt PyTorch state_dict(纯权重字典)
onnx/seed{101,202,303,404,505}.onnx ONNX 单文件,opset 18,权重内嵌
SHA256SUMS 10 个文件的校验和
.pt 不是整模型对象,需配合代码仓库的 model.py 加载:
from model import ResNet34UNet
m = ResNet34UNet(3, False) # in_ch=3, use_attention=False
m.load_state_dict(torch.load("seed101.pt", map_location="cpu"))
m.eval()
ONNX 与 PyTorch 输出已逐一比对,最大绝对误差 ≤ 7.44e-05。
推理示例(ONNX)
import numpy as np, cv2, onnxruntime as ort
MEAN = np.array([0.485, 0.456, 0.406], np.float32)
STD = np.array([0.229, 0.224, 0.225], np.float32)
sess = ort.InferenceSession("seed101.onnx", providers=["CPUExecutionProvider"])
bgr = cv2.imread("img.jpg")
rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
h, w = rgb.shape[:2] # 378, 672
x = (rgb.astype(np.float32) / 255.0 - MEAN) / STD
x = np.transpose(x, (2, 0, 1))[None]
x = np.pad(x, ((0,0),(0,0),(0,384-h),(0,0)), mode="reflect")
logits = sess.run(None, {"input": x})[0][:, :, :h]
prob = 1.0 / (1.0 + np.exp(-logits))[0, 0]
5 个模型要各跑一遍再对概率取平均,单模型会低约 0.8 个点。
完整后处理(面积过滤 + 门控细化)见代码仓库 code/make_submission.py。
局限
- X4 变焦未解决:2–3 px 宽度下 P/R 失衡(70.3 / 86.2)。实测 11 个方法中 10 个让 X4 变差。
- 推理成本 ×5:若需实时,K=2 只损失约 0.5 点。
- 300 张无标注图未利用:半监督两次崩溃(IoU 掉到 0.07–0.18),标注它们是最大改进空间。
- 编码器用了 ImageNet 预训练:若规则禁止外部预训练需重训,预期降 2–3 点(未实测)。
数据集
UAV-CrackX 遵循 CC BY-NC-SA 3.0,仅限本次比赛非商业使用,禁止二次分发。本仓库只提供训练得到的权重,不包含任何原始影像或标注。
引用
@article{shan2024uav,
title = {UAV-Based Pavement Image Stitching without Occlusion, Crack Semantic Segmentation, and Quantification},
author = {Shan, et al.},
journal = {IEEE Transactions on Intelligent Transportation Systems},
volume = {25},
number = {11},
pages = {17038--17053},
year = {2024}
}
许可
MIT