LeRobot 图片集转视频数据集
更新时间:2026-09-14
简介
把用 PNG 帧存图像观测的 LeRobot v3.0 数据集重新编码成分块 MP4 的视频数据集,产出一份新数据集,源不动。包 lerobot datasets/dataset_tools.py:1530 convert_image_to_video_dataset,编码走 lerobot datasets/video_utils.py encode_video_frames(PyAV / FFmpeg)。默认 libsvtav1 + crf 30,相比 PNG 帧有量级上的存储节省。
功能描述
- 只处理图像数据集:源数据集已经含任何 video key 时直接失败;被转换的特征是名字以
observation.image开头的那些(observation.images.*也命中),一个都没有则失败 - 特征表里图像特征的
dtype从image改成video,info由编出来的首个 mp4 探测填入(lerobotget_video_info);data/**/*.parquet里的图像列被去掉,图像不再进 parquet - episode 按估算体积成批:先用一小段样本试编估算每帧字节,再按数据集的
video_files_size_in_mb上限把多个 episode 顺序编进同一个 mp4,逐 episode 记videos/<key>/from_timestamp/to_timestamp - 编码前把帧逐个落成临时 PNG 到
<output_path>/temp_images(num_workers个线程写盘),每批编完即删,finally里清掉整个临时目录 - 编码参数
vcodec/pix_fmt/g/crf/fast_decode原样转给 lerobotencode_video_frames episode_indices可只转指定 episode;meta/tasks.parquet原样拷贝- crash-safe:开跑前把已存在的输出目录整体删掉重建,中途失败再清一次半成品
- 完成后校验输出是合法 v3.0(
meta/info.json+codebase_version) - skip-if-done:输出已是 v3.0 且
force=False时不动手,返回SKIPPED
算子参数
输入
| 输入 | 含义 |
|---|---|
| dataset_path | 源 v3.0 图像数据集根目录(只读,不能含 video 特征) |
| output_path | 输出视频数据集根目录 |
输出
| 输出 | 含义 |
|---|---|
| result | SUCCESS / SKIPPED: output already exists / Failed: dataset_path and output_path are required / Failed: [<dataset_path>] <异常类型>: <信息> |
参数
| 参数名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| vcodec | str | "libsvtav1" | 编码器,取值受 lerobot resolve_vcodec 限制(见注意事项) |
| pix_fmt | str | "yuv420p" | 像素格式 |
| g | int | 2 | GOP 大小(关键帧间隔) |
| crf | int | 30 | 码率控制参数,越大画质越低体积越小 |
| fast_decode | int | 0 | 解码优化档位,>0 时 libsvtav1 加 svtav1-params=fast-decode=N,其他编码器加 tune=fastdecode |
| episode_indices | list[int] 或 None | None | 只转这些 episode。None 表示全部 |
| num_workers | int | 4 | 落临时 PNG 的线程数,取 max(1, num_workers) |
| force | bool | False | True 表示输出已是 v3.0 也重新转换 |
注意事项
vcodec合法取值由 lerobotresolve_vcodec限定:h264/hevc/libsvtav1/auto,以及硬件编码器h264_nvenc/hevc_nvenc/h264_vaapi/h264_qsv/h264_videotoolbox/hevc_videotoolbox。libx264不在这个集合里,会直接抛ValueError;没有 SVT-AV1 的机器请用h264。auto会去探测硬件编码器(有 NVIDIA 卡时会选 nvenc)。- 输出的
meta/stats.json是把源 stats 里的图像特征剔除后写入的,转换完视频特征没有统计。需要的话再跑一次「LeRobot 数据集统计量计算」补上。 - 一个 mp4 里顺序放了多个 episode,单独解某个 episode 必须按它的
videos/<key>/from_timestamp偏移,从 0 秒读会拿到别的 episode 的帧。 - 只转部分
episode_indices时输出保留原episode_index(不重索引),total_episodes只等于所选数量,索引可能不连续——这一点与 Episode 删除 / 数据集划分的重索引行为不同。 - 临时 PNG 落在输出目录下的
temp_images,转换过程中需要额外临时磁盘空间(按一批 episode 的原始帧算)。 crf在不同编码器上映射到不同参数(软编码crf、nvencqp、videotoolboxq:v);libsvtav1的preset被 lerobot 固定成 12,本算子未暴露。pix_fmt=yuv444p与libsvtav1/hevc不兼容,会被上游自动改回yuv420p。- 输出数据集的逻辑数据集名由 lerobot 固定成
<源目录名>_video,本算子未暴露repo_id。 output_path目录会被整体删除重建,不要指向源数据集或还有其他内容的目录。
调用示例
Python
1from __future__ import annotations
2
3import os
4
5import daft
6from daft import col
7
8from daft.aihc.common.udf import aihc_udf
9from daft.aihc.functions.embodied.lerobot.convert_images_to_video_udf import (
10 ConvertImagesToVideoDataset,
11)
12
13if __name__ == "__main__":
14 if os.getenv("DAFT_RUNNER", "native") == "ray":
15 import ray
16 ray.init(dashboard_host="0.0.0.0", ignore_reinit_error=True)
17 daft.set_runner_ray()
18 daft.set_execution_config(actor_udf_ready_timeout=6000, min_cpu_per_task=0)
19
20# 夹具可用 test/_helpers/lerobot_edit_fixture.py:build_image_dataset 生成
21 samples = {
22 "dataset_path": ["/path/to/lerobot_image_dataset"],
23 "output_path": ["/tmp/lerobot_video_out"],
24 }
25 ds = daft.from_pydict(samples)
26 ds = ds.with_column(
27 "result",
28 aihc_udf(
29 ConvertImagesToVideoDataset,
30 construct_args={
31 "vcodec": "libsvtav1",
32 "pix_fmt": "yuv420p",
33 "g": 2,
34 "crf": 30,
35 "fast_decode": 0,
36 "episode_indices": None,
37 "num_workers": 4,
38 "force": False,
39 },
40 num_cpus=2,
41 concurrency=1,
42 batch_size=1,
43 )(col("dataset_path"), col("output_path")),
44 )
45 ds.show()
评价此篇文章
