无人机图传延迟是影响飞行安全和操控体验的核心指标。业界常用 LED + 光电传感器法测量物理链路延迟,但这套方法无法用于仿真环境,仿真和外场需要两套完全不同的测量工具,数据也无法直接对比。

本文提出并实验验证了一种基于视觉时间戳标记的端到端延迟测量方法:在画面中放一个持续刷新时间戳的 QR 码,接收端解码即可算出延迟。这套方法仿真和外场使用完全相同的代码,实验证明测量精度 < 3ms,标准差 < 0.3ms。全部代码开源。


一、问题:为什么需要一个通用的延迟测量方法

1.1 无人机图传延迟的完整链路

1
2
光线 → 机载相机(采集) → 编码器(H.264/H.265) → 图传发射 → 无线传输 → 接收 → 解码 → 地面显示
T_cap T_enc T_tx T_rf T_rx T_dec T_disp

各环节典型耗时:

环节 描述 典型延迟
相机采集 CMOS 曝光 + 读出 5-15 ms
编码 H.264/H.265 压缩 16-50 ms
无线传输 RF 调制/传输/接收 1-5 ms
编解码缓冲 各缓冲 1-3 帧 20-100 ms
解码 地面站解压 15-40 ms
显示渲染 屏幕刷新 8-20 ms
合计 65-230 ms

1.2 现有方法的局限

方法 仿真可用 外场可用 代码复用 精度
LED + 光电传感器 0.5 ms
示波器法 亚毫秒
双屏秒表法 ±30 ms
KLV 时间戳法 部分 ~1 ms
视觉标记法(本文) < 3 ms

二、方法设计:视觉时间戳标记法

2.1 核心思路

把时间信息编码进视觉内容本身:在画面中放一个 QR 码,其内容是当前精确时间戳(微秒)。无论这个图像经过多少次编码、传输、解码,只要最终画面里的 QR 码还能被识别,就能准确测出端到端延迟。

2.2 为什么选 QR 码而非简单闪烁

方案 单帧可测 不依赖边沿检测 编解码鲁棒 精度
亮/灭闪烁 取决于帧率
颜色编码 差(压缩伪影)
ArUco 码 否(仅位姿)
QR 码时间戳 微秒级

QR 码的关键优势:

  • 纠错能力:即使被 H.264 压缩伪影干扰,仍可正确解码
  • 信息密度:一帧即可携带完整时间戳
  • 标准化pyzbar 库毫秒级解码,无需自定义协议
  • 无需时序:不依赖前后帧对比,单帧独立测量

2.3 仿真与外场的统一

环节 仿真实现 外场实现 代码
标记生成 Gazebo 场景中的动态纹理 手机/平板屏幕 同一个 MarkerGenerator
图传链路 RTSP 推拉流 真实无线图传 不涉及
延迟检测 从 RTSP 拉帧 从图传拉帧 同一个 LatencyDetector
统计报告 matplotlib 图表 matplotlib 图表 同一个 report.py

三、实现

3.1 核心代码架构

1
2
3
4
5
6
7
8
9
10
video-latency-tester/
├── src/
│ ├── marker_generator.py # QR 时间戳标记生成器
│ ├── latency_detector.py # 延迟检测器(从视频帧解码 QR)
│ └── report.py # 统计报告 + 图表生成
├── experiments/
│ ├── exp1_loopback.py # 实验1:直接环回(方法基线)
│ ├── exp2_ffmpeg_rtsp.py # 实验2:RTSP 推拉流
│ └── exp3_simulated_delay.py # 实验3:注入已知延迟验证
└── results/ # 实验结果

3.2 标记生成器

1
2
3
4
5
6
7
8
9
10
class MarkerGenerator:
def generate(self) -> tuple[np.ndarray, int]:
"""生成带时间戳的 QR 码图像"""
ts_us = time.clock_gettime_ns(time.CLOCK_REALTIME) // 1000
qr = qrcode.QRCode(version=2, error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=6, border=2)
qr.add_data(str(ts_us))
qr.make(fit=True)
img = np.array(qr.make_image().convert("L"), dtype=np.uint8)
return cv2.resize(img, (self.size, self.size), interpolation=cv2.INTER_NEAREST), ts_us

