关于 fiftyone-dataset-import
fiftyone-dataset-import 是用于检查本地数据集并引导其导入 FiftyOne 的技能。它识别媒体、标注格式、分组模式和依赖要求,在创建数据集前征求确认,并核对导入样本数量。
主要功能
- 01扫描目录结构与媒体文件
- 02识别标注和数据集格式
- 03检测多模态分组模式
- 04检查格式所需的依赖包
- 05创建数据集前征求确认
- 06核对导入样本数量
适用场景
- 01导入带有已识别标注的图像或视频目录
- 02为 FiftyOne 准备分组多模态数据
- 03将 MCAP 记录导入为多模态样本
- 04在选择导入方式前了解数据集结构
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ voxel51/ fiftyone-skills --skill fiftyone-dataset-import安装后在 Claude Code 中输入/fiftyone-dataset-import确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
HF-HUB-IMPORT.mdLEROBOT-IMPORT.mdMCAP-AUTHORING.mdMCAP-DATASET-AND-VALIDATION.mdMCAP-TROUBLESHOOTING.mdREADME.mdSPECIALIZED-3D-FORMATS.mdUSE-CASE-EXAMPLES.md详细介绍
FiftyOne 的通用数据集导入
关键指令
始终遵循以下规则:
1. 首先扫描文件夹
导入前,深入扫描目录以了解其结构:
# Use bash to explore
find /path/to/data -type f | head -50
ls -la /path/to/data
2. 自动检测所有内容
自动检测媒体类型、标签格式和分组模式。如果可以推断出格式,绝不要询问用户指定格式。
3. 检测多模态分组
查找表明数据已分组的模式:
- 包含多个媒体文件的场景文件夹
- 具有共同前缀的文件名模式(例如,
scene_001_left.jpg、scene_001_right.jpg) - 应该分组的混合媒体类型(图像 + 点云)
4. 检测并安装所需的软件包
指定的自动驾驶开发工具包格式(PandaSet、nuScenes、Waymo Open、Argoverse、KITTI 3D、
Lyft L5、A2D2)需要外部 Python 软件包。使用 pip show <package> 检查,安装前询问用户,
然后通过导入测试验证。完整的软件包表、目录模式检测和完整转换工作流见
SPECIALIZED-3D-FORMATS.md。
导入或渲染 MCAP(.mcap/.bag/.rrd)文件不需要任何软件包。 仅凭文件扩展名
即可设置 media_type == "multimodal",频道解码和渲染由 FiftyOne App 在客户端完成。不要告诉用户
为此运行 pip install mcap。Python 端软件包唯一可选的用途是在打开 App 前读取频道架构,详见下方的第 9D 步。
3D 处理所需的其他软件包: open3d(PCD 转换)、pyntcloud、laspy
(LAS/LAZ)。Hugging Face Hub 所需软件包: huggingface_hub、pyarrow、Pillow。
5. 导入前确认
向用户展示检查结果,并在创建数据集前明确请求确认。 扫描摘要末尾务必以清晰的问题结尾,例如:
- “继续导入吗?”
- “要使用这些设置创建数据集吗?”
等待用户回复后再继续。 在用户确认之前不要创建数据集。
6. 检查现有数据集并生成名称
创建数据集前,检查拟定名称是否已存在:
list_datasets()
如果数据集名称已存在,询问用户:
- 覆盖:删除现有数据集并创建新的数据集
- 重命名:使用其他名称(建议使用
dataset-name-v2等替代名称) - 中止:取消导入
如果用户没有提供数据集名称,使用 {ADJECTIVE}_{NOUN}_{VERB} 模式生成一个有趣且唯一的名称:
squiggly_sky_floatsdroopy_horse_slamssmooth_grass_grumblesnervous_hamburger_yodels
使用 list_datasets() 交叉检查以确保名称唯一。继续操作前务必告知用户生成的名称。
7. 导入后验证
将导入的样本数与源文件数进行比较。报告任何差异。
8. 尽量简洁地向用户报告错误
向用户提供的错误消息应简单明了。使用详细错误信息在内部诊断问题。
完整工作流
扫描前,先确定源的类型——大多数源都是本地目录,按以下步骤 1-12 操作;但有两种格式会预先识别,而不是通过扫描散落文件来识别:
lerobot/...Hugging Face Hub 仓库 ID,或根目录下含有meta/info.json的本地目录 → LeRobot。直接跳转到步骤 9E和 LEROBOT-IMPORT.md;不要先对裸仓库 ID 执行步骤 1 的文件夹扫描,因为下载前本地没有可扫描的内容。- 任何其他 Hugging Face Hub 仓库 ID(
owner/name)或huggingface.co/datasets/...URL → 参见下文从 Hugging Face Hub 导入。 - 仅包含
.mcap/.bag/.rrd文件的本地目录 → 扫描、确认和创建时适用步骤 1-8,然后跳转到步骤 9D执行导入。 - 其他所有情况(包含图像、视频、点云或现有标注格式的本地路径)→ 从步骤 1 继续。
步骤 1:深度扫描文件夹
扫描目标目录以了解其结构:
# Count files by extension
find /path/to/data -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn
# List directory structure (2 levels deep)
find /path/to/data -maxdepth 2 -type d
# Sample some files
ls -la /path/to/data/* | head -20
# IMPORTANT: Scan for ALL annotation/label directories
ls -la /path/to/data/annotations/ 2>/dev/null || ls -la /path/to/data/labels/ 2>/dev/null
整理以下内容的清单:
- 按类型分类的媒体文件(图像、视频、点云、3D)
- 按格式分类的标注文件(JSON、XML、TXT、YAML、PKL)
- 目录结构(扁平、嵌套或基于场景)
- 所有现有的标注类型(长方体、分割、跟踪等)
对于 3D/自动驾驶数据集,请特别检查:
# List all annotation subdirectories
find /path/to/data -type d -name "annotations" -o -name "labels" | xargs -I {} ls -la {}
# Sample an annotation file to understand its structure
python3 -c "import pickle, gzip; print(pickle.load(gzip.open('path/to/annotation.pkl.gz', 'rb'))[:2])"
步骤 2:识别媒体类型
按扩展名对文件分类:
| 扩展名 | 媒体类型 | FiftyOne 类型 |
|---|---|---|
.jpg、.jpeg、.png、.gif、.bmp、.webp、.tiff | 图像 | image |
.mp4、.avi、.mov、.mkv、.webm | 视频 | video |
.pcd、.ply、.las、.laz | 点云 | point-cloud |
.fo3d、.obj、.gltf、.glb | 3D 场景 | 3d |
.mcap、.bag、.rrd | 多模态(机器人/自动驾驶传感器日志) | multimodal |
MCAP 录制文件是一种特殊情况。 单个 .mcap 文件是一个自包含的多模态片段,可以在内部保存多个时间同步的数据流(相机图像、LIDAR、IMU、GPS、变换、诊断信息),每个数据流都有各自的频道/主题。不存在单独的 MCAP 数据集类型,也没有要导入的标签文件:一个 .mcap 文件就是一个样本。请参见下文的步骤 9D。
LeRobot 数据集也是一种特殊情况。 LeRobot 源是一个根目录下含有 meta/info.json 的目录(或 lerobot/... Hugging Face Hub 仓库),而不是一堆散落的媒体文件——不要像上述模式那样逐个文件扫描。一个样本 = 一个片段,通过 fo.Dataset.from_dir(..., dataset_type=fo.types.LeRobotDataset) 构建,绝不要使用 add_samples。请参见下文的步骤 9E。
步骤 3:检测标签格式
根据文件模式识别标签格式:
| 模式 | 格式 | 数据集类型 |
|---|---|---|
annotations.json 或符合 COCO 结构的 instances*.json | COCO | COCO |
符合 Pascal VOC 结构的 *.xml 文件 | VOC | VOC |
每张图像对应一个 *.txt 文件,另有 classes.txt | YOLOv4 | YOLOv4 |
data.yaml + labels/*.txt | YOLOv5 | YOLOv5 |
每张图像对应一个 *.txt 文件(KITTI 格式) | KITTI | KITTI |
单个 annotations.xml(CVAT 格式) | CVAT | CVAT Image |
符合 OpenLABEL 结构的 *.json | OpenLABEL | OpenLABEL Image |
| 按类别分文件夹的结构 | 分类 | Image Classification Directory Tree |
带有文件路径列的 *.csv | CSV | CSV |
符合 GeoJSON 结构的 *.json | GeoJSON | GeoJSON |
.dcm DICOM 文件 | DICOM | DICOM |
带有地理元数据的 .tiff | GeoTIFF | GeoTIFF |
源目录根目录下的 meta/info.json + meta/episodes/*.parquet(或 lerobot/... 下的 HF 仓库) | LeRobot | LeRobotDataset |
LeRobot 机器人学习数据集基于目录,而非文件:在尝试匹配以上任何模式之前,先检查源目录根目录下是否存在 meta/info.json(或 HF 仓库 ID 是否位于 lerobot/ 命名空间下)。无需单独导入标签文件——片段、任务以及 observation.state/action 数据均由 LeRobot 导入器提供。参见
步骤 9E。
专用自动驾驶格式(PandaSet、nuScenes、Waymo Open、Argoverse、KITTI 3D、 Lyft L5、A2D2)需要外部开发工具包和转换步骤。有关目录模式检测、软件包表格和完整转换工作流,请参见 SPECIALIZED-3D-FORMATS.md。
步骤 4:检测所需软件包
检查检测到的格式所需的软件包是否已安装(pip show <package>),告知用户需要安装什么以及原因,征得用户许可后再安装,然后通过导入冒烟测试进行验证。详细信息请参见 SPECIALIZED-3D-FORMATS.md。
步骤 5:检测分组模式
确定数据是否需要分组:
模式 A:场景文件夹(多模态数据中最常见)
/data/
├── scene_001/
│ ├── left.jpg
│ ├── right.jpg
│ ├── lidar.pcd
│ └── labels.json
├── scene_002/
│ └── ...
检测:每个子文件夹 = 一个组,文件 = 切片
模式 B:文件名前缀
/data/
├── 001_left.jpg
├── 001_right.jpg
├── 001_lidar.pcd
├── 002_left.jpg
├── 002_right.jpg
├── 002_lidar.pcd
检测:通用前缀 = 组 ID,后缀 = 切片名称
模式 C:不分组(平铺)
/data/
├── image_001.jpg
├── image_002.jpg
├── image_003.jpg
检测:单一媒体类型,没有明确的分组模式
模式 D:MCAP 多模态录制(无需分组)
/data/
├── episode-0001.mcap
├── episode-0002.mcap
├── episode-0003.mcap
检测:每个 .mcap/.bag/.rrd 文件本身就是独立完整的多模态录制(摄像头、激光雷达、IMU、GPS 等都是文件内部的通道)。不要尝试将这些文件与其他文件分组——将每段录制作为单个样本导入。参见
步骤 9D。
步骤 6:向用户展示检测结果
导入前,向用户提供清晰的摘要,其中包括所有检测到的标签:
Scan Results for /path/to/data:
Media Found:
- 3,000 images (.jpg, .png)
- 1,000 point clouds (.pkl.gz → will convert to .pcd)
- 0 videos
Grouping Detected:
- Pattern: Scene folders
- Groups: 1,000 scenes
- Slices: left (image), right (image), front (image), lidar (point-cloud)
ALL Labels Detected:
├── cuboids/ (3D bounding boxes, 1,000 files)
│ └── Format: pickle, Fields: label, position, dimensions, rotation, track_id
├── semseg/ (Semantic segmentation, 1,000 files)
│ └── Format: pickle, point-wise class labels
└── instances.json (2D detections, COCO format)
└── Classes: 10 (car, pedestrian, cyclist, ...)
Required Packages:
- ✅ pandaset (installed)
- ⚠️ open3d (needed for PCD conversion) → pip install open3d
Proposed Configuration:
- Dataset name: my-dataset
- Type: Grouped (multimodal)
- Default slice: front_camera
- Labels to import:
- detections_3d (from cuboids/)
- point_labels (from semseg/)
- detections (from instances.json)
Proceed with import? (yes/no)
重要:
- 列出扫描期间找到的所有标注类型
- 展示每种标签类型的格式/结构
- 指明将导入哪些标签以及导入方式
- 继续操作前等待用户确认
步骤 7:检查现有数据集并生成名称
创建前,检查该数据集名称是否已存在:
# Check existing datasets
list_datasets()
如果用户未提供名称,请使用 {ADJECTIVE}_{NOUN}_{VERB} 模式生成一个名称(例如,smooth_grass_grumbles)。与 list_datasets() 的结果交叉核对,确保名称唯一。继续操作前务必告知用户生成的名称。
如果建议的数据集名称已存在于列表中:
- 告知用户:“名为 'my-dataset' 的数据集已存在,其中有 X 个样本。”
- 询问用户的选择:
- 覆盖:先删除现有数据集
- 重命名:提供替代名称建议(例如,
my-dataset-v2、my-dataset-20240107) - 中止:取消导入
如果用户选择覆盖:
# Delete existing dataset
set_context(dataset_name="my-dataset")
execute_operator(
operator_uri="@voxel51/utils/delete_dataset",
params={"name": "my-dataset"}
)
步骤 8:创建数据集
# Create the dataset
execute_operator(
operator_uri="@voxel51/utils/create_dataset",
params={
"name": "my-dataset",
"persistent": true
}
)
# Set context
set_context(dataset_name="my-dataset")
步骤 9A:导入简单数据集(无分组)
对于不含分组的扁平数据集:
# Import media only
execute_operator(
operator_uri="@voxel51/io/import_samples",
params={
"import_type": "MEDIA_ONLY",
"style": "DIRECTORY",
"directory": {"absolute_path": "/path/to/images"}
}
)
# Import with labels
execute_operator(
operator_uri="@voxel51/io/import_samples",
params={
"import_type": "MEDIA_AND_LABELS",
"dataset_type": "COCO",
"data_path": {"absolute_path": "/path/to/images"},
"labels_path": {"absolute_path": "/path/to/annotations.json"},
"label_field": "ground_truth"
}
)
步骤 9B:导入分组数据集(多模态)
对于包含分组的多模态数据,请直接使用 Python。引导用户:
import fiftyone as fo
# Create dataset
dataset = fo.Dataset("multimodal-dataset", persistent=True)
# Add group field
dataset.add_group_field("group", default="front")
# Create samples for each group
import os
from pathlib import Path
data_dir = Path("/path/to/data")
samples = []
for scene_dir in sorted(data_dir.iterdir()):
if not scene_dir.is_dir():
continue
# Create a group for this scene
group = fo.Group()
# Add each file as a slice
for file in scene_dir.iterdir():
if file.suffix in ['.jpg', '.png']:
# Determine slice name from filename
slice_name = file.stem # e.g., "left", "right", "front"
samples.append(fo.Sample(
filepath=str(file),
group=group.element(slice_name)
))
elif file.suffix == '.pcd':
samples.append(fo.Sample(
filepath=str(file),
group=group.element("lidar")
))
elif file.suffix == '.mp4':
samples.append(fo.Sample(
filepath=str(file),
group=group.element("video")
))
# Add all samples
dataset.add_samples(samples)
print(f"Added {len(dataset)} samples in {len(dataset.distinct('group.id'))} groups")
步骤 9C:导入专用格式数据集(3D/自动驾驶)
对于需要外部开发工具包的数据集(PandaSet、nuScenes、Waymo、Argoverse、KITTI 3D、Lyft
L5、A2D2),请使用开发工具包加载原始数据,将点云转换为 PCD,为 3D 可视化构建 fo.Scene
对象,并导入检测到的所有标签类型(立方体、分割、跟踪)。完整工作流、PCD 转换代码、标签类型映射以及完整的 PandaSet 示例,请参阅 SPECIALIZED-3D-FORMATS.md。
步骤 9D:导入多模态(MCAP)录制文件
MCAP 是 FiftyOne 用于时间同步的机器人和自动驾驶车辆传感器日志的容器格式(摄像头图像、LIDAR/点云、IMU、GPS、坐标系变换、诊断信息等,全部作为通道/主题存储在一个文件中)。与上面的专用 3D 格式不同,导入时无需开发工具包、无需转换标签,也无需额外的 Python 软件包——仅凭样本的 filepath 扩展名,FiftyOne 就足以将其归类为 media_type == "multimodal";通道模式(ROS 1/2、Foxglove、JSON)的解码和平铺查看器的渲染完全由客户端在 App 中打开样本时完成。
本节介绍常见情形:你已经有可正常使用的 .mcap 文件,只需将它们导入数据集。 如需深入了解,以下三个关联参考文件提供了其余信息。请阅读与实际情况相符的文件:
| 情况 | 阅读 |
|---|---|
| 某个平铺视图未能渲染,或 App“看起来坏了” | MCAP-TROUBLESHOOTING.md。在认定为 bug 之前,请先查看其中的症状表:当模式无法解码时,查看器会按设计静默失败,因此大多数“导入不起作用”的报告实际上根本不是导入 bug |
使用 foxglove-sdk 从原始传感器数据(ROS 包、Zarr、HDF5、PCD、CSV、图像文件夹)创作 .mcap,或转换/合并/拆分/修补现有 MCAP 文件 | MCAP-AUTHORING.md |
| 从已完成的片段构建 FiftyOne 数据集,或准备宣布导入完成 | MCAP-DATASET-AND-VALIDATION.md |
1. 导入。 每个 .mcap 文件恰好对应一个样本。无需安装软件包。
使用与用例 3(点云)相同的 MEDIA_ONLY + glob 模式:
execute_operator(
operator_uri="@voxel51/utils/create_dataset",
params={"name": "robot-teleop-episodes", "persistent": true}
)
set_context(dataset_name="robot-teleop-episodes")
execute_operator(
operator_uri="@voxel51/io/import_samples",
params={
"import_type": "MEDIA_ONLY",
"style": "GLOB_PATTERN",
"glob_patt": {"absolute_path": "/path/to/recordings/*.mcap"}
}
)
也可以直接在 Python 中执行,以获得更多控制(例如,按来源为片段添加标签,或添加从文件名提取的自定义元数据字段):
import fiftyone as fo
from pathlib import Path
dataset = fo.Dataset("robot-teleop-episodes", persistent=True)
recordings_dir = Path("/path/to/recordings")
samples = [
fo.Sample(filepath=str(mcap_file))
for mcap_file in sorted(recordings_dir.glob("*.mcap"))
]
dataset.add_samples(samples)
print(dataset.media_type) # "multimodal"
2. 不要将 MCAP 样本与其他切片分组。 每个 .mcap 文件本身已经包含所有传感器流。将它作为一个切片添加到 fo.Group() 中,同时再加入单独导出的摄像头或 LiDAR 文件,会导致重复添加录制文件中已有的数据。
2b. 根据模式而不是主题名称检测功能,并将其存储为字段。 主题名称并不能可靠地表示数据的渲染方式。名为 /livox/lidar 或 /os_node/imu_packets 的主题看起来像 LiDAR 或 IMU 数据,但如果其实际消息模式是供应商专用格式(Livox 的 livox_ros_driver/msg/CustomMsg 或 Ouster 的原始 ouster_ros/msg/PacketMsg),FiftyOne 就没有内置解码器。无论主题名称是什么,这类数据都不会在 3D 或 Plot 平铺视图中渲染,并且始终会回退到原始 Message 平铺视图。每种平铺视图只能渲染固定的一组模式。完整列表请参阅 MCAP-TROUBLESHOOTING.md 中的模式与平铺视图对照表;自定义或专有的 LiDAR 消息不在列表中,因此预期会保留在 Message 平铺视图中。
使用轻量级 mcap 包(pip install mcap,这是一个纯 Python 读取器,与任何 ROS 安装无关)从文件中检查真实的架构,并将结果存储为布尔字段(has_pointcloud、has_image、has_gps、has_imu 等),这样用户和 Agent 无需在 App 中逐个打开录制文件,就能查询多个录制文件的能力。请使用 MCAP-DATASET-AND-VALIDATION.md 中完整的 mcap_stats()/build_sample() 辅助函数,而不要重新实现一个功能更有限的版本。它还会在同一轮处理中提取验证所需的 duration_s、message_count、topics 和 schemas,并可通过 dataset.match(F("has_pointcloud")) 回答“这个文件会显示点云吗”,而无需逐个打开样本来确认。
3. 验证。 确认 dataset.media_type == "multimodal",并且样本数量与扫描期间找到的录制文件数量一致。单个通道、主题、注释和时间轨迹应在 App 的多模态查看器中检查,而不是通过 Python 导入步骤检查。对于超过少数几个文件的情况,还应运行 MCAP-DATASET-AND-VALIDATION.md 中开销很小的 validate_mcap() 结构检查。文件可能通过这里所有基于计数的检查,但实际上已遭到静默损坏,只有真正打开样本时才会暴露问题。
4. 启动 App 以探索数据流。FiftyOne 会在平铺查看器中打开多模态样本(图像、3D、地图、绘图、消息和日志平铺),并使用共享的播放时钟:
launch_app(dataset_name="robot-teleop-episodes")
关于播放开始时“无数据”的说明: 消息、绘图、3D 和地图平铺都会显示截至当前播放头的最新消息。如果某个主题的首条消息不是从 t=0 开始的(很常见,因为传感器启动会有延迟),绑定到该主题的平铺在播放经过该主题的首个时间戳之前确实会显示为空,例如“此主题在当前播放头或之前没有消息”。这是预期行为,并不表示导入失败。得出平铺损坏的结论前,请先按下播放键或向前拖动播放位置进行确认。如果之后平铺仍显示异常,请先查看 MCAP-TROUBLESHOOTING.md 的症状表,不要贸然认定导入失败。
注意: 时间标签(录制文件中时间区间上的标签,通过 dataset.temporal_tags.add(...) 添加)可在本地使用,无需 Enterprise。相关用法请参阅 MCAP-DATASET-AND-VALIDATION.md。MCAP 索引会将通道投影到可查询的 Parquet 表中,以便跨录制文件搜索;这是仅限 Enterprise 的功能,不在本地导入的讨论范围内。如果用户询问此功能,请参阅 FiftyOne 多模态指南。
步骤 9E:导入 LeRobot 机器人学习数据集
LeRobot 是一种基于目录的机器人学习数据集格式(本地数据集,或从 Hugging Face Hub 的 lerobot/... 仓库下载,例如 lerobot/aloha_sim_insertion_human)。一个样本对应一个episode,而不是一个文件,并且 fo.types.LeRobotDataset 仅支持 v3 布局。
完整工作流、STOP 检查关卡和故障排除请参阅 LEROBOT-IMPORT.md——导入 LeRobot 数据源前请先阅读。 摘要:
- 确认数据源(本地路径或 HF 仓库 ID),如果位于 Hub 上则将其下载。
- 检查
meta/info.json并检测codebase_version;如有需要,使用lerobot的转换器将 v2.x 转为 v3(fo.types.LeRobotDataset遇到 v2.x 时会引发UnsupportedLeRobotVersionError)。 - STOP 检查关卡: 在安装任何内容之前,确认所需软件包(
pyarrow>=10.0.0、huggingface_hub、lerobot)。 - STOP 检查关卡: 展示导入计划(episode 数量、fps、robot_type、摄像头/状态/动作形状),并等待确认后再创建数据集。
- 使用
fo.list_datasets()检查名称冲突,然后导入:
import fiftyone as fo
dataset = fo.Dataset.from_dir(
dataset_dir="/abs/path/lerobot/<name>",
dataset_type=fo.types.LeRobotDataset,
name="<name>",
persistent=True,
)
- 将导入的 episode 数量与
meta/info.json中的total_episodes核对,并报告dataset.info["lerobot"]["skipped_episodes"]——如果任一项不匹配,不要宣告成功。 - 启动 App:episode 将以每个摄像头一个 Image 瓦片、一个 State & Action 瓦片、用于状态/动作维度的 Plot 瓦片以及一个 Streams 标签页呈现。
此处不要使用 add_samples——它无法引入 LeRobot 数据源。使用 dataset.add_dir(..., dataset_type=fo.types.LeRobotDataset) 将更多 LeRobot 数据源添加到现有数据集中。
步骤 10:导入其他标签(可选)
如果标签未随专用格式一同导入,请单独添加:
# For COCO labels that reference filepaths
execute_operator(
operator_uri="@voxel51/io/import_samples",
params={
"import_type": "LABELS_ONLY",
"dataset_type": "COCO",
"labels_path": {"absolute_path": "/path/to/annotations.json"},
"label_field": "ground_truth"
}
)
步骤 11:验证导入
# Load and verify
load_dataset(name="my-dataset")
# Check counts match
dataset_summary(name="my-dataset")
比较:
- 导入的样本与源文件
- 已创建的分组与预期分组
- 导入的标签与标注数量
步骤 12:启动 App 并查看
launch_app(dataset_name="my-dataset")
# For grouped datasets, view different slices
# In the App, use the slice selector dropdown
支持的数据集类型
媒体类型
| 类型 | 扩展名 | 描述 |
|---|---|---|
image | .jpg、.jpeg、.png、.gif、.bmp、.webp、.tiff | 静态图像 |
video | .mp4、.avi、.mov、.mkv、.webm | 带帧的视频文件 |
point-cloud | .pcd、.ply、.las、.laz | 3D 点云数据 |
3d | .fo3d、.obj、.gltf、.glb | 3D 场景和网格 |
multimodal | .mcap、.bag、.rrd | 时间同步的机器人/AV 传感器记录(MCAP 容器格式) |
标签格式
| 格式 | 数据集类型值 | 标签类型 | 文件模式 |
|---|---|---|---|
| COCO | COCO | 检测、分割、关键点 | *.json |
| VOC/Pascal | VOC | 检测 | 每张图像一个 *.xml |
| KITTI | KITTI | 检测 | 每张图像一个 *.txt |
| YOLOv4 | YOLOv4 | 检测 | *.txt + classes.txt |
| YOLOv5 | YOLOv5 | 检测 | data.yaml + labels/*.txt |
| CVAT Image | CVAT Image | 分类、检测、折线、关键点 | 单个 *.xml |
| CVAT Video | CVAT Video | 帧标签 | XML 目录 |
| OpenLABEL Image | OpenLABEL Image | 所有类型 | *.json 目录 |
| OpenLABEL Video | OpenLABEL Video | 所有类型 | *.json 目录 |
| TF Object Detection | TF Object Detection | 检测 | TFRecords |
| TF Image Classification | TF Image Classification | 分类 | TFRecords |
| Image Classification Tree | Image Classification Directory Tree | 分类 | 每个类别一个文件夹 |
| Video Classification Tree | Video Classification Directory Tree | 分类 | 每个类别一个文件夹 |
| Image Segmentation | Image Segmentation | 分割 | 掩码图像 |
| CSV | CSV | 自定义字段 | *.csv |
| DICOM | DICOM | 医疗元数据 | .dcm 文件 |
| GeoJSON | GeoJSON | 地理位置 | *.json |
| GeoTIFF | GeoTIFF | 地理位置 | 带地理信息的 .tiff |
| FiftyOne Dataset | FiftyOne Dataset | 所有类型 | 导出格式 |
| LeRobot | LeRobotDataset | 回合元数据(任务、状态、动作、时长) | meta/info.json + meta/episodes/*.parquet |
常见用例
USE-CASE-EXAMPLES.md 中提供了 COCO、YOLO、点云、自动驾驶分组、分类树和混合媒体的可复制粘贴入门示例。
使用分组
了解分组结构
在分组数据集中:
- 每个组代表一个场景/时刻(例如,一个时间戳)
- 每个切片代表一种模态(例如,左侧摄像头、激光雷达)
- 组内所有样本共享相同的
group.id - 每个样本都有一个
group.name,用于标示其切片
# Access group information
print(dataset.group_slices) # ['front_camera', 'left_camera', 'lidar']
print(dataset.group_media_types) # {'front_camera': 'image', 'lidar': 'point-cloud'}
print(dataset.default_group_slice) # 'front_camera'
# Iterate over groups
for group in dataset.iter_groups():
print(f"Group has {len(group)} slices")
for slice_name, sample in group.items():
print(f" {slice_name}: {sample.filepath}")
# Get specific slice view
front_images = dataset.select_group_slices("front_camera")
all_point_clouds = dataset.select_group_slices(media_type="point-cloud")
在应用中查看分组
启动应用后:
- 顶栏中会出现切片选择下拉菜单
- 选择不同切片以查看各个模态
- 样本会同步显示——选择一个样本即可查看其所属组中的所有样本
- 使用网格视图并排查看多个切片
从 Hugging Face Hub 导入
完整的 HF Hub 导入文档请参阅 HF-HUB-IMPORT.md。
快速参考:
| 数据集类型 | 方法 |
|---|---|
FiftyOne 格式(fiftyone.yml) | load_from_hub("repo_id") |
| 基于 Parquet 的数据集 | load_from_hub("repo_id", format="ParquetFilesDataset", filepath="image") |
| HF 上的 COCO/YOLO/VOC | snapshot_download() → 本地导入 |
| 受速率限制(>10K) | Parquet 提取回退方案(参见 HF-HUB-IMPORT.md) |
LeRobot(lerobot/...) | 运行 hf download,然后执行 fo.Dataset.from_dir(..., dataset_type=fo.types.LeRobotDataset) — 参见 步骤 9E |
快速入门:
from fiftyone.utils.huggingface import load_from_hub
# FiftyOne-formatted dataset
dataset = load_from_hub("Voxel51/VisDrone2019-DET", persistent=True)
# Generic parquet dataset
dataset = load_from_hub(
"username/dataset",
format="ParquetFilesDataset",
filepath="image",
classification_fields="label",
persistent=True,
)
LeRobot 仓库(lerobot/...)是例外——不要通过 load_from_hub() 导入。
请使用 hf download 下载,然后使用 fo.Dataset.from_dir(..., dataset_type=fo.types.LeRobotDataset) 导入。
请参阅 步骤 9E 和
LEROBOT-IMPORT.md。
故障排除
错误:"Dataset already exists"
- 使用其他数据集名称
- 或删除现有数据集:
execute_operator("@voxel51/utils/delete_dataset", {"name": "dataset-name"})
错误:"No samples found"
- 确认目录路径正确且可访问
- 检查文件扩展名是否受支持
- 对于嵌套目录,请确保启用递归扫描
错误:"Labels path not found"
- 确认标签文件或目录存在
- 检查路径是否为绝对路径,而非相对路径
- 确保检测到正确的格式
错误:"Invalid group configuration"
- 每个组必须至少包含一个样本
- 各组中的切片名称必须一致
- 每个组只能有一个
3d切片
导入速度较慢
- 对于大型数据集,请使用委托执行
- 如有需要,可分批导入
- 考虑使用 glob 模式筛选文件
点云无法渲染
- 确保
.pcd文件有效 - 检查是否启用了 FiftyOne 3D 可视化
- 确认已安装点云插件
已添加 MCAP 样本,但 dataset.media_type 不是 "multimodal"
- 确认文件路径扩展名恰好为
.mcap、.bag或.rrd(小写) - 数据集的媒体类型取决于其所有样本的扩展名——在同一个(非分组)数据集中混合
.mcap文件与图像或视频会导致媒体类型冲突;请将 MCAP 录制文件放在独立数据集中或单独的组切片中
多模态磁贴(Image/3D/Map/Plot/Logs)渲染结果不符合预期
- 这几乎从来不是导入损坏——如果架构无法解码,或主题的数据不是从
t=0开始,查看器会按设计静默失败。请先查看 MCAP-TROUBLESHOOTING.md 中的症状表 - 如果你要编写、转换或修补
.mcap文件本身(而不只是导入现有文件),请改为查看 MCAP-AUTHORING.md
未检测到组
- 检查文件夹结构是否符合预期模式
- 确认不同场景的命名一致
- 可能需要手动指定分组
LeRobot 数据源出现 UnsupportedLeRobotVersionError 或 MalformedMediaSourceError
- 该数据源为 v2.x(使用
meta/episodes.jsonl,而非meta/episodes/*.parquet)——请先转换为 v3。详见 LEROBOT-IMPORT.md 的步骤 4 和完整故障排除表 add_samples无法添加 LeRobot 数据源——请使用from_dir/add_dir,并设置dataset_type=fo.types.LeRobotDataset
最佳实践
- 始终先扫描 - 导入前先了解数据
- 与用户确认 - 创建数据集前先展示扫描结果
- 使用描述性名称 - 数据集名称和标签字段应有明确含义
- 验证数量 - 确保导入的样本与源文件相符
- 妥善处理错误 - 清楚地报告问题,并继续处理有效文件
- 多模态数据使用分组 - 不要将应分组的数据展平
- 设置合适的默认切片 - 选择最常查看的模态
- 为导入添加标签 - 使用标签追踪导入批次或来源
性能说明
导入时间估算:
- 1,000 张图像:约 10-30 秒
- 10,000 张图像:约 2-5 分钟
- 100,000 张图像:约 20-60 分钟
- 点云:比图像慢约 2 倍
- 视频:取决于帧提取设置
内存需求:
- 每个样本元数据约 1KB
- 媒体文件仅被引用,不会加载到内存
- 大型数据集可能需要提高 MongoDB 限制
资源
- FiftyOne 数据集导入指南
- 分组数据集指南
- 点云支持
- FiftyOne 多模态(MCAP)指南
- 支持的数据集格式
- FiftyOne I/O 插件
- FiftyOne Hugging Face 集成
- Hugging Face Hub 文档
- LeRobot GitHub 仓库 — 数据集格式、v2→v3 转换脚本
- LeRobot 数据集格式文档 — episode/chunk 布局、
meta/info.json架构
此技能目录会按需读取参考文件,而非在每次调用时读取所有文件:
- HF-HUB-IMPORT.md:Hugging Face Hub 相关信息
- SPECIALIZED-3D-FORMATS.md:PandaSet/nuScenes/Waymo/Argoverse/KITTI 3D/Lyft L5/A2D2 devkit 工作流
- USE-CASE-EXAMPLES.md:常见导入形式的可复制粘贴起点
- MCAP-TROUBLESHOOTING.md:症状表,以及瓦片未渲染的原因
- MCAP-AUTHORING.md:从原始数据创建 MCAP、转换 ROS 包、合并/修补
- MCAP-DATASET-AND-VALIDATION.md:功能标记、验证,以及 MCAP 导入的流程规范
- LEROBOT-IMPORT.md:完整的 LeRobot 工作流 — HF Hub 下载、v2.x → v3 转换、STOP 检查点、验证和故障排查