LeRobot documentation

Paramètres d'encodage vidéo

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.6.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Paramètres d'encodage vidéo

Lorsque le stockage vidéo est activé, LeRobot enregistre chaque flux caméra sous forme de fichier MP4 au lieu de sauvegarder un fichier image par pas de temps. L’encodage vidéo compresse les données dans le temps, ce qui réduit généralement la taille du jeu de données et les opérations d’entrée/sortie par rapport à une accumulation de PNG, tout en conservant le format MP4, compris par tous les lecteurs et chargeurs.

L’encodage des images en MP4 constitue un pipeline FFmpeg complet : choix de l’encodeur, format de pixels, GOP/images clés, compromis qualité/vitesse et drapeaux d’encodeur supplémentaires optionnels. La plupart de ces paramètres sont ajustables par l’utilisateur via rgb_encoder, une configuration imbriquée RGBEncoderConfig (lerobot.configs.video.RGBEncoderConfig) transmise via PyAV.

Vous pouvez définir ces paramètres depuis l’interface en ligne de commande avec --dataset.rgb_encoder.<field> (par exemple avec lerobot-record ou lerobot-rollout). Le même bloc s’applique à chaque flux vidéo de caméra de cette exécution.

Le stockage vidéo doit être activé pour que rgb_encoder ait un effet — use_videos=True dans les API Python, ou --dataset.video=true sur la ligne de commande (le comportement par défaut de l’enregistrement). Si la vidéo est désactivée, les entrées restent des images et rgb_encoder est ignoré.

Pour plus de détails sur le moment où les images sont écrites par rapport à l’encodage (en streaming ou après l’épisode), les files d’attente et les autres options de haut niveau --dataset.*, consultez Streaming Video Encoding. Pour une comparaison des paramètres d’encodage et des expériences, consultez l’Space video-benchmark.


Exemple

lerobot-record \
    --robot.type=so100_follower \
    --robot.port=/dev/tty.usbmodem58760431541 \
    --robot.cameras="{laptop: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \
    --robot.id=black \
    --teleop.type=so100_leader \
    --teleop.port=/dev/tty.usbmodem58760431551 \
    --teleop.id=blue \
    --dataset.repo_id=<my_username>/<my_dataset_name> \
    --dataset.num_episodes=2 \
    --dataset.single_task="Grab the cube" \
    --dataset.streaming_encoding=true \
    --dataset.encoder_threads=2 \
    --dataset.rgb_encoder.vcodec=h264 \
    --dataset.rgb_encoder.preset=fast \
    --dataset.rgb_encoder.extra_options='{"tune": "film", "profile:v": "high", "bf": 2}' \
    --display_data=true

Paramètres d’ajustement

Les valeurs par défaut sont calibrées pour équilibrer le taux de compression, la qualité visuelle et la vitesse de décodage/accélération pour les jeux de données robotiques typiques. Les modifier peut affecter à la fois l'enregistrement (charge CPU, pertes de frames) et l'entraînement (débit de décodage, qualité des images).

N’activez ces paramètres que si vous en avez une raison spécifique, et mesurez l’impact sur votre pipeline avant de vous fier aux nouveaux réglages.

Tous les drapeaux ci-dessous sont préfixés par --dataset.rgb_encoder. sur la ligne de commande.