3.3 延迟检测器

1
2
3
4
5
6
7
8
class LatencyDetector:
def measure(self, frame: np.ndarray) -> float | None:
"""从帧中解码 QR 码,计算延迟"""
t_recv_us = time.clock_gettime_ns(time.CLOCK_REALTIME) // 1000
decoded = zbar_decode(gray_frame)
t_send_us = int(decoded[0].data.decode("utf-8"))
latency_ms = (t_recv_us - t_send_us) / 1000.0
return latency_ms

3.4 时钟同步要求

场景 方案 精度
仿真(同一台机器) 天然同步 完美
外场(同一局域网) NTP ±5 ms
外场(高精度) PTP (IEEE 1588) 或 GPS PPS ±1 μs

四、实验验证

4.1 实验 1:直接环回(方法基线)

目的:测量 QR 编码 + 解码本身的开销,确认方法不引入显著偏差。

链路MarkerGenerator.generate()LatencyDetector.measure() (同一进程,无任何传输)

结果(500 次采样):

指标
平均延迟 2.21 ms
中位数 2.00 ms
P95 2.09 ms
P99 2.37 ms
标准差 4.06 ms(受极少数 GC 毛刺影响)

结论:方法本身的固有开销约 2ms,作为已知系统误差,可在最终结果中扣除。

实验 1 延迟分布

4.2 实验 3:已知延迟注入验证(最关键实验)

目的:注入精确已知的延迟(0, 20, 50, 100, 200, 500 ms),验证检测器能否正确测量。

做法generate()time.sleep(target_delay)measure()

结果(每组 200 次采样):

注入延迟 实测均值 误差 标准差
0 ms 2.06 ms +2.06 ms 0.11 ms
20 ms 22.12 ms +2.12 ms 0.22 ms
50 ms 52.19 ms +2.19 ms 0.06 ms
100 ms 102.38 ms +2.38 ms 0.12 ms
200 ms 202.58 ms +2.58 ms 0.16 ms
500 ms 502.91 ms +2.91 ms 0.20 ms

实验 3 精度验证

