从TT100K到YOLO:一份完整的交通标志数据集转换与实战指南
1. 为什么需要转换TT100K数据集格式第一次接触TT100K数据集时我完全被它复杂的目录结构和标注格式搞懵了。这个由清华大学和腾讯联合发布的交通标志数据集包含了10万张图片和3万多个标注实例但它的JSON标注格式和YOLO完全不兼容。当时为了训练YOLOv5模型我不得不花了两周时间研究格式转换的问题。TT100K数据集最大的特点是采用层级式JSON标注所有标注信息都存放在一个巨大的annotations_all.json文件里。这种设计虽然节省了存储空间但在实际使用时非常不方便。相比之下YOLO需要的格式就简单多了——每个图片对应一个.txt文件每行记录一个目标的类别和归一化坐标。举个具体例子TT100K中一个停车标志的标注可能是这样的{ objects: [{ category: p12, bbox: {xmin: 100, ymin: 200, xmax: 150, ymax: 250} }] }而YOLO需要的格式则是0 0.325 0.417 0.104 0.083这种转换不仅仅是格式变化还涉及到坐标系的转换从绝对坐标到相对坐标、类别ID的重新映射从字符串标签到数字索引以及数据集划分策略的调整。我在第一次尝试时就因为忽略了图像尺寸的读取顺序导致所有检测框都偏移了位置。2. 数据预处理的关键步骤2.1 筛选有效类别TT100K原始数据集包含221个交通标志类别但实际项目中我们往往只需要其中的一部分。我的经验是先用以下代码统计各类别的实例数量with open(annotations_all.json) as f: data json.load(f) class_count {} for img_id, img_info in data[imgs].items(): for obj in img_info[objects]: class_count[obj[category]] class_count.get(obj[category], 0) 1 # 按数量排序 sorted_classes sorted(class_count.items(), keylambda x: x[1], reverseTrue)建议保留实例数超过100的类别这样可以保证每个类别都有足够的训练样本。在我的实践中最终筛选出了45个主要类别包括禁令标志如p1、p10警告标志如ph4、pl5指示标志如i2、i42.2 处理破损和无效数据数据集里总会有些问题儿童需要特别处理标注错误有些边界框完全超出图像范围需要用clamp函数限制坐标图像损坏约0.3%的JPEG文件无法正常读取建议用OpenCV的imread检查长宽比异常极少数图片的宽高比超过10:1这类样本最好剔除这里分享一个实用的图像验证代码片段def validate_image(img_path): try: img cv2.imread(img_path) if img is None: return False h, w img.shape[:2] return w 16 and h 16 # 过滤掉过小的图像 except: return False3. 从TT100K到COCO的格式转换3.1 构建COCO格式的中间层为什么需要COCO格式作为中转因为直接从TT100K转到YOLO格式会丢失很多结构化信息。我的转换脚本主要处理以下几个部分类别信息将筛选后的类别建立数字ID映射图像信息记录每张图片的路径、尺寸和唯一ID标注信息转换边界框格式并关联到对应图像核心的数据结构如下coco_format { info: {...}, licenses: [...], categories: [ {id: 0, name: p1, supercategory: prohibitory}, ... ], images: [ {id: 0, file_name: test/100.jpg, width: 640, height: 480}, ... ], annotations: [ { id: 0, image_id: 0, category_id: 0, bbox: [100, 200, 50, 50], area: 2500, iscrowd: 0 }, ... ] }3.2 数据集划分策略TT100K原本的划分方式不适合目标检测任务。我采用了分层抽样的方法确保每个类别在训练集、验证集和测试集中都有代表按7:2:1的比例划分对样本数较少的类别适当增加其在训练集中的比例确保同一张图片不会出现在多个子集中实现代码的关键部分for cls in class_list: cls_images get_images_by_class(cls) random.shuffle(cls_images) train_end int(0.7 * len(cls_images)) val_end train_end int(0.2 * len(cls_images)) train_set.update(cls_images[:train_end]) val_set.update(cls_images[train_end:val_end]) test_set.update(cls_images[val_end:])4. COCO到YOLO格式的终极转换4.1 坐标归一化处理这是最容易出错的环节。YOLO要求的是中心坐标宽高的归一化格式计算时需要特别注意def coco_to_yolo_bbox(bbox, img_width, img_height): # bbox格式[x_min, y_min, width, height] x_center bbox[0] bbox[2] / 2 y_center bbox[1] bbox[3] / 2 # 归一化 x_center / img_width y_center / img_height width bbox[2] / img_width height bbox[3] / img_height return [x_center, y_center, width, height]4.2 生成YOLO格式的标签文件每个图片对应一个.txt文件格式要求非常严格每行一个目标空格分隔的五个数值类别ID、中心x、中心y、宽度、高度数值精度保留6位小数实际操作时我建议使用这个模板def save_yolo_label(file_path, class_id, bbox): with open(file_path, a) as f: line f{class_id} {bbox[0]:.6f} {bbox[1]:.6f} {bbox[2]:.6f} {bbox[3]:.6f}\n f.write(line)4.3 创建数据集配置文件最后需要准备YOLO模型训练必需的data.yaml文件train: ../images/train val: ../images/val test: ../images/test nc: 45 # 类别数量 names: [p1, p10, ph4, ...] # 按类别ID顺序排列5. 实战中的常见问题与解决方案5.1 标签错位问题第一次训练时模型完全学不会任何东西。排查后发现是因为图像尺寸读取错误OpenCV的shape返回的是高度在前归一化时混淆了宽高顺序解决方法是在转换时统一添加尺寸检查height, width img.shape[:2] assert width 0 and height 0, fInvalid image size: {img_path}5.2 类别不平衡处理某些常见标志如限速标志的样本数是不常见标志的100倍以上。我采用了这些策略过采样少数类别使用带权重的损失函数在数据增强时对少数类别使用更强的变换5.3 数据增强技巧针对交通标志的特点这些增强方式特别有效模拟天气变化添加雾、雨、雪效果透视变换模拟不同拍摄角度色彩抖动考虑白平衡变化的影响示例增强代码import albumentations as A transform A.Compose([ A.RandomBrightnessContrast(p0.5), A.HueSaturationValue(p0.5), A.RandomFog(fog_coef_lower0.1, fog_coef_upper0.3, p0.1), A.RandomRain(p0.1) ])6. 完整代码结构与使用指南我的项目目录结构是这样的tt100k2yolo/ ├── configs/ │ ├── classes.txt # 筛选后的类别列表 │ └── data.yaml # YOLO数据集配置 ├── datasets/ │ ├── images/ # 图片文件夹 │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ └── labels/ # 标签文件夹 │ ├── train/ │ ├── val/ │ └── test/ └── scripts/ ├── convert.py # 主转换脚本 └── utils.py # 工具函数转换流程只需三步修改configs/classes.txt定义需要的类别运行转换脚本python scripts/convert.py \ --input_dir /path/to/tt100k \ --output_dir ./datasets \ --config ./configs/classes.txt检查生成的data.yaml文件7. 模型训练与效果验证使用转换后的数据集训练YOLOv8关键配置参数model YOLO(yolov8n.yaml) results model.train( dataconfigs/data.yaml, epochs300, imgsz640, batch16, optimizerAdamW )在我的RTX 3090上训练300个epoch大约需要8小时。最终在测试集上的指标mAP0.5: 0.87mAP0.5:0.95: 0.63推理速度8ms/张640x640特别要注意的是交通标志检测需要更高的召回率。我通过调整置信度阈值和NMS参数将漏检率控制在5%以下results model.predict( sourcetest.jpg, conf0.3, # 降低置信度阈值 iou0.4, # 放宽IoU阈值 augmentTrue )经过三个版本迭代这套转换流程已经稳定支持各种YOLO系列模型。最大的收获是认识到数据质量比模型结构更重要——合理的格式转换和数据处理能让普通模型也表现出色。