ParamètreTypePar défautDescription
vcodecstr"libsvtav1"Nom du codec vidéo. "auto" sélectionne le premier encodeur matériel disponible à partir d'une liste de préférences fixe, en utilisant libsvtav1 en cas d'échec.
pix_fmtstr"yuv420p"Format de pixels en sortie. Doit être pris en charge par le codec choisi dans votre build FFmpeg.
gint2Taille du GOP — une image clé toutes les g images. Émise en tant qu'option FFmpeg g.
crfint ou float30Valeur de qualité abstraite, mappée par codec (voir le mappage). Plus la valeur est basse, plus la qualité est élevée et la sortie volumineuse, lorsque le mappage est monotone.
presetint ou str12 *Préréglage de vitesse de l'encodeur ; la signification dépend du codec.
* En l'absence de valeur et avec vcodec=libsvtav1, LeRobot utilise par défaut 12.
fast_decodeint0libsvtav1 : 0–2, transmis via svtav1-params.
h264 / hevc (logiciel) : si >0, définit tune=fastdecode.
Autres codecs : généralement inutilisé.
video_backendstr"pyav"Seul "pyav" est actuellement implémenté pour le codage vidéo.
extra_optionsdict{}Options spécifiques à FFmpeg ou au codec fusionnées après les champs structurés ci-dessus. Ne peut pas écraser les clés déjà définies par ces champs.

Flux de profondeur

Les cartes de profondeur (Intel RealSense, Reachy 2) sont stockées en tant que flux vidéo distincts aux côtés des flux RGB. La profondeur brute (uint16 en millimètres ou float32 en mètres) ne peut pas survivre à un codec 8 bits, LeRobot quantifie donc chaque carte en un code 12 bits ([0, 4095]) — logarithmiquement par défaut, pour correspondre au profil d'erreur 1/depth des capteurs de profondeur — puis l'empaque dans un format de pixel de profondeur de bits élevée (gray12le) et l'encode avec un codec 12 bits.

Profondeur brute uint16 mm
float32 m
→
Temps d’enregistrement Clip sur [depth_min,
depth_max]
→ Quantiser codes 12 bits 0–4095
log (par défaut) ou linéaire
→ Empaquetage en plan
gray12le
→ Encodage HEVC
Main 12
→ MP4 flux
stocké
→
Temps de chargement Déquantiser en mm / m

Configurez le pipeline de profondeur via un bloc depth_encoder parallèle (DepthEncoderConfig). Il partage tous les champs de RGBEncoderConfig (vcodec, pix_fmt, crf, …) et ajoute quatre réglages de quantificateur, définis via --dataset.depth_encoder.<field> :

lerobot-record \
    ... \
    --dataset.depth_encoder.vcodec=hevc \
    --dataset.depth_encoder.depth_min=0.05 \
    --dataset.depth_encoder.depth_max=5.0 \
    --dataset.depth_encoder.use_log=true
ParamètreTypePar défautDescription
vcodecstr"hevc"HEVC Main 12 (un codec compatible 12 bits, compatible MP4).
extra_optionsdict{"x265-params": "lossless=1"}La profondeur est sans perte par défaut (aller-retour exact) ; crf est ignoré. Passez extra_options={} et définissez crf pour un flux avec perte plus petit.
pix_fmtstr"gray12le"Format de pixel 12 bits mono-canal utilisé pour transporter les codes quantifiés.
depth_minfloat0.01Profondeur en mètres mappée sur le quantique 0. Les valeurs inférieures sont rognées lors du décodage.
depth_maxfloat10.0Profondeur en mètres mappée sur 4095 quantique. Les valeurs supérieures sont tronquées lors du décodage.
shiftfloat3.5Décalage pré-logarithmique (mètres) utilisé dans la quantification logarithmique pour la stabilité numérique près de zéro. Doit satisfaire depth_min + shift > 0.
use_logboolTrueSi true, quantifie dans l'espace logarithmique (recommandé pour les capteurs de profondeur typiques). Définissez sur false pour une quantification uniforme/linéaire.

depth_min, depth_max et shift sont toujours interprétés en mètres, quelle que soit l’unité de la profondeur en entrée. Les entrées sont détectées automatiquement : les tableaux d’entiers (par ex. uint16 en millimètres, directement issus d’un RealSense) sont traités comme des millimètres, et les tableaux flottants comme des mètres. Choisissez depth_min / depth_max pour encadrer la plage de travail réelle de votre capteur — les valeurs en dehors de cette plage saturent, ce qui peut écraser le détail aux limites.