关键发现

  1. 线性度极好:实测值与注入值几乎完美线性关系(R21.0R^2 \approx 1.0
  2. 系统偏差恒定:所有组的误差都是 +2~3ms,恰好等于 QR 编解码开销(与实验 1 吻合)
  3. 精度极高:标准差 < 0.3ms,远优于双屏秒表法的 ±30ms
  4. 跨量程一致:从 20ms 到 500ms 误差特征一致,证明方法在图传延迟的典型范围内完全可靠

4.3 实验 2:RTSP 推拉流端到端延迟

目的:测量经过真实 H.264 编解码和 RTSP 传输的端到端延迟。

链路

1
2
3
MarkerGenerator → ffmpeg (H.264 ultrafast, zerolatency)
→ mediamtx (RTSP server) → ffmpeg (RTSP pull, decode)
→ LatencyDetector

配置:640×480@30fps,H.264 ultrafast + zerolatency,本地回环

结果(300 次采样):

指标
平均延迟 40.77 ms
中位数 40.60 ms
最小值 40.41 ms
最大值 43.73 ms
P95 42.61 ms
标准差 0.53 ms

实验 2 RTSP 延迟分布

实验 2 延迟时序

分析

扣除方法固有开销 (~2ms) 后,纯 H.264 编解码 + RTSP 传输的延迟约为 38ms

延迟构成估算:

环节 估算延迟
QR 编码 + 图像生成 ~1 ms
H.264 编码(ultrafast + zerolatency) ~16 ms (1帧@60fps)
RTSP 打包 + 本地传输 ~1 ms
H.264 解码 ~16 ms
QR 解码 ~2 ms
其他(调度、缓冲) ~5 ms
合计 ~41 ms

与实测 40.77ms 高度吻合。


五、在无人机仿真/外场中的部署方式

5.1 仿真中使用(Gazebo + RTSP)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 在 Gazebo 场景中放一个平面,贴上 QR 码纹理
# 2. 通过 Python 脚本持续更新纹理
gen = MarkerGenerator(size=240)
while True:
img, ts = gen.generate()
cv2.imwrite("/tmp/latency_marker.png", img) # Gazebo 动态纹理引用此文件
time.sleep(0.01)

# 3. 从仿真相机输出的 RTSP 流中拉帧检测
detector = LatencyDetector()
cap = cv2.VideoCapture("rtsp://localhost:8554/sim_camera")
while cap.isOpened():
ret, frame = cap.read()
if ret:
latency = detector.measure(frame)

5.2 外场使用

1
2
3
4
5
# 1. 在平板/手机上运行标记显示器,放在相机视野内
python3 src/marker_generator.py # 显示动态 QR 码窗口

# 2. 地面站从图传拉流并检测
python3 src/latency_detector.py "rtsp://192.168.1.100:8554/drone"

5.3 批量对比测试

1
2
3
4
5
6
7
8
9
# 对比不同编码参数的延迟
configs = {
"ultrafast": "rtsp://localhost:8554/ultrafast",
"medium": "rtsp://localhost:8554/medium",
"h265": "rtsp://localhost:8554/h265",
}
for name, url in configs.items():
det = run_from_source(url, max_samples=300)
generate_report(det, f"compare_{name}")

六、方法的适用范围与局限

6.1 适用范围

场景 适用性 说明
无人机图传测试 完全适用 典型延迟 50-300ms 在方法最佳工作范围内
RTSP/RTMP 推拉流 完全适用 H.264/H.265 压缩后 QR 码仍可解码
仿真内部链路 完全适用 无需物理传感器
仿真 vs 外场对标 完全适用 同一套代码,数据直接可比
多通道同步测试 适用 每路独立测量,比对即可

6.2 局限

局限 影响 缓解措施
精度受帧率限制 30fps 时量化步长 ~33ms 用高帧率相机或插值
需要时钟同步 跨设备时钟不同步导致误差 NTP/PTP/GPS
QR 码需可见 被遮挡或过小则解码失败 ROI 定位 + 合适尺寸
方法开销 ~2ms 系统偏差 已标定,可扣除
高压缩比下可能解码失败 极低码率时 QR 码模糊 增大 QR 码尺寸 + 提高纠错级别

6.3 vs LED + 光电传感器法

维度 LED 法 视觉标记法(本文)
精度 0.5 ms ~2 ms
仿真可用
外场可用
代码复用
需要额外硬件 Arduino + LED + 光电管 无(纯软件)
自动化统计 需自己写 内置
适用延迟范围 1-1000 ms 10-10000 ms

总结:如果只在外场测试且追求亚毫秒精度,LED 法更好;如果需要仿真和外场通用、代码复用、纯软件方案,视觉标记法是更优选择。


七、代码获取

完整代码开源在 GitHub:

1
2
3
4
5
6
7
8
9
10
git clone https://github.com/goodisok/video-latency-tester.git
cd video-latency-tester
pip install -r requirements.txt

# 运行精度验证实验
cd experiments
python3 exp3_simulated_delay.py

# 运行 RTSP 延迟测试
python3 exp2_ffmpeg_rtsp.py

参考文献

  1. Bachhuber, C. et al., “A System for High Precision Glass-to-Glass Delay Measurements in Video Communication”, ICIP 2015, arXiv:1510.01134
  2. IETF RFC 9317, “Operational Considerations for Streaming Media”
  3. SVTA 1058, “An Exploration into Measuring Streaming Latency”
  4. ITU-T P.931, “Multimedia Communications Delay, Synchronization and Frame Rate Measurement”
  5. fpv.blue, “Glass to Glass Video Latency Measurement”, 2016
  6. Oscar Liang, “FPV Camera Latency Testing”, oscarliang.com