使用FiftyOne查看自建数据集

  • 引言
  • 一、主要功能
  • 二、实现步骤
    • 2.1 方法调研
      • (1)FiftyOne
      • (2)Label Studio
      • (3)CVAT(Computer Vision Annotation Tool)
      • (4)TensorBoard / Weights & Biases (W&B)
      • (5)功能对比与结论
    • 2.2 安装FiftyOne
    • 2.3 在FiftyOne中建立自定义数据集
      • (1)配置标注文件路径并读取
      • (2)初始化数据集
      • (3)逐张图片读取标注文件创建样本
      • (4)批量添加样本到数据集
      • (5)启动服务
    • 2.4 查看效果


引言

计算机专业硕士在读,主要研究方向是特定目标大斜视角目标检测与定位。因为要做的是特定目标,公开数据集较少,经过多方考虑还是决定要自建数据集。最终考虑的解决方案还是 Blender + Python API 的方式,项目起名叫 RealEarthStudio
这系列文章主要对开发过程进行记录,方便我个人后续查看,也给相类似方向的同学提供一个思路。

【项目目录】:项目目录链接


一、主要功能

  • 功能:使用FiftyOne查看自建数据集。
  • 背景:前期已经初步完成了数据集的创建,现在我希望能够有工具能够实现数据集的查看。经过调研计划使用FiftyOne进行查看。
  • 效果
    在这里插入图片描述

二、实现步骤

2.1 方法调研

我的需求主要是针对数据集的查看,而且因为我们研究团队有研究生在做点云配准方向的内容,因此我想后续也可以用这个工具创建点云数据集。据此我调研了几种主流的工具:

