最近在审计一批 LeRobot 格式的机器人数据集时,遇到了视频冻结问题。本文分享 RDA 的视频冻结检测方案、实现思路和实测结果。

背景:为什么需要检测视频冻结

机器人学习数据集通常包含多路摄像头的视频流。如果视频在某段时间内帧画面完全相同(冻结),说明采集设备可能出了问题。用冻结帧训练出来的策略模型,学到的可能是"什么都不做"。

常见的检测方式是对比 episode 的首帧和末帧。但这种方式有两个问题:

  • 机器人任务起止位置相同是正常现象,容易误报
  • 视频中间段的冻结完全检测不到

RDA 的检测方案

RDA(Robot Data Audit)的 video_freeze 检测分四步:

1. 低分辨率灰度化

python

# 用 PyAV 解码视频为 64×64 灰度帧序列

import av

import numpy as np



def decode_grayscale(video_path, size=64):

container = av.open(video_path)

frames = []

for frame in container.decode(video=0):

img = frame.to_ndarray(format='gray')

img = cv2.resize(img, (size, size))

frames.append(img.astype(np.float32))

return np.stack(frames)

为什么用 64×64 灰度?因为冻结检测不需要高分辨率,降噪比保真更重要。

2. 自适应阈值

python

# 逐帧差分,取 p10 作为噪声底

diffs = np.array([

np.abs(frames[i+1] - frames[i]).mean()

for i in range(len(frames) - 1)

])

noise_floor = np.percentile(diffs, 10)

threshold = max(0.10, 0.25 * noise_floor)



# 低于阈值的帧视为"疑似冻结"

frozen_mask = diffs < threshold

关键点:阈值不是固定的,而是根据每个视频自身的噪声水平自适应。不同数据集的摄像头质量差异很大,固定阈值要么太松要么太严。

3. 连续段检测

python

# 找连续冻结段,过滤单帧噪声

min_duration = int(min_freeze_duration_sec * fps) # 默认 0.5 秒

freeze_segments = []

start = None

for i, is_frozen in enumerate(frozen_mask):

if is_frozen and start is None:

start = i

elif not is_frozen and start is not None:

if i - start >= min_duration:

freeze_segments.append((start, i))

start = None

单帧差分低于阈值太常见了(传感器噪声),只有连续多帧才说明真的冻结了。

4. 动作交叉验证(核心)

python

# 判断冻结段内机械臂是否在运动

def is_true_freeze(freeze_start, freeze_end, actions, threshold_pct=0.05):

action_diffs = np.abs(np.diff(actions[freeze_start:freeze_end], axis=0))

motion_ratio = np.mean(action_diffs > threshold_pct * np.percentile(np.abs(np.diff(actions)), 90))

# 如果动作显示机械臂在动,但视频帧不动 → 真冻结

# 如果动作也接近零 → 正常静止,不是冻结

return motion_ratio < 0.5 # 运动中冻结比例低于阈值才算冻结

这一步是 RDA 与其他方案最大的区别。 冻结本身不是问题——机器人在等待时本来就不动。问题是"该动却不动"。通过 action 数据判断机械臂的运动状态,RDA 能有效区分:

表格

情况视频帧动作数据判定
正常静止相同接近零✅ PASS
真实冻结相同有变化❌ FREEZE
低质量帧模糊/噪声任意✅ PASS(非冻结)

实测结果

LIBERO 基准数据集

对 LIBERO 的 10 个任务(379 个 episode)做了完整审计:

表格

指标结果
总 episode 数379
视频冻结检出6 个(1.6%)
Action 突变点3622 个(100% episode 受影响)
有效运动占比中位数 28.3%(71.7% 空闲)
状态空间占用率中位数 6.6%

6 个冻结 episode 集中在边界区域,持续时间短。同时发现 action discontinuity 更为普遍——这可能比视频冻结更影响训练效果。

宇树 G1_WBT 数据集

对 G1_WBT_Brainco_Pickup_Pillow(300 episodes,4 路摄像头)做了完整视频审计:

表格

指标结果
有视频可检 episode44/300
视频冻结检出0 个
帧完整性44/44 通过
多摄像头时间同步offset=0ms,drift=0ms/min

44 个 episode 全部通过视频冻结检测。其中 episode 18 的腕部摄像头质量评分为 0.5(画面模糊),但 RDA 正确识别为"质量下降"而非"冻结"。

小结

  1. 视频冻结检测必须结合动作数据——纯像素比较会产生大量误报
  2. 自适应阈值比固定阈值更鲁棒——不同数据集的摄像头质量差异大
  3. 冻结只是数据质量的一个维度——action discontinuity、idle ratio、state space occupancy 等结构性问题可能更值得关注

RDA 是开源工具,欢迎试用和反馈:github.com/liesliy/rda

安装:pip install robot-data-audit

审计命令:rda audit <dataset_path> --video-quality

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