Les fonctionnalités de profondeur sont signalées par "is_depth_map": true dans meta/info.json, et leurs paramètres de quantificateur (video.depth_min, video.depth_max, video.shift, video.use_log) sont persistés — ce qui permet de déquantifier la profondeur en unités physiques au chargement.

Unité de sortie au moment du chargement

depth_encoder est une préoccupation de temps d’enregistrement. L’unité vers laquelle les cartes de profondeur sont déquantifiées au chargement (par exemple pendant l’entraînement) est définie séparément par le drapeau de temps de lecture --dataset.depth_output_unit :

lerobot-train \
    --dataset.repo_id=<my_username>/<my_dataset_name> \
    --dataset.depth_output_unit=m \
    --policy.type=act
ParamètreTypePar défautDescription
depth_output_unitstr"mm"Les cartes de profondeur d’unités physiques sont déquantifiées au chargement en : "mm" (millimètres) ou "m" (mètres).

Il s’agit purement d’un choix de présentation au moment du décodage — cela ne modifie pas la vidéo stockée ni ses métadonnées, de sorte que le même jeu de données peut être lu en mm ou en m sans réencodage. Cela n’a aucun effet sur les jeux de données sans caméras de profondeur.


Persistance dans les métadonnées du jeu de données

Après l’encodage du premier épisode d’un flux vidéo, la configuration de l’encodeur est persistée dans les métadonnées du jeu de données (meta/info.json) sous chaque fonction vidéo, aux côtés des valeurs extraites du fichier lui-même. Pour une fonction vidéo observation.images.<camera>, la structure dans info.json est la suivante :

{
  "features": {
    "observation.images.laptop": {
      "dtype": "video",
      "shape": [480, 640, 3],
      "info": {
        "video.height": 480,
        "video.width": 640,
        "video.codec": "h264",
        "video.pix_fmt": "yuv420p",
        "video.fps": 30,
        "video.channels": 3,
        "is_depth_map": false,
        "video.g": 2,
        "video.crf": 30,
        "video.preset": "fast",
        "video.fast_decode": 0,
        "video.video_backend": "pyav",
        "video.extra_options": { "tune": "film", "profile:v": "high", "bf": 2 }
      }
    }
  }
}

Deux sources contribuent au bloc info :

SourceD'où il vientChamps
Dérivé du fluxLire à nouveau depuis le MP4 encodé avec PyAV.video.height, video.width, video.codec, video.pix_fmt, video.fps, video.channels, is_depth_map, audio.*
Dérivé de l'encodeurExtrait de RGBEncoderConfig / DepthEncoderConfig.video.g, video.crf, video.preset, video.fast_decode, video.video_backend, video.extra_options

Ce bloc est rempli une seule fois, à partir du premier épisode. Il suppose que tous les épisodes du jeu de données ont été encodés avec le même rgb_encoder. Modifier les paramètres de l’encodeur en cours d’enregistrement n’est pas pris en charge — le fichier info.json ne reflétera que les paramètres utilisés pour le premier épisode.


Fusion de jeux de données

Lors de l’agrégation de jeux de données avec merge_datasets, les fichiers vidéo sont concaténés tels quels (sans réencodage) et les champs encodeur de info.json sont fusionnés par clé :

Règle de fusionChampsComportement
Doit correspondrevideo.codec, video.pix_fmt, video.height, video.width, video.fpsLes champs dérivés des flux doivent correspondre entre les sources, sinon le démultiplexeur concat de FFmpeg échoue.
Fusion lâchevideo.g, video.crf, video.preset, video.fast_decode, video.extra_optionsChamps de réglage de l’encodeur. Si toutes les sources sont d’accord, la valeur est conservée ; sinon, elle est définie sur null (ou {} pour video.extra_options) et un avertissement est journalisé.
Update on GitHub