news 2026/4/18 9:40:05

BDD100K数据集标签转换实战:从JSON到YOLO格式的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
BDD100K数据集标签转换实战:从JSON到YOLO格式的完整指南

1. BDD100K数据集与YOLO格式简介

当你第一次接触BDD100K数据集时,可能会被它的JSON标签格式搞得一头雾水。这个由伯克利大学发布的自动驾驶数据集包含10万个视频片段,覆盖了各种天气、光照和道路场景,是训练目标检测模型的绝佳资源。但问题来了——YOLOv5/YOLOv8需要的是TXT格式的标签,每个文件对应一张图片,记录着归一化的目标位置和类别。

我刚开始用这个数据集时,花了一整天研究如何转换格式。后来发现,其实核心就是三步:解析JSON里的box2d坐标、按需筛选类别、将绝对坐标转为相对坐标。举个例子,JSON中一个"car"的坐标可能是{"x1": 320, "y1": 240, "x2": 480, "y2": 360},而YOLO需要的则是"0 0.5 0.5 0.25 0.25"这样的格式(假设类别car对应数字0)。

2. 环境准备与数据目录结构

在开始转换前,建议按这个结构组织你的文件夹:

bdd100k/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── det_annotations/ # 原始JSON标签 │ ├── train/ │ └── val/ └── yolo_labels/ # 转换后的TXT标签 ├── train/ └── val/

需要安装的Python包其实很简单:

pip install json numpy tqdm

我建议用tqdm加个进度条,特别是处理几万张图片时,看着进度条慢慢走完会有种莫名的治愈感。曾经有一次我没用进度条,程序跑了半小时我都不知道是否卡死了,最后忍不住强制终止,结果发现已经处理完了...

3. JSON标签解析实战

BDD100K的JSON结构比COCO复杂些,关键是要找到"frames"下的"objects"数组。每个对象包含:

  • category:类别名称(如"car")
  • box2d:包含x1,y1,x2,y2的边界框
  • attributes:可能有交通灯颜色等额外属性

这里有个坑:不同版本的BDD100K标签结构略有差异。有次我拿到的版本里,"frames"变成了"labels",害我debug了好久。建议先用这个代码检查结构:

import json with open("sample.json") as f: data = json.load(f) print(json.dumps(data, indent=2)[:500]) # 打印前500字符

4. 类别筛选与映射策略

BDD100K有13个基础类别,但你可能只需要其中几个。我整理了这个对照表:

BDD原始类别保留标记YOLO类别ID
car0
pedestrian-
traffic light1
.........

实现时建议用字典管理类别映射:

CLASS_MAP = { "car": 0, "traffic light": 1, "traffic sign": 2 }

处理交通灯时要特别注意,颜色信息藏在attributes里:

if obj["category"] == "traffic light": color = obj["attributes"]["trafficLightColor"] class_name = f"tl_{color}" # 如tl_red

5. 坐标归一化关键细节

这是最容易出错的部分!YOLO要求的是中心点坐标和宽高,且必须是相对于图像尺寸的比例值。计算公式如下:

def normalize_bbox(x1, y1, x2, y2, img_w=1280, img_h=720): x_center = (x1 + x2) / 2 / img_w y_center = (y1 + y2) / 2 / img_h width = (x2 - x1) / img_w height = (y2 - y1) / img_h return x_center, y_center, width, height

注意BDD100K默认分辨率是1280x720,但有些图片可能不同。安全起见,可以检查JSON中的"resolution"字段。我曾经因为忽略这个,导致小目标检测完全失效——所有框都偏移了20%!

6. 完整代码实现与优化

结合上述要点,这是优化后的转换代码:

import json import os from tqdm import tqdm class BDD2YOLO: def __init__(self): self.class_map = { "car": 0, "traffic light": 1, "traffic sign": 2, "person": 3 } def convert(self, json_path, output_dir): os.makedirs(output_dir, exist_ok=True) with open(json_path) as f: data = json.load(f) filename = data["name"] lines = [] for frame in data["frames"]: for obj in frame["objects"]: category = obj["category"] if category not in self.class_map: continue # 处理交通灯颜色 if category == "traffic light": color = obj["attributes"].get("trafficLightColor", "none") category = f"tl_{color}" # 坐标归一化 box = obj["box2d"] xc, yc, w, h = self.normalize_bbox( box["x1"], box["y1"], box["x2"], box["y2"] ) lines.append( f"{self.class_map[category]} {xc:.6f} {yc:.6f} {w:.6f} {h:.6f}\n" ) # 保存结果 if lines: with open(f"{output_dir}/{filename}.txt", "w") as f: f.writelines(lines) @staticmethod def normalize_bbox(x1, y1, x2, y2, img_w=1280, img_h=720): xc = (x1 + x2) / 2 / img_w yc = (y1 + y2) / 2 / img_h w = (x2 - x1) / img_w h = (y2 - y1) / img_h return xc, yc, w, h # 批量处理 converter = BDD2YOLO() json_dir = "bdd100k/labels/det_annotations/train" output_dir = "bdd100k/labels/yolo_labels/train" for filename in tqdm(os.listdir(json_dir)): converter.convert( f"{json_dir}/{filename}", output_dir )

