资讯详情

黄牌车牌检测数据集:json标签校验与YOLO/COCO转换避坑

📅 2026/10/24 1:50:00 | 华诺云谱 👁 阅读
黄牌车牌检测数据集:json标签校验与YOLO/COCO转换避坑
简介这是一份面向车牌检测与字符识别任务的黄牌图像数据集适合计算机视觉学习者、算法开发者及课程设计、项目实训使用。数据覆盖多种拍摄角度标注采用polygon多边形目标框四个顶点分别对应车牌四角可更贴合倾斜、透视场景下的车牌轮廓为检测模型训练与字符识别预处理提供直接可用的标注基础。所有图片经人工逐张筛选剔除模糊与歧义区域减少后续清洗成本。压缩包共9324个文件其中4627张jpg、35张jpeg图像与4662个json标注文件整体约257.79MB图像与标签一一对应便于按目录组织训练集和验证集。已有890人学习下载。对需要矩形框json格式的读者作者也提供转换支持无论是做黄牌检测、车牌定位还是字符识别流程验证都能从中获得较完整的图像与标注素材。1. 黄牌车牌检测数据集不是“有框就行”json标签先决定上限某开发者拿一批黄牌车牌检测数据集做园区门口抓拍训练损失降得很顺推理时却总把黄色广告牌、收费亭反光条框成车牌。翻到数据层才发现json标签里的框是中心点加宽高转换脚本却按左上右下读模型学的是一套偏移框。这个资源就是带json标签的黄牌车牌检测数据集落在图像识别流程里负责车牌识别之前的定位环节适合卡口、停车场、园区门口这类黄牌车较多的场景也适合想练json转YOLO、COCO标注口径的人。黄牌颜色是先验不是标签json字段没读透训练越久偏得越远。下面从字段校验开始把能复现的步骤和翻车点拆开。2. 把json标签读透字段探测、坐标校验与黄牌样本分布2.1 先做字段探测不要上来就硬编码键名json标签最怕“看起来一样”。同样叫bbox有的存[x_min, y_min, x_max, y_max]有的存[x, y, w, h]还有的存归一化后的中心点宽高。黄牌车牌检测数据集如果来自不同标注批次字段名和层级都可能变。我一般不会先写转换脚本而是先跑一个字段探测把一份json里所有键路径打印出来确认图像路径、宽高、标注列表、框字段、类别字段分别在哪一层。import json from pathlib import Path def walk_keys(obj, prefix): 递归打印json键路径列表只采样前3个元素避免大文件卡住 if isinstance(obj, dict): for k, v in obj.items(): yield prefix k, v yield from walk_keys(v, prefix k .) elif isinstance(obj, list): for i, v in enumerate(obj[:3]): yield from walk_keys(v, prefix f[{i}].) json_path Path(labels/one_sample.json) data json.loads(json_path.read_text(encodingutf-8)) for key, value in walk_keys(data): # 只打印键路径和值类型不打印整段base64或大数组 print(f{key} - {type(value).__name__})这段代码只做一件事把嵌套结构摊平。walk_keys对字典逐层拼路径对列表只取前三个元素因为标注文件里objects或annotations可能很长全量递归会拖慢排查。prefix用来保留层级比如objects.[0].bbox能直接看出框在标注对象里而不是在顶层。实际使用时先拿一份样本跑确认键路径后再写批量脚本。常见字段命名可以对照下表但不要把它当标准。表里只是排查方向最终以实际json为准。信息类型常见键名要确认的点图像路径imagePath、image_path、file_name是相对路径还是绝对路径根目录在哪图像宽高width、height、imageWidth与真实读图尺寸是否一致标注列表objects、annotations、shapes是列表还是按类别分组的字典框坐标bbox、points、box是四个数还是两个点是否归一化类别label、category、class_name大小写、中英文、是否有空格提示字段探测阶段不要急着改json先把原始键路径和值类型记录下来。后面转换脚本报错时这份记录就是后悔药。2.2 坐标口径与越界检查四个必须落库的校验确认字段后下一步不是直接转YOLO而是做坐标校验。黄牌车牌在图像里通常偏小框偏移几个像素肉眼看不出来但归一化之后会被放大。我一般要求四个校验必须落库坐标数值有限、右下大于左上、框不越界、json宽高与真实读图尺寸一致。前三个决定框能不能用第四个决定归一化分母对不对。import math from PIL import Image def to_xyxy(bbox, fmt, w, h): 把不同口径的框统一成绝对像素xyxy if fmt xyxy: x1, y1, x2, y2 bbox elif fmt xywh: x, y, bw, bh bbox x1, y1, x2, y2 x, y, x bw, y bh elif fmt cxcywh: cx, cy, bw, bh bbox x1, y1, x2, y2 cx - bw / 2, cy - bh / 2, cx bw / 2, cy bh / 2 elif fmt norm_xyxy: x1, y1, x2, y2 bbox[0] * w, bbox[1] * h, bbox[2] * w, bbox[3] * h elif fmt norm_cxcywh: cx, cy, bw, bh bbox x1, y1 (cx - bw / 2) * w, (cy - bh / 2) * h x2, y2 (cx bw / 2) * w, (cy bh / 2) * h else: raise ValueError(f未知坐标口径: {fmt}) return x1, y1, x2, y2 def check_bbox(bbox, fmt, img_path, tol2.0): img Image.open(img_path) w, h img.size x1, y1, x2, y2 to_xyxy(bbox, fmt, w, h) if not all(math.isfinite(v) for v in (x1, y1, x2, y2)): return non_finite if x2 x1 or y2 y1: return invalid_wh # 允许少量越界超过tol像素就记为异常不要静默裁剪 if x1 -tol or y1 -tol or x2 w tol or y2 h tol: return out_of_bound return okto_xyxy把五种常见口径统一成绝对像素左上右下。fmt必须由字段探测确认不能猜。check_bbox里tol2.0是容忍少量像素越界因为标注工具缩放时可能产生1到2像素误差超过这个范围就记异常而不是直接裁剪。裁剪会把错误藏起来后面评估时看不出问题。实际落地时建议把原始框、统一后的框、异常类型一起写进检查表方便回查。如果json里有width和height还要和Image.open(img_path).size比对。差异超过1像素就要查原因是图像被重新缩放后没更新json还是手机拍摄的EXIF方向导致读图尺寸旋转。EXIF问题可以用ImageOps.exif_transpose在读图时统一方向再以旋转后的尺寸为准。2.3 用统计和可视化找“黄牌偏科”黄牌车牌检测数据集容易“偏科”白天多、夜间少近景多、小目标少干净车牌多、泥污遮挡少。只看总框数没意义要看每图框数、框面积占比、宽高比和黄色像素比例的分布。框面积占比能判断小目标比例宽高比能发现异常扁框黄色像素比例能辅助看颜色先验是否稳定但它不是标签不能拿来当训练目标。import numpy as np from PIL import Image from pathlib import Path def yellow_ratio(img_path): 粗略统计黄色像素比例只用于分布检查不参与训练标签 img Image.open(img_path).convert(RGB) arr np.asarray(img).astype(np.float32) / 255.0 r, g, b arr[..., 0], arr[..., 1], arr[..., 2] # 黄色大致满足红绿高、蓝低阈值只用于观察不作为硬规则 mask (r 0.45) (g 0.35) (b 0.45) (r b 0.12) (g b 0.08) return float(mask.mean()) def bbox_area_ratio(bbox, fmt, w, h): x1, y1, x2, y2 to_xyxy(bbox, fmt, w, h) return max(0.0, (x2 - x1) * (y2 - y1)) / (w * h)yellow_ratio用RGB近似黄色阈值写成比例而不是固定0到255方便不同曝光图像比较。bbox_area_ratio算框面积占全图比例输出分位数比看均值可靠。实际排查时把面积占比分成0.1%、0.1%到1%、1%三档看验证集和训练集比例是否接近。如果训练集小目标多、验证集近景多mAP会虚高业务现场却掉点。注意黄色像素比例只适合做分布观察。夜间暖光、泥污、反光条都会让黄色比例失真把它当过滤条件会埋下漏检。2.4 划分训练验证集按场景分组别按文件随机黄牌车牌检测数据集常见连拍同一辆车在同一个门口连续几张文件名只差序号。按文件随机划分训练集和验证集会同时出现同一辆车的相邻帧指标看起来很好换场景就崩。我一般按场景分组目录名、文件名前缀、拍摄点位、时间段任选一个能代表“场景”的键保证同一组只进一个split。from collections import defaultdict from pathlib import Path import random def group_key(json_path: Path): # 按父目录名分组如果文件名前缀更能代表场景可改成 json_path.stem.split(_)[0] return json_path.parent.name json_files sorted(Path(labels).rglob(*.json)) groups defaultdict(list) for p in json_files: groups[group_key(p)].append(p) keys list(groups.keys()) random.Random(42).shuffle(keys) train, val, test [], [], [] for i, k in enumerate(keys): # 7:2:1 按组划分组内文件整体进入同一个split if i % 10 7: train.extend(groups[k]) elif i % 10 9: val.extend(groups[k]) else: test.extend(groups[k])group_key是划分的核心。父目录名通常对应一个拍摄批次或一个场景比文件名随机稳。random.Random(42)固定种子方便复现。i % 10实现7:2:1组数少时可以改成按组大小分层避免某个split没有小目标。划分完要再跑一次统计确认训练集和验证集的框面积分位数、黄色比例分位数没有明显断层。断层太大就先调分组键不要急着训练。3. 从json转到YOLO与COCO转换脚本、参数口径和回读自检3.1 选YOLO还是COCO看训练框架和后续标注回流json标签转格式先定目标格式。YOLO的txt适合单阶段检测训练每行类别 id cx cy w h全部归一化到0到1COCO的json适合多工具协作和标注回流bbox是绝对像素[x, y, w, h]area是面积category_id从1开始更常见。黄牌车牌检测数据集如果只做单类plateYOLO txt最轻如果团队还要用标注平台复标、做数据版本管理COCO json更稳。维度YOLO txtCOCO json坐标口径归一化中心点宽高绝对像素左上宽高类别 id通常从0开始通常从1开始空标签生成空txt表示负样本没有annotation也要有image记录适合场景快速训练、单类检测多工具协作、标注回流易错点归一化分母、类别顺序image_id、category_id、area选型不是技术高低是流程匹配。单类黄牌车牌检测YOLO txt足够如果后续要加颜色分类、车型分类COCO json的扩展字段更从容。转换前把class_map固定下来比如{plate: 0}不要在不同脚本里各写一套。3.2 写一个可复用的json转YOLO脚本转换脚本要处理三件事找到标注列表、统一框口径、把类别名映射成id。未知类别必须报错不能静默跳过否则训练时类别数对不上。空标注也要生成空txtYOLO训练需要负样本。import json from pathlib import Path from PIL import Image CLASS_MAP {plate: 0} # 黄牌数据集单类时固定为0多类时在这里统一顺序 def iter_objects(data): 兼容 objects / annotations / shapes 三种常见标注列表 for key in (objects, annotations, shapes): value data.get(key) if isinstance(value, list): return value return [] def pick_bbox(obj): for key in (bbox, box, points): if key in obj: return obj[key] raise KeyError(f找不到框字段: {obj.keys()}) def pick_label(obj): for key in (label, category, class_name, name): if key in obj: return str(obj[key]).strip() raise KeyError(f找不到类别字段: {obj.keys()}) def convert_one(json_path, img_path, out_txt, fmtxyxy): data json.loads(Path(json_path).read_text(encodingutf-8)) w, h Image.open(img_path).size lines [] for obj in iter_objects(data): label pick_label(obj) if label not in CLASS_MAP: raise ValueError(f未知类别 {label}先补 CLASS_MAP) x1, y1, x2, y2 to_xyxy(pick_bbox(obj), fmt, w, h) # 归一化并保留6位小数减少txt体积 cx (x1 x2) / 2 / w cy (y1 y2) / 2 / h bw (x2 - x1) / w bh (y2 - y1) / h lines.append(f{CLASS_MAP[label]} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) Path(out_txt).write_text(\n.join(lines), encodingutf-8)iter_objects按常见键名找标注列表找到第一个列表就返回避免同一份json里多个字段重复。pick_bbox和pick_label把字段差异收敛到两个函数后面换数据集只改这里。CLASS_MAP必须显式定义未知类别直接抛错这是血泪经验静默跳过会让某类样本在训练集里消失评估时才发现召回上不去。fmt要和字段探测结果一致传错就是框整体偏移。空标注时lines为空仍然写出空txt负样本才有记录。提示转换前先用一份样本打印前5个框的原始值和转换后的归一化值肉眼确认中心点落在车牌上再跑批量。3.3 转COCO时最容易错的两个字段COCO json有两个字段最容易翻车image_id和category_id。image_id是图像记录的唯一整数annotation里的image_id必须和images里的id一致category_id通常从1开始YOLO习惯从0开始直接混用会让类别错位。bbox写绝对像素[x, y, w, h]area写w * h不要写归一化值。coco { images: [], annotations: [], categories: [{id: 1, name: plate}], } ann_id 1 for image_id, (json_path, img_path) in enumerate(pairs, start1): w, h Image.open(img_path).size coco[images].append({id: image_id, file_name: str(img_path), width: w, height: h}) data json.loads(Path(json_path).read_text(encodingutf-8)) for obj in iter_objects(data): x1, y1, x2, y2 to_xyxy(pick_bbox(obj), fmt, w, h) bw, bh x2 - x1, y2 - y1 coco[annotations].append({ id: ann_id, image_id: image_id, # 必须等于 images 里的 id category_id: 1, # 与 categories 里的 id 对齐 bbox: [x1, y1, bw, bh], # 绝对像素不是归一化 area: bw * bh, iscrowd: 0, }) ann_id 1这段代码里image_id用enumerate生成保证唯一category_id固定1和categories一致。bbox是[x1, y1, bw, bh]不是[x1, y1, x2, y2]这是COCO和YOLO最大的口径差。area用于评估时区分小中大目标黄牌车牌大多落在小目标区间area写错会影响分层指标。iscrowd0表示普通实例黄牌检测一般不用crowd标注。3.4 转换后回读自检三类断言转换脚本跑完不等于正确。我一般做三类断言每张图有对应txt、每行五列且类别id在集合内、反算像素框与原始json框的IoU大于0.999。IoU断言能抓住中心点宽高和左上右下混用的问题比肉眼看几张图可靠。def yolo_to_xyxy(line, w, h): cls_id, cx, cy, bw, bh line.split() cx, cy, bw, bh map(float, (cx, cy, bw, bh)) x1 (cx - bw / 2) * w y1 (cy - bh / 2) * h x2 (cx bw / 2) * w y2 (cy bh / 2) * h return int(cls_id), x1, y1, x2, y2 def iou(a, b): ax1, ay1, ax2, ay2 a bx1, by1, bx2, by2 b ix1, iy1 max(ax1, bx1), max(ay1, by1) ix2, iy2 min(ax2, bx2), min(ay2, by2) iw, ih max(0.0, ix2 - ix1), max(0.0, iy2 - iy1) inter iw * ih union (ax2 - ax1) * (ay2 - ay1) (bx2 - bx1) * (by2 - by1) - inter return inter / union if union 0 else 0.0回读时对每张图读原始json框和txt反算框逐框算IoU。阈值设0.999因为只差浮点舍入低于这个值就打印原始框、反算框和fmt十有八九是口径传错。类别id也要断言在set(CLASS_MAP.values())里防止把plate写成Plate后映射失败。空txt要允许存在但要在检查表里标记为负样本不要当成转换失败。4. 黄牌检测训练基线配置、增强边界与误检分析4.1 单类检测还是多类检测先定标签语义黄牌车牌检测数据集先定标签语义。如果json里只有plate就做单类检测输出一个框颜色信息交给后处理或单独分类器。如果json里明确分了yellow_plate、blue_plate可以保留多类但类别顺序必须和CLASS_MAP一致。不要因为图像是黄牌就把颜色塞进类别名除非标注本身这么定义。单类的好处是减少类间混淆黄牌颜色先验在推理阶段做二次校验更灵活。单类训练时names只写0: plate评估只看一类AP。多类训练时每个类别都要有足够样本否则小类别会把整体mAP拉低。黄牌场景里如果混入少量蓝牌负样本可以把蓝牌车牌标成背景不框或者单独加一类取决于业务要不要拒绝蓝牌。标签语义定不下来后面转换、训练、评估都会反复。4.2 基线训练配置与黄牌小目标参数基线配置先跑通不要一上来堆增强。黄牌车牌在卡口图里往往只占几十像素imgsz比模型大小更关键。我一般从960起步显存不够再降batch按显存调lr0用常规值patience留早停。数据配置文件只写路径和类别不写花哨参数。path: /data/plate_yellow train: images/train val: images/val names: 0: plateyolo detect train \ datadata.yaml \ model预训练权重 \ imgsz960 \ epochs100 \ batch16 \ lr00.01 \ patience20 \ workers8 \ projectruns/plate \ nameyellow_baselinepath是数据集根目录train和val写相对路径避免换机器后失效。imgsz960是为了保住小目标细节黄牌车牌在640下可能只剩十几个像素。batch16不是固定值显存不够就降到8同时按比例调lr0。patience20表示验证指标20轮不升就停省时间。workers8按CPU核数调太高反而拖慢数据加载。第一次训练先关掉强增强确认loss正常下降再加。增强参数要克制。马赛克增强会把多张图拼在一起小目标可能被切碎黄牌颜色对HSV增强敏感色相扰动过大可能把黄色推到橙色。常见做法是先把马赛克关小或关掉随机缩放范围不要压得太狠HSV的饱和度和明度扰动保留色相扰动调低。具体值看验证集不要照搬。参数基线建议调整理由imgsz960起黄牌车牌小分辨率比模型深度更直接batch显存允许的最大值小目标梯度噪声大batch太小不稳定lr00.01附近预训练权重微调过大容易震荡mosaic先低后高小目标被切碎后反而学不到完整车牌hsv_h调低黄色色相范围窄扰动过大改变颜色语义patience20到30小目标指标波动大早停太早会误杀注意验证集指标不升不一定是模型不行先回看标注框是否偏移、验证集是否和训练集同场景。数据层的问题调参救不回来。4.3 评估指标怎么看mAP之外还要看召回分层评估命令把置信度阈值压低先看PR曲线全貌再定业务阈值。黄牌检测不能只看mAP50小目标多的时候mAP50-95会明显低这是正常现象。要看召回按框面积分层小框召回够不够夜间子集召回掉多少误检集中在什么背景。yolo detect val \ modelruns/plate/yellow_baseline/weights/best.pt \ datadata.yaml \ imgsz960 \ conf0.001 \ iou0.6conf0.001是为了让PR曲线覆盖低置信度区间评估阶段不怕框多怕漏。iou0.6是NMS和匹配的常用值黄牌车牌框比较规整0.5到0.6都可以试。看结果时先看召回再看精确率。业务现场漏检比误检更麻烦阈值可以偏低误检交给二次校验。指标关注点异常信号mAP50框大致重合时的综合表现高但现场漏检查验证集泄漏mAP50-95高IoU下的定位精度明显低查小目标和框偏移Precision误检比例低查黄色广告牌、反光条Recall漏检比例低查夜间、遮挡、小目标分层AP按面积/场景拆开小框AP远低于大框调imgsz和增强评估完不要只看一个总分。把验证集按白天/夜间、近景/远景、干净/遮挡拆开分别跑一遍。黄牌车牌检测数据集如果夜间样本少整体mAP会被白天拉高夜间召回可能很难看。拆开看才知道下一步是补数据还是调增强。4.4 误检分析黄色先验不能当硬规则黄牌检测的误检经常来自黄色物体广告牌、反光条、收费亭、工程车车身。颜色先验可以做二次校验但不能在检测前硬过滤。硬过滤会把夜间暖光下的黄牌、泥污车牌、偏色图像直接删掉漏检比误检更难补。我一般把检测框裁出来统计框内黄色像素比例看误检和真检的分布是否可分再决定阈值。import numpy as np from PIL import Image def crop_yellow_ratio(img_path, xyxy): img Image.open(img_path).convert(RGB) x1, y1, x2, y2 map(int, xyxy) crop np.asarray(img.crop((x1, y1, x2, y2))).astype(np.float32) / 255.0 if crop.size 0: return 0.0 r, g, b crop[..., 0], crop[..., 1], crop[..., 2] mask (r 0.45) (g 0.35) (b 0.45) (r b 0.12) (g b 0.08) return float(mask.mean())这个函数只做统计不直接过滤。把真检和误检的黄色比例分别画分布如果真检集中在高分段、误检集中在低分段可以设一个保守阈值做二次排序而不是一刀切。阈值取分位数比如保留真检95%召回对应的下限再看误检能压掉多少。夜间和逆光样本要单独看否则阈值会被白天样本带偏。5. 避坑与排查json标签落地时最容易翻车的五件事5.1 框整体偏移中心宽高与左上右下混用现象很典型训练loss正常下降验证集mAP也有零点几但推理框整体往左上或右下偏车牌只框到一半。原因是json里存的是中心点宽高cx, cy, bw, bh转换脚本按左上右下x1, y1, x2, y2读中心点被当成左上角框整体偏移半个宽高。黄牌车牌框本来就小偏一点就掉出车牌。解决不靠肉眼抽查靠回读断言。转换后把txt反算成像素框和原始json框算IoU低于0.999就报错。to_xyxy里把fmt作为必填参数不允许默认值逼着调用方确认口径。批量转换前先拿一份样本打印原始框和反算框确认中心点落在车牌中心。字段探测阶段看到bbox是四个数还不够要看数值范围如果数值都小于1可能是归一化如果宽高明显小于坐标可能是宽高格式。5.2 图像尺寸字段与实际读图不一致现象是归一化后的框整体缩放错位或者同一批数据里部分图正常、部分图偏移。原因是json里的width、height是标注时的尺寸图像后来被重新缩放、裁剪或者手机EXIF方向导致读图尺寸旋转json没同步更新。用json尺寸做归一化分母就会把错误放大到所有框。解决是以真实读图尺寸为准不用json宽高做分母。读图时先做EXIF方向校正再取size。如果json宽高和读图尺寸差异超过1像素记录下来抽样看是缩放还是旋转。批量脚本里不要把json宽高当唯一真值它只能做交叉校验。遇到旋转图先把图像转正再标注或转换不要一边转一边用旧尺寸。from PIL import Image, ImageOps def read_size(img_path): img Image.open(img_path) img ImageOps.exif_transpose(img) # 先按EXIF转正 return img.sizeImageOps.exif_transpose返回转正后的图像size才是视觉上的宽高。黄牌车牌如果横竖方向不一致框的宽高比会异常统计时很容易发现。5.3 训练验证集连拍泄漏导致指标虚高现象是验证集mAP很高换一个门口或换一天就掉得厉害。原因是同一辆车、同一个场景的连拍图被随机分到训练集和验证集模型记住了背景和车牌字符不是学会定位。黄牌车牌检测数据集如果按文件随机划分相邻帧几乎一模一样指标虚高是必然的。解决是按场景分组划分。用目录名、文件名前缀、拍摄点位、时间段做group_key保证同一组只进一个split。划分后检查训练集和验证集的框面积分位数、黄色比例分位数差异大就换分组键。连拍图还可以用感知哈希或文件大小近似去重但不要只靠文件名序号序号可能跨场景重复。5.4 类别名大小写与中英文不一致现象是转换时报未知类别或者训练时类别数对不上评估混淆矩阵里出现空类。原因是json里同一类写成plate、Plate、车牌、车牌CLASS_MAP只写了一个键。静默跳过未知类别会让样本悄悄消失训练集里某类样本变少召回上不去。解决是先统计所有类别名再定映射表。统计时用strip()去空格但不要自动转小写先把原始值列出来人工确认哪些是同一类。CLASS_MAP里未知类别必须抛错不能continue。映射表单独存一份json或csv转换脚本和评估脚本共用避免两处各写一套。from collections import Counter counter Counter() for obj in all_objects: counter[pick_label(obj).strip()] 1 print(counter)Counter输出原始类别名和出现次数先看有没有大小写变体、中英文混写、尾部空格。确认后再写映射比如{plate: 0, Plate: 0, 车牌: 0}但训练时只输出一个id。映射表要版本化后面加类别时先改表再转格式。5.5 颜色阈值硬过滤造成漏检现象是白天效果不错夜间、逆光、泥污车牌漏检明显。原因是在检测前用固定HSV阈值过滤黄色区域夜间暖光把黄牌照成橙色泥污把饱和度拉低阈值一卡就没了。黄牌颜色先验有用但它是统计特征不是硬门禁。解决是把颜色放到检测后做二次校验用分位数定阈值不用固定值。先统计真检框的黄色比例分布取保留95%真检的下限再看误检能压掉多少。夜间样本单独统计阈值可以放宽。检测器主输出仍然保留颜色只做排序或复核不直接删除框。这样即使颜色判断错了还有检测框兜底。6. 进阶用法把黄牌检测接进业务流程的三个技巧6.1 切片推理处理小目标黄牌车牌在广角卡口图里可能只占几十像素整图缩放到960再推理小目标只剩几个像素。我一般用切片推理把原图按重叠窗口切成若干块分别推理后再把框映射回原图坐标做一次NMS。切片大小和重叠率要看车牌像素分布太小会增加误检太大起不到放大作用。常见做法是切片边长取原图短边的三分之一到二分之一重叠20%左右先在一批验证图上比较整图推理和切片推理的小框召回再定参数。切片推理耗时高适合离线复核或重点点位不适合所有帧全量跑。6.2 颜色先验做二次校验而不是硬门禁颜色先验放在检测后用法是给每个框算黄色比例再结合置信度做排序或复核。不要设一个固定阈值直接删框而是看真检和误检的分布重叠区。重叠区大的样本送人工复核重叠区小的按置信度处理。夜间、逆光、泥污单独分组统计阈值分组设置。这样颜色是加分项不是一票否决。黄牌车牌检测数据集的黄牌比例高颜色特征确实有用但业务现场的偏色和遮挡会让固定阈值翻车。6.3 用json回写做人工复核闭环模型跑完不要只保存txt把检测结果回写成和原始json同结构的文件带上图像路径、框、置信度、颜色比例人工复核时直接看json和裁图。复核确认的框再回流到训练集形成闭环。回写时保留原始image_id或文件名不要打乱顺序置信度低和颜色比例处于重叠区的样本优先送审。这样每次复核都在补数据而不是一次性验收。从那以后我每次拿到带json标签的数据集都先把字段探测、坐标校验、回读断言跑一遍再谈训练。黄牌车牌检测数据集的价值不在图像多而在标签口径能不能复现。需要拿这份资源练手时按资源页的获取方式取原始包先跑字段校验和转换自检再开训练别急着上大模型。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