尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

交通灯检测未标注数据获取与利用:从数据集挖掘到伪标签训练

交通灯检测未标注数据获取与利用:从数据集挖掘到伪标签训练 简介本资源是面向计算机视觉与智能交通领域研究者的交通灯检测基础数据集适用于目标检测模型训练、信号灯状态识别算法验证及CCF BDCI相关赛题备赛。数据集包含2000个原始采集样本其中1997张JPG格式图像覆盖城市道路、交叉口、不同光照与天气条件下的真实交通灯场景2个JSON文件提供图像元信息与初步结构化描述1个TXT文件含基础说明与使用指引整体压缩包大小为873.01MB。目前已有1702人下载学习体现了其在实际项目中的高参考价值。用户可直接获取未经标注的原始图像资源结合主流标注工具如LabelImg、CVAT开展自定义标注适配YOLO、Faster R-CNN等检测框架同时图像数量充足、场景多样性高便于划分训练/验证/测试集并支持多任务拓展如红黄绿灯分类、箭头灯识别等。1. 为什么你需要一份“未标注”的交通灯数据1.1 交通灯检测到底难在哪做了几年检测任务说实话交通灯是少数让我觉得“数据比模型更值钱”的方向。它和通用目标检测不太一样难在几个很实际的地方第一目标太小。路口画面里一辆车可能占几百个像素但一个信号灯往往只有二三十个像素。在博世那套经典数据集里很多灯的标注框甚至不到32x32像素放到YOLOv8默认的640输入分辨率里基本就是几个点。第二环境干扰太严重。逆光、雨天、夜晚、LED屏闪烁、树影遮挡、对面车灯直射都会让同一盏灯呈现出完全不同的样子。第三地域差异非常大。国内常见的是圆盘灯加倒计时欧洲很多路口是横排的小箭头灯美国还有一堆黄灯闪烁的工况。同一个模型搬到另一个城市性能掉几个点是非常正常的。也就是说交通灯检测的真正瓶颈不是模型结构而是数据能不能覆盖足够多的场景。而“覆盖场景”这件事其实不一定非要靠人工标注数据来完成。未标注数据同样能帮上大忙。1.2 未标注数据能解决什么问题很多人一听到“未标注数据”就觉得没用因为训练目标检测确实需要框。这是思维定式。未标注数据在交通灯这个场景里至少有三条成熟的用法自监督预训练。拿到几千张没标签的路口图像在域内数据上做一轮自监督预训练让backbone先学会“红灯、绿灯、黄灯、箭头灯长什么样”这种底层视觉特征再拿少量标注数据微调。实践里这种做法的效果往往比直接用ImageNet预训练权重要好尤其是当标注数据只有几百张的时候。伪标签 半监督迭代。用一个已经能用的交通灯检测模型在未标注数据上推理把高置信度的预测结果当成标签和人工标注数据混合在一起训练。这是目前性价比最高的扩数据方式后面我会重点讲怎么做。域适应。你的模型在A城市跑得好到了B城市效果变差。这时候你不需要在B城市标大量数据只需要采集B城市的未标注路口视频用域适应或者自训练的方式让模型对齐目标场景的分布。这在智慧交通项目交付时特别实用。1.3 哪些人适合看这篇这篇文章主要写给三类人一是做自动驾驶感知的算法工程师想扩充交通灯场景但标注预算有限二是做智慧交通、车路协同项目的开发者手里有大量摄像头视频但是没时间标三是刚入门目标检测的学生想完整体验一遍“数据采集—清洗—伪标签—训练—评估”的全流程。如果你只是想要一份“下载下来就能直接train”的标注数据集那这篇帮助有限但如果你手头恰好有一些路口视频、行车记录仪视频或者你能从公开数据集的原始视频里挖出大量未标注帧那这篇应该能帮你省下好几周的标注时间。2. 主流交通灯数据集盘点哪些能拿到未标注数据2.1 经典数据集清单与特点我把做交通灯检测绕不开的几个公开数据集整理了一下。这里我特意不写死精确到个位数的统计量因为很多版本和划分在不同平台上不一样以官方发布文档为准更可靠。但数据集的特点和适用方向是有共性的数据集来源/城市内容特点标注情况未标注获取方式Bosch Small Traffic Lights德国1280x720车载图像灯体极小经典小目标测试集标注图像大约一千多张官方原始视频序列中有大量未标注帧需申请LISA Traffic Light美国加州包含白天/夜晚、圆形灯/箭头灯/行人灯等多种类型场景丰富帧级标注覆盖约上万帧官方提供原始视频标注稀疏可提取未标注帧DriveU Traffic Light德国城市道路多段城市道路视频标注较稀疏适合抽未标注帧关键帧标注不是每一帧都有框完整的视频流可以按帧抽取LaRa Traffic Light法国巴黎带GPS和时间戳同步的视频序列多路口、多灯型视频由标注帧和大量无标注帧组成原始视频流S2TLD丹麦包含合成数据和真实数据做“合成→真实”域适应常用合成域有大量标注真实域部分标注真实域视频可提炼未标注样本BDD100K美国/其他大而全的自动驾驶数据集交通灯只是其中一类有交通灯标注但标注密度不高官方原始视频可自行抽帧注意非商业许可如果你只想要一个起点我建议优先看Bosch和LISA。Bosch的未标注帧里都是典型的德国窄路口场景LISA的视频里有很多美国大路口和夜晚红灯反光的情况风格差异大正好用来测试模型跨场景能力。2.2 为什么很多标注数据集的“未标注帧”被低估大多数视频型标注数据集标注人员不是逐帧打框的。比如一段30秒的路口视频可能每隔10帧才标一帧或者只在信号灯状态改变的关键帧上打框。这意味着官方发布的数据包里面天然就躺着大量“没有标签但画质正常”的视频帧。很多人在数据集页面只看到“有标注”三个字就直接把这个来源忽略了。我自己常用的一个做法是下载官方原始视频序列用它提供的标注JSON/XML反查被标注的帧ID然后把没有被标注的帧全部导出来。这样得到的未标注数据和标注数据完全同源画质、相机视角、路口类型都一致做预训练或者伪标签非常合适。这就是很多人忽略掉的一块数据金矿。2.3 关于版权与许可下载前先搞清楚先说结论做学术实验和写论文基本没问题但商用一定要谨慎。这些数据集大部分是“仅供研究用途”的具体条款每个页面都不同。有些要求你用学校或企业邮箱单独申请有些允许直接下载但是禁止二次分发。你的模型如果只是内部验证一般问题不大如果要做成产品卖给客户建议把许可条款发给法务过一遍。顺带解释两个热词里常有人问的许可证含义。Apache License 2.0允许商用、允许修改和再分发保留版权声明即可对专利有明确授权是目前最友好的协议之一。GPL-2.0允许商用和修改但衍生作品必须以相同许可证开源有“传染性”如果你的项目是闭源产品引用GPL代码要非常小心。至于“Apache 2.0/GPL-2.0的数据集”这种说法要看它约束的是代码还是数据本身很多数据集页面写的是“数据集使用CC BY-NC 4.0”这类知识共享协议属于另一套体系不能和软件许可证混为一谈。3. 三条路径获取未标注交通灯数据3.1 从现有标注数据集中剥离未标注帧这是成本最低的方式。以DriveU这类带视频的数据集为例标注文件里通常会写明每一帧的编号或者时间戳。你只需要写个小脚本把标注过的帧从视频里挑出去剩下的帧全部导出为图片。关键代码思路大致是这样import cv2 import json # 假设标注文件里记录了所有被标注帧的 frame_id 列表 with open(annotations.json, r) as f: annos json.load(f) labeled_frames {item[frame_id] for item in annos[frames]} video_path raw_video.mp4 save_dir unlabeled_frames/ cap cv2.VideoCapture(video_path) fps cap.get(cv2.CAP_PROP_FPS) frame_id 0 while True: ret, frame cap.read() if not ret: break if frame_id not in labeled_frames: # 每间隔3帧保存一次避免连续冗余 if frame_id % 3 0: cv2.imwrite(f{save_dir}/{frame_id:06d}.jpg, frame) frame_id 1 cap.release()实际操作中有两个细节。一是帧ID和时间戳对不上的问题有的数据集标注里写的是视频时间比如3.24秒你抽样的时候要用frame_id int(time * fps)换算要注意四舍五入的误差。二是抽帧间隔我建议先全量抽到内存里看一眼画面重复率再决定要不要跳帧。城市道路视频在等红灯时前几十帧几乎一模一样全部保留只会拖慢后续清洗速度。3.2 行车记录仪自采低成本扩场景自己采数据看着原始其实是最能补足公开数据集短板的方式。公开数据集主要集中在德国、美国、丹麦、法国这几个地方国内的路口形态、信号灯位置、倒计时样式它们覆盖得很差。你如果最终要部署到国内项目自采数据几乎是必经之路。采集设备不一定要多贵行车记录仪完全够用。我建议注意下面几点安装角度记录仪稍微往上仰一点保证画面里能看到路口上方的信号灯杆而不是只拍前车屁股。分辨率至少2K因为交通灯在画面里占比太小1080P拍出来后期裁切会很不舒服。路线规划尽量覆盖十字路口、T型路口、带倒计时牌的路口、多车道宽路面、夜间街道路口。另外最好把不同时段的数据分开存放方便以后按场景评测。拍摄时长不用一次拍一小时每一段5到10分钟就够关键是路口类型要多、光线条件要杂。隐私问题公共道路拍摄要遵守当地规定。真正落地发布前建议对清晰可见的车牌和人脸做模糊处理。这个可以用现成的检测模型自动处理不用人工一个个盖马赛克。3.3 官方原始数据/未标注子集除了上面的数据集的标注包有一部分数据集的官方页面还提供了“raw data”下载这些原始视频里没有任何标签文件专供做自监督和无监督研究的。申请这类数据时我建议直接发邮件给发布方的研究组正文写清楚三件事你是谁、用在什么项目上、是否需要商用授权。大多数情况下学术用途的申请都能通过。注意有些页面下载之后要等人工审核不要反复刷注册耐心等就行。4. 未标注数据的工程化处理抽帧、清洗与存储4.1 抽帧不能无脑均匀抽拿到一段路口的视频很多人第一反应是“每秒抽一帧”。这在车辆快速通过路口时没问题但一旦遇到红灯停车队列前车刹车灯亮着不动连续几十帧画面几乎相同。把这些帧全部送进训练集会造成严重的重复样本问题模型会在重复的车尾和信号灯上过拟合。我推荐一个做法时间抽帧加运动量筛选。先用每3秒一帧的节奏粗抽一遍然后计算相邻帧之间的像素差异。我用的是朴素但有效的方案缩放到32x32的灰度图后计算平均绝对误差MAEimport cv2 import numpy as np def frame_diff(a, b): a_small cv2.resize(cv2.cvtColor(a, cv2.COLOR_BGR2GRAY), (32, 32)) b_small cv2.resize(cv2.cvtColor(b, cv2.COLOR_BGR2GRAY), (32, 32)) return np.mean(np.abs(a_small.astype(int) - b_small.astype(int))) # 如果相邻帧差异小于 2.0就认为画面基本静止跳过这一帧这个阈值不一定对所有视频通用我的经验是0.5到3.0之间都正常你可以先看几组统计值再定。对于等红灯场景差异通常会低于1.0车辆正常通过路口时差异值往往在5.0以上所以阈值设2.0左右比较平衡。4.2 清洗把没用的帧挑出来丢掉抽完帧之后未标注数据集里会有明显的一批“垃圾帧”不处理直接进训练流程就是浪费资源。第一类是模糊帧。夜间或者车辆颠簸时画面整体模糊模型学不到任何有效特征。可以用拉普拉斯方差做检测对灰度图做拉普拉斯变换然后计算方差。方差很低说明图像边缘太少也就是模糊。具体阈值和分辨率强相关1280x720的图我一般以80到120为界低于这个值就删掉。第二类是过暗/过曝帧。统计灰度直方图如果纯黑像素占比超过30%说明画面基本是夜里的死黑状态如果纯白像素占比很高说明是迎着太阳拍的车前盖反光。这两种帧对训练没有正面贡献。第三类是完全没有信号灯的帧。这个最消耗时间我的做法是先用一个现成的交通灯检测模型把所有帧都过一遍只保留检测到灯体、或者置信度处在模糊区域的帧其他的直接丢进“无效样本目录”备用。这块顺便说一下“数据质量”这件事。最近总有人讨论高质量数据集评测规范我的理解是对检测任务来说所谓高质量不一定是标注有多精细而是有效样本占比高、场景覆盖广、噪声类别少。未标注数据的清洗本质上就是在做第一层质量筛选。4.3 目录组织和格式预留清洗完之后不要随手把图片扔进一个大文件夹后面训练的时候会后悔。我习惯从一开始就按下面这种结构组织dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── raw/ │ └── unlabeled/ └── scripts/未标注图片在还没有标签之前先统一放在raw/unlabeled/下面。等伪标签生成完毕再按YOLO格式移动到images/和labels/对应的训练集目录。这样做的原因是YOLO系列的训练流程默认是“图片目录 标签目录”配对扫描如果图片和标签数量对不上或者目录里混着没标签的图片训练时会报错或者直接忽略。提前把目录结构规划好后面转COCO、转VOC都会方便很多。顺便提一句“BDD100K转YOLO”这类问题其实所有带标注的数据集最终都要落到统一的中间格式上。不要迷信某种格式本身核心是维护一个“图片路径 类别 归一化坐标”的清单格式只是这个清单的外皮。5. 未标注数据怎么做进训练流程5.1 自监督预训练路线如果你完全没有任何现成的交通灯模型那伪标签这条路暂时走不通。这时候可以先走自监督预训练。思路很简单用清洗好的几千张未标注交通灯图做一轮对比学习或者掩码重建预训练让骨干网络学会提取路口图像的特征。常见框架比如SimCLR、MAE、DINO随便挑一个能跑通的就行。不过我要提个醒交通灯是小目标全局自监督预训练时模型很容易只关注到车辆和路面的主体特征灯体实在太小了。我实测下来的改善办法是先把图像里包含信号灯的区域裁成小块用这些小块图像做自监督预训练然后再把backbone权重拿回去用完整图像微调检测头。这样预训练阶段看到的就是灯体本身而不是整张路口大图。5.2 伪标签 半监督迭代性价比最高的路线这是我最推荐的一条路。条件是你手里已经有一个效果还过得去的交通灯检测模型哪怕只是在公开数据集上训练的也没关系。整体流程是把未标注图片批量推理一遍拿到所有框、类别和置信度。按置信度把结果分成三档高置信度比如0.8以上直接作为伪标签中置信度0.5~0.8放进候选池等人工抽检后决定要不要用低置信度0.5以下直接丢弃。把高质量的伪标签数据和已有的真标注数据混合重新训练模型。重复一轮每轮之后模型对目标场景的理解都会更好。用YOLOv8做这一步非常顺手推理时直接保存txt标签from ultralytics import YOLO model YOLO(traffic_light_baseline.pt) results model.predict( sourcedataset/raw/unlabeled/, imgsz960, conf0.5, save_txtTrue, save_confTrue, projectpseudo_labels, )跑完之后pseudo_labels/labels/下每个图片都对应一个txt文件里面是YOLO格式的类别、中心点、宽高、置信度。再用一个脚本把置信度低于0.8的标签删掉剩下的就是可用的伪标签。我踩过最大的坑是伪标签里的类别分布会失衡。比如模型对绿灯检测得特别好伪标签里就全是绿灯黄灯几乎没有。如果你发现这种情况要按类别做抽样保证每类数量别差太远否则训练完的模型会偏向于把其他灯也判成绿灯。另外伪标签框的边缘通常不如人工标注干净训练时建议在标签上加一点轻微抖动比如坐标随机偏移1到2个像素可以略微提升框回归的稳定性。5.3 域适应与场景扩充如果你的目标是把模型从公开数据集场景迁移到特定城市、特定硬件上域适应路线也值得考虑。不展开讲对抗训练这些复杂公式只说一个非常实用的变种用目标场景的未标注数据做“自训练”。先用源域模型在目标域未标注视频上推理筛选出高置信度的结果然后把这些带伪标签的目标域数据和源域标注数据混合重新训练。这和5.2的流程很像区别是这里更强调“目标域数据比例”的调节。我实测下来目标域数据占比在30%到60%之间效果最好太少没效果太多会让模型逐渐忘记源域里见过的复杂情况。6. 常见问题与避坑实录6.1 抽出来的帧大量重复怎么办表现是训练集统计下来明明有5000张图实际互相去重之后可能只有1500张的有效信息。重复不仅浪费算力还会让验证指标看起来虚高。解决办法是上一章说的运动量筛选再加上pHash感知哈希去重。对每张图计算一个64位哈希值两两比较汉明距离小于5就视为近似重复保留其中一张。这个步骤在几千张图上跑起来很快值得加进流程里。6.2 视频里根本没有信号灯的帧太多如果采集路线经过很多没有信号灯的路段粗筛阶段会发现一半以上的帧都检测不到灯。不用慌先用现成模型过一遍把完全没有检测框的帧直接挪走。注意这里别把“置信度低的帧”也一起删了低置信度帧往往是你的模型在目标场景下漏检的候选难例留着对后续迭代有帮助。6.3 伪标签的置信度阈值到底设多少我见过有人直接设0.9结果拿到的伪标签数量太少有人设0.3结果错框一堆训练之后模型反而变差了。建议分档处理而不是一刀切。我通常把高置信度设在0.8中置信度在0.5~0.8低置信度区间直接丢。高置信度伪标签也要按一定比例混入不是越多越好我一般控制在总标签量的30%以下。中置信度样本留着每轮抽检200到300张人工快速确认一下这样能让迭代更稳。6.4 小目标漏检、误检严重怎么办YOLOv8默认640输入对交通灯这种小目标很吃亏。我在自采数据上训练时会把输入分辨率提到960推理时候再切图tiling也就是把大图切成几个有重叠的小块分别推理。切图重叠率至少20%防止正好把一个信号灯切成两半。另外评估指标一定要分小目标看除了mAP0.5和mAP0.5:0.95我习惯单独统计面积小于32x32像素的灯的AP很多模型整体mAP看着不错小目标AP其实很差只有单独统计才能暴露问题。6.5 开源许可证和数据集版权怎么避坑这里再强调一遍代码库的Apache 2.0/GPL-2.0许可证和数据文件本身的许可协议是两回事。数据集的页面往往单独写了“reserved for non-commercial research use”“custom license”这类字样。哪怕是GPL代码配合的数据数据本身也不自动变成GPL。做商用项目之前把这些许可落到文档里存档别等项目交付了再来补授权那时候非常被动。6.6 要不要把未标注数据全部重新人工标注成本上不建议。真实场景里交通灯类别少、目标特征集中伪标签的可靠性比通用目标检测高不少。如果你一定要人工复核我建议用主动学习的思路只挑模型置信度中等、灯体过小、或者被遮挡严重的难例来标这样同样的标注预算能把模型短板补得更准。7. 一套可以直接抄的落地节奏伪标签YOLOv8为例最后给你一套我最近跑过的完整节奏适合手里已经有几百张标注数据、想快速扩充场景的情况。第一步收集未标注数据。从公开数据集剥离未标注帧或者用车载记录仪拍原始视频目标先定在5000到10000张有效画面上。第二步抽帧清洗去重。按3.1和4.1的方法处理筛掉模糊、过暗、重复帧最后大概还剩3000到5000张“值得进训练流程”的图。第三步生成伪标签。用已经训练好的交通灯模型推理保存YOLO格式标签。命令我在5.2给过了唯一要注意的是输入分辨率设到960别用小分辨率跑。第四步双阈值过滤和抽检。高置信度0.8以上直接保留中置信度0.5到0.8先保留清单。随机抽200张伪标签可视化出来人工看一眼重点看有没有把红灯误检成车辆尾灯、把倒计时LED误检成信号灯的情况。第五步混合训练。原始标注数据作为基础伪标签数据按30%左右比例混入YOLOv8训练时图片尺寸设960训练轮次150左右早停和学习率参数可以按默认来。第六步按场景细分评估。在验证集上分别统计白天、夜晚、逆光、远距离四类场景的AP看伪标签到底提升了哪个部分。我自己跑下来假标签带来的提升主要来自“环境多样性”而不是简单的数据量增加。夜间AP如果还是上不去大概率是伪标签里夜景样本本身太黑、标注质量差这时候别继续加数据先去想办法补亮一点的夜间样本。最后分享一个经验整个流程跑第一轮的时候别急着加更多数据先把这一轮数据清洗、伪标签过滤、训练和评估闭环走通。等你看到“加了未标注数据之后小目标AP确实有提升”再扩大规模也不迟。交通灯检测的数据工程本质上是一个反复迭代收敛的过程先小后大、先稳后扩是省时间的关键。本文还有配套的精品资源点击获取
返回列表