这个版本比原始代码增加了错误处理、进度显示和更清晰的代码结构。用类封装也让后续维护更方便。

7. 验证与调试技巧

转换完成后,强烈建议做这些检查:

  1. 空文件检查:有些图片可能没有目标,确保对应的TXT文件为空或不存在
  2. 坐标范围验证:所有坐标值应在[0,1]范围内
  3. 可视化验证:用OpenCV画框检查是否对齐

这里有个可视化脚本片段:

import cv2 def visualize(img_path, label_path, class_names): img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path) as f: for line in f: cls_id, xc, yc, bw, bh = map(float, line.split()) x1 = int((xc - bw/2) * w) y1 = int((yc - bh/2) * h) x2 = int((xc + bw/2) * w) y2 = int((yc + bh/2) * h) cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2) cv2.putText(img, class_names[int(cls_id)], (x1,y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,255), 1) cv2.imshow("Preview", img) cv2.waitKey(0)

8. 性能优化与批量处理

当处理10万级数据时,我有几个提速心得:

  1. 多进程处理:Python的multiprocessing模块能大幅提升速度
from multiprocessing import Pool def process_file(filename): converter.convert(f"{json_dir}/{filename}", output_dir) with Pool(8) as p: # 8个进程 list(tqdm(p.imap(process_file, os.listdir(json_dir)), total=len(os.listdir(json_dir))))
  1. 缓存机制:如果中断后重新开始,可以跳过已处理的文件
  2. SSD存储:机械硬盘处理小文件速度会慢很多

最后提醒:转换完成后,记得在YOLO的配置文件中正确设置类别数和类别名称。比如在data.yaml中:

names: ["car", "traffic light", "traffic sign", "person"]
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:15:48

TurboDiffusion实测报告:图像生成视频的真实效果分析

TurboDiffusion实测报告:图像生成视频的真实效果分析 1. 开篇:当视频生成快到“眨眼即成” 你有没有试过在手机上点开一个短视频,刚想看清画面细节,视频已经播完了?现在,这种“快”正被TurboDiffusion带进…

作者头像 李华
网站建设 2026/4/17 19:52:32

Qwen3-VL-8B实战:3步搭建个人AI聊天网站(附完整教程)

Qwen3-VL-8B实战:3步搭建个人AI聊天网站(附完整教程) 你不需要懂模型训练,也不用配环境、调参数、写后端——只要三步,就能在自己的机器上跑起一个带界面、能看图、会对话、支持多轮的AI聊天网站。这不是Demo&#xf…

作者头像 李华
网站建设 2026/4/17 17:45:26

手把手教你用Lychee Rerank搭建智能图片搜索系统

手把手教你用Lychee Rerank搭建智能图片搜索系统 【一键部署镜像】Lychee Rerank 多模态智能重排序系统 高性能图文语义匹配工具,开箱即用,支持文本查图、以图搜图、图文混合检索 你是否遇到过这样的问题:在成千上万张产品图、设计稿或素材…

作者头像 李华
网站建设 2026/4/18 8:00:27

3步搞定CCMusic部署:让AI帮你识别音乐风格

3步搞定CCMusic部署:让AI帮你识别音乐风格 你有没有遇到过这样的场景:听到一首歌,被它的节奏和氛围深深吸引,却说不清它属于什么流派?是爵士的慵懒、摇滚的躁动、还是电子的律动?传统方法需要专业乐理知识…

作者头像 李华
网站建设 2026/4/18 5:39:15

LightOnOCR-2-1B实战:一键提取图片中的多语言文字

LightOnOCR-2-1B实战:一键提取图片中的多语言文字 1. 这不是传统OCR,而是一次文字提取的体验升级 你有没有过这样的经历:拍了一张会议白板照片,上面有中英文混排的要点;扫了一份带德语注释的工程图纸;或者…

作者头像 李华
网站建设 2026/4/18 8:05:49

Motrix便携版制作终极指南:跨平台免安装解决方案全解析

Motrix便携版制作终极指南:跨平台免安装解决方案全解析 【免费下载链接】Motrix A full-featured download manager. 项目地址: https://gitcode.com/gh_mirrors/mo/Motrix 一、便携化需求与技术挑战 在企业办公、公共机房或多设备切换场景中,传…

作者头像 李华