(1)FiftyOne

  • 强大的 API
    • 提供完整的 Python SDK(可编程加载、过滤、分析数据集)
    • 内置 REST API(通过 fiftyone app --port 5151 启动后,前端可调用 /api 接口)
    • 支持 Jupyter Notebook 无缝集成
  • 多模态支持
    • 图像:COCO, YOLO, TFRecord, CVAT 等
    • 点云:原生支持 .pcd, .las, .ply(需配合 Open3D)
    • 视频、嵌入向量、分类、检测、分割全覆盖
  • 前端友好
    • 自带 Web UI(React + WebSocket),响应式设计
    • 可通过 iframe 嵌入你的前端应用
    • 支持自定义插件(如添加地图底图)
  • 部署灵活
    • 支持 pip install fiftyone
    • 提供 Docker 镜像voxel51/fiftyone
    • 可配置为远程服务(fiftyone app --remote
  • 开源免费:MIT 许可证,企业可私有部署
  • ❌ 点云渲染依赖浏览器 WebGL,超大点云(>10M 点)可能卡顿
  • ❌ 中文文档较少(但英文文档极完善)

💡 适用场景

图像+点云、API 驱动、可嵌入服务、开源可控。

(2)Label Studio

  • 强大 API:完整 REST API(创建项目、导入数据、获取标注等)
  • 支持多模态:图像、文本、音频、点云(实验性)
  • 可嵌入:提供 React 组件(@heartexlabs/label-studio-react
  • 开源:Apache 2.0,可私有部署
  • 核心定位是标注工具,纯“查看”体验不如 FiftyOne 流畅
  • ❌ 点云支持较弱(需自定义模板,性能一般)
  • ❌ 默认 UI 偏重任务流,不适合快速浏览大数据集

💡 适用场景

如果未来需要人工标注闭环,Label Studio 是好选择;但纯查看 + 点云,不如 FiftyOne。

(3)CVAT(Computer Vision Annotation Tool)

  • ✅ 工业级标注工具,支持视频跟踪、3D 点云(via KITTI 格式)
  • ✅ 提供 REST API 和 Python SDK (cvat-sdk)
  • ✅ 支持 Docker 一键部署
  • 过于重型:启动需多个容器(PostgreSQL, Redis, Django…)
  • 查看功能弱:UI 为标注优化,不适合快速浏览
  • ❌ 点云支持有限(仅 3D bounding box,无自由视角旋转)
  • ❌ 学习成本高

💡 适用场景

大型团队做专业标注,不适合轻量级查看需求

(4)TensorBoard / Weights & Biases (W&B)

  • ✅ W&B 提供优秀数据集版本管理和可视化
  • ✅ 支持图像、点云(W&B)
  • 非通用数据集浏览器:需先将数据“记录”到其系统中
  • W&B 是 SaaS:私有部署需企业版(贵)
  • ❌ TensorBoard 不支持点云,且交互弱

💡 适用场景

模型训练监控,不适合作为独立数据集查看器

(5)功能对比与结论

工具 图像查看 点云支持 REST API Python API 可嵌入前端 Docker 支持 开源
FiftyOne ✅✅✅ ✅✅(Open3D) ✅(内置) ✅✅✅ ✅(iframe/API) ✅ MIT
Label Studio ✅✅ ⚠️(实验性) ✅✅✅ ✅(React 组件) ✅ Apache
CVAT ⚠️(3D bbox) ✅ MIT
W&B ✅✅ ✅(需登录) ⚠️(企业版) ❌(SaaS)
TensorBoard ⚠️

最终决定使用FiftyOne作为主要的数据集查看器。

2.2 安装FiftyOne

pip install fiftyone

安装方法不再赘述。

2.3 在FiftyOne中建立自定义数据集

(1)配置标注文件路径并读取

# 配置路径
image_dir = #<你的数据文件夹路径>
annotation_file = os.path.join(image_dir, "metadata.json")

# 读取标注
with open(annotation_file, 'r') as f:
    annotations = json.load(f)

(2)初始化数据集

# 创建数据集
dataset_name = "real_world_studio_dataset"
if dataset_name in fo.list_datasets():
    fo.delete_dataset(dataset_name)
dataset = fo.Dataset(dataset_name)

(3)逐张图片读取标注文件创建样本

for img_name, anns in annotations.items():
    img_path = os.path.join(image_dir, img_name)

    detections = []
    for ann in anns:
        x, y, w, h = ann["bbox"]
        rel_bbox = [x - w / 2, y - h / 2, w, h]

        label_tags = []
        occlusion = ann["occlusion"]
        if occlusion <= 0.05:
            label_tags.append("未遮挡")
        elif occlusion <= 0.3:
            label_tags.append("轻度遮挡")
        elif occlusion <= 0.5:
            label_tags.append("中度遮挡")
        else:
            label_tags.append("重度遮挡")

        detection = fo.Detection(
            label=ann["target_class"],
            bounding_box=rel_bbox,
            confidence=1,
            occlusion=occlusion,
            tags=label_tags,
        )
        detections.append(detection)

    # 创建样本
    sample = fo.Sample(filepath=img_path)
    sample["RealEarthStudio标注"] = fo.Detections(detections=detections)
    sample["光照强度"] = anns[0]["sun_energy"]
    sample["光照角度"] = anns[0]["sun_azimuth_deg"]
    sample["光照仰角"] = anns[0]["sun_elevation_deg"]
    sample["拍摄距离"] = anns[0]["distance"]
    sample["拍摄角度"] = anns[0]["azimuth_deg"]
    elevation_deg = anns[0]["elevation_deg"]
    sample["拍摄仰角"] = elevation_deg
    sample["渲染器类型"] = anns[0]["renderer"]

    # 写入标签
    if elevation_deg > 80:
        sample.tags.append("顶视角")
    elif elevation_deg > 30:
        sample.tags.append("斜视角")
    else:
        sample.tags.append("大斜视角")

    samples.append(sample)

这里需要说明的是:在 FiftyOne 中,tagslabel tags(即检测框/分割区域上的标签)以及自定义字段 custom fields 是三种不同层级的元数据,适用于不同场景。

  • 样本级标签 Tags :描述整张图像/点云/视频帧的属性。用于快速分组、过滤整个样本。
  • 标注级标签 Label Tags:给单个检测框(Detection)、分割区域(Segmentation)等标注对象打标签。常用于表示该物体的状态(如遮挡、截断、困难样本等)。
  • 自定义字段 Custom Fields:推荐用于额外信息。如果你有更复杂或结构化的信息(如相机参数、天气、时间戳、渲染设置等),强烈建议使用自定义字段,而不是滥用 tags。

(4)批量添加样本到数据集

# 批量添加
dataset.add_samples(samples)
dataset.compute_metadata()
dataset.sort_by("拍摄角度", reverse=True)

(5)启动服务

session = fo.launch_app(dataset)
session.wait()

注意:这里一定要添加 session.wait() ,否则服务一启动就会停止。

2.4 查看效果

在这里插入图片描述


在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