相关新闻

数据科学转行实战路径:问题驱动的认知构建法

数据科学转行实战路径:问题驱动的认知构建法

1. 这不是一张“通关地图”,而是一份我带过37个转行学员后画出的实战路标 数据科学学习路径——这个词听起来像一份标准化的课程表,但实际操作中,它更接近于在浓雾里徒步时手绘的地形草图:有标记、有涂改、有折痕,甚至…

2026/7/4 23:19:08 阅读更多 →
2026普通人AI使用指南:看懂参数、混合思考与国产模型三大核心

2026普通人AI使用指南:看懂参数、混合思考与国产模型三大核心

1. 这不是科幻预告片,是普通人下周就该打开手机查的“技术天气预报”2026年4月这个时间点,听起来像科幻小说里随手写的年份,但如果你最近刷过几条国产大模型发布会的短视频,或者留意过身边朋友突然开始用“文心一言新版本”写周报…

2026/7/4 23:17:06 阅读更多 →
Let‘s Encrypt泛域名证书申请与自动化续期实战指南

Let‘s Encrypt泛域名证书申请与自动化续期实战指南

1. 项目概述与核心价值最近在折腾自己的个人博客和几个内部服务,域名下挂了好几个子域名,每次给每个子域名单独申请SSL证书,不仅麻烦,续期更是让人头大。直到我开始用Let‘s Encrypt的泛域名证书,配合自动化续期脚本&a…

2026/7/4 23:17:06 阅读更多 →

最新新闻

AI赋能传染病建模:从数据到动力学模型的本地实践指南

AI赋能传染病建模:从数据到动力学模型的本地实践指南

这次我们来看一个将 AI 与传染病动力学建模结合的前沿方向。想象一下,你手头有一份流感爆发的病例数据,传统的建模方法可能需要复杂的微分方程和大量的手动调参,而 AI 模型能否直接从数据中“学习”出传播规律,甚至自动跑通整个建…

2026/7/5 0:07:38 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
Solidity 访问控制:onlyOwner 不是权限体系

Solidity 访问控制:onlyOwner 不是权限体系

Solidity 访问控制:onlyOwner 不是权限体系 一、单一 owner 很容易变成单点风险 很多 Solidity 合约早期会用 onlyOwner 解决权限问题。部署者可以升级参数、提取资金、暂停合约。简单项目这样写很快,但资产规模和协作人数上来后,单一 owner …

2026/7/4 23:59:31 阅读更多 →
终极AMD Ryzen调试指南:如何用免费开源工具深度掌控你的处理器性能?

终极AMD Ryzen调试指南:如何用免费开源工具深度掌控你的处理器性能?

终极AMD Ryzen调试指南:如何用免费开源工具深度掌控你的处理器性能? 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table…

2026/7/4 23:57:30 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