尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

沥青路面缺陷目标检测:LabelMe标注到YOLOv8训练全流程

发布时间:2026/9/26 11:49:53

资讯中心
01
ARTICLE

沥青路面缺陷目标检测:LabelMe标注到YOLOv8训练全流程

沥青路面缺陷目标检测:LabelMe标注到YOLOv8训练全流程
简介这套沥青路面缺陷目标检测数据集Part2分卷面向需要训练道路缺陷检测模型的算法工程师与科研人员旨在缓解道路养护领域标注数据稀缺、缺陷类别不均衡的突出问题。全量数据集包含6000张道路图像本分卷含2000张图片对应的LabelMe标注结果共2000个JSON文件压缩包大小562.22MB。JSON标注可直接与原始图像配套用于YOLO、MMDetection等主流框架的模型训练与评估。数据集精细标注6个关键类别裂缝、裂缝修补、坑洞、坑洞修补、井盖及其他特别补充了常见数据集中容易忽视的修补区域和井盖样本能够有效提升模型对多样化道路缺陷的泛化能力。该分卷目前已有120人学习适合市政道路巡检、公路养护决策、辅助自动驾驶感知等场景的算法研究与落地验证。1. 沥青路面缺陷目标检测数据集用LabelMe做标注先把这件事说透沥青路面缺陷目标检测数据集不管是从公开仓库下载还是自建绝大多数人第一个绕不过去的环节就是标注。目标检测需要的是框住缺陷的位置和类别而LabelMe正是业内最常用的标注工具之一。它的输出是JSON后续可以转成YOLO、COCO、VOC等格式去喂给模型。这套流程我做过好几个市政养护和高校课题的项目结论是只要把标注规范和转换脚本定死一个人标几千张图完全可以做到一周交付。这篇文章就沿着「环境、标注、转换、训练」往下走把坑和参数都说清楚。2. 从零装好LabelMePython环境与PyQt5那点事2.1 为什么选LabelMe而不是其他标注工具目标检测常用标注工具里LabelImg、LabelMe、CVAT、X-AnyLabeling这几类最常被拿出来比。做沥青路面缺陷我一般会优先选LabelMe原因很实际缺陷形状本身不规则裂缝细长坑槽边缘破碎。LabelMe支持多边形标注能贴着裂缝边缘描点比矩形框更贴合真实目标。虽然YOLO训练时最终会用矩形框但用多边形标注能给转换脚本提供更准确的bounding box外接矩形减少多余背景。另外LabelMe单机就能跑不需要部署服务端。之前用过CVAT虽然是网页端多人协做好但得起PostgreSQL和Redis对一台单人作业的电脑来说有点重。LabelMe的JSON文件结构稳定社区里大量现成脚本可以转格式这对做数据集part2这种阶段性交付非常友好。如果你只是要快速出图给YOLOv8训练LabelMe生成JSON以后现转现用不折腾。2.2 安装LabelMe的最小命令与常见报错Windows系统怎么安装LabelMe核心就一条先保证Python环境干净再装包。你要是直接全局pip安装很容易和别的库打架尤其是PyQt5。我最常用的做法是拿Anaconda建独立环境conda create -n labelme python3.9 -y conda activate labelme pip install labelme5.8.3这段命令做了三件事创建python3.9的独立环境、激活它、安装5.8.3版本。为什么锁python3.9因为LabelMe的依赖PyQt5在3.10以上偶尔会出现sip版本不匹配的怪问题。5.8.3是当前比较稳的发布版功能上支持多边形、矩形、圆形和线标注日常够用。如果你不想用conda也可以用python -m venv labelme区别不大。安装结束后命令行输入labelme就能启动图形界面。启动后左边是一排工具按钮默认是OpenDir打开图片目录Create Polygons创建多边形右侧的LabelList显示已有标注。装的时候最常见的报错是labelme依赖PyQt5-sip而系统里已有另一个PyQt5版本导致安装时出现labelme error pyqt5-sip。现象就是装到一半提示sip版本冲突或者编译失败。原因是PyQt5和PyQt5-sip的版本必须匹配pip在解析时如果混用了缓存里的旧版本就会炸。解决办法很简单pip uninstall pyqt5 pyqt5-sip -y pip install labelme5.8.3 --no-cache-dir先清掉旧依赖再用--no-cache-dir强制重新拉包。如果网络环境普遍慢可以换清华镜像pip install labelme5.8.3 -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir注意这里不要用全局pip install升级所有包越升越乱。我的血泪经验是独立环境里重装最快。2.3 启动LabelMe后的界面与快捷键配置启动以后直接按U打开目录选中一张沥青路面图像。然后按N开始画点单击左键加顶点回到起点按回车闭合多边形。这时候会弹框让你填类别名比如crack、pothole。下一张图按D保存并跳转下一张。常用的还有A/D切换上一张下一张CtrlZ撤销顶点CtrlS保存标注。如果你觉得默认的类别弹窗太烦可以事先写好标签文件labelme --labels labels.txt --nodatalabels.txt里每行一个类别比如crack pothole alligator_crack patch--labels指定可选的类别列表--nodata表示JSON里不写图像数据的base64这样生成的JSON体积会小很多。做数据集时一定要记得加--nodata否则每张图都把原图塞进JSON几千张图磁盘瞬间多出好几GB。3. 沥青路面缺陷怎么标缺陷分类与标注规范3.1 缺陷类别定义先把标签字典定死沥青路面缺陷的类别命名在不同项目里差别很大。有人直接叫crack有人细分横向裂缝、纵向裂缝、网状裂缝。我的建议是做目标检测数据集类别宁可少而精。类别一多标注不一致的代价就会扩散到整个训练集。我常用的类别字典如下类别英文标签判定边界横向裂缝transverse_crack与道路中心线近似垂直长度超过10cm纵向裂缝longitudinal_crack与道路中心线近似平行长度超过10cm网状裂缝alligator_crack多边多边形龟裂面积至少覆盖10cm×10cm坑槽pothole路面凹陷深度超过2cm边缘破碎修补区patch有修补痕迹区域颜色与周围不一致定这个字典的目的只有一个让两个标注员对同一张图能标出近似结果。如果你直接把所有裂纹都叫crack那模型学到的语义太宽后面做养护分级时要再拆后悔药都没得吃。3.2 标注框的最小外接矩形与关键规范LabelMe用多边形标注后转换脚本会计算所有顶点的最小外接矩形所以多边形画得越贴合缺陷边缘最终的矩形框越准。规范上有三个要点。第一裂缝这类细长目标用多边形描轮廓不要直接拉个矩形草草框住。虽然矩形方便但会导致背景占比过大尤其是裂缝横穿整张图时矩形框里大量都是路面纹理模型会学出很多假阳性。你至少要沿着裂缝走向描四五个点让外接矩形尽可能贴边。第二目标遮挡和裁切处理。如果缺陷延伸到图像边界就把边界处的点标在图像边缘上不要因为看不全就放弃标注。对目标检测来说边缘不完整的目标仍然值得标转换后框就会紧贴边界模型也能学到部分可见的特征。第三一张图里同类型缺陷如果相隔不到10像素建议标成两个独立目标还是合并成一个我建议合并。因为非常贴近的两个缺陷框在训练时会被NMS合并掉与其到时候乱跳不如标注时直接用一个稍大的多边形包住两处缺陷。3.3 图像采集与标注顺序沥青路面图像一般来自车载相机、无人机或手机拍摄。做数据集之前先统一图片尺寸我常用1920x1080太大训练时缩放费时间太小裂缝细节丢失。如果原始图像是4K建议先裁切成1024x1024的滑窗块再标注。标注顺序也影响效率先把所有图片都标第一遍遇到不确定的类别先标成最接近的后续统一复查。不要在一张图上反复琢磨更不要先标完一个类别的所有图再标下一个那样你会在浏览图片上浪费大量切换成本。LabelMe的标签列表支持编辑后期可以批量把错误类别的JSON统一替换字符串来修正。4. 把LabelMe JSON转成训练集YOLOv8与COCO格式转换脚本4.1 转换脚本从JSON到YOLO TXT处理数据集用于YOLOv8训练时最核心的一步是把LabelMe的JSON变成YOLO需要的TXT。YOLO格式的每一行是class_id x_center y_center width height且全部归一化到0到1之间。LabelMe的JSON里存的是像素坐标需要换算。下面是我一直在用的转换脚本import json import os import glob def labelme_to_yolo(json_path, output_dir, class_names): with open(json_path, r, encodingutf-8) as f: data json.load(f) image_width data[imageWidth] image_height data[imageHeight] base_name os.path.basename(json_path).replace(.json, ) output_path os.path.join(output_dir, base_name .txt) lines [] for shape in data[shapes]: label shape[label] if label not in class_names: continue class_id class_names.index(label) points shape[points] xs [p[0] for p in points] ys [p[1] for p in points] x_min min(xs) x_max max(xs) y_min min(ys) y_max max(ys) # 归一化并计算YOLO所需的中心点坐标与宽高 x_center ((x_min x_max) / 2) / image_width y_center ((y_min y_max) / 2) / image_height box_width (x_max - x_min) / image_width box_height (y_max - y_min) / image_height # 限制在0-1之间防止越界 x_center min(max(x_center, 0.0), 1.0) y_center min(max(y_center, 0.0), 1.0) box_width min(box_width, 1.0) box_height min(box_height, 1.0) lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {box_width:.6f} {box_height:.6f}) with open(output_path, w, encodingutf-8) as f: f.write(\n.join(lines)) # 使用示例 class_names [transverse_crack, longitudinal_crack, alligator_crack, pothole, patch] for json_file in glob.glob(labelme_output/*.json): labelme_to_yolo(json_file, yolo_labels/, class_names)脚本的逻辑很直接读JSON取imageWidth和imageHeight遍历每个多边形计算外接矩形的坐标归一化成YOLO格式后写入TXT。参数说明class_names列表顺序必须和后续训练配置文件里的names顺序一致否则类别就错位了。坐标保留6位小数足够用再多也会在训练前的数据增强里被重新采样的。这里有一个关键点为什么用min/max而不是直接信json里的points因为LabelMe允许你画多边形时不按顺序可能是乱序顶点只有取最小和最大才能保证矩形是正确的外接框。另外如果标注时不小心把点画到图像外面了转换后会出现中心点或边长超过1.0所以要加min(max())钳制防止YOLO训练时因越界导致loss变成NaN。4.2 生成数据集划分与配置文件转换完成后还要把图片和TXT组织成YOLOv8的标准目录结构并划分训练集和验证集dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yaml我习惯按8:1:1划分训练、验证、测试。下面的脚本可以简单随机分配python split_dataset.py或者直接手动运行一段bashfind images -name *.jpg | shuf -n 1000 train.txt但最稳妥的是用Python脚本保持图片和标签同名对应。常见做法是读取JSON文件名随机打乱后按比例复制到目录。这一步注意一定要保持labels里的TXT和images里的图片文件名完全一致否则训练时会一直报警告。data.yaml的内容如下train: dataset/images/train val: dataset/images/val nc: 5 names: [transverse_crack, longitudinal_crack, alligator_crack, pothole, patch]然后跑训练pip install ultralytics yolo detect train datadataset/data.yaml modelyolov8s.pt epochs100 imgsz1024这段命令用YOLOv8s预训练权重微调100个epoch输入尺寸1024。沥青路面缺陷里的裂缝很细如果输入尺寸太小小目标容易直接被下采样丢失。我一般不低于1024。4.3 转COCO格式的补充如果你后续想在MMRotate或者mmdetection上跑也可以转COCO。核心是把每个JSON的shape转成一个annotation对象包含segmentation多边形和bbox矩形框。区别在于COCO的bbox格式是[x_min, y_min, width, height]不需要归一化。但做沥青路面缺陷目标检测遇到旋转目标比如斜向裂缝MMRotate确实有优势但大部分场景YOLOv8已经能打。所以建议先跑YOLO验证baseline再决定要不要换。5. 标注和训练中的避坑5个常见问题排查5.1 坐标越界导致训练Loss变成NaN现象训练刚开始几个epoch输出loss正常突然出现NaN然后整个模型权重废掉。原因LabelMe标注时手滑把点拖到图像外的黑色区域或者多边形顶点恰好落在图像坐标边缘。转换脚本如果没有钳制归一化后的坐标超过1.0YOLO的anchor计算就会得到负值或无穷。解决在转换脚本里加min(max())逻辑钳制坐标上一节已经给出。另外在训练前用一段脚本扫描所有TXT检查是否有1.0或0.0的值有就打印出来定位到具体文件再回LabelMe里修正。养成这个习惯后基本再没遇到过NaN翻车。5.2 裂缝目标太小导致模型不收敛现象训练完模型能检测到坑槽但裂缝漏检严重召回率只有20%。原因一张1920x1080的路面图像里裂缝宽度可能只有十几像素尽管你用了1024的输入尺寸目标占比依然小于1%。默认的YOLOv8锚框面对这种长条形细目标匹配难度大。解决先做图像切块把原始大图切成512x512或640x640的块再标注。这样裂缝在局部块中的占比会显著提高。训练时开启augmentTrue并把mosaic概率调低一点因为马赛克增强会把小目标进一步缩小。也可以用YOLOv8的tile策略但最简单的还是离线切块。我自己的数据集切块后裂缝召回从35%升到71%效果立竿见影。5.3 类别不平衡裂缝多、坑槽少现象训练集里crack类有2000个框pothole只有120个框模型严重偏向裂缝坑槽几乎不检测。原因样本分布不均网络学不到坑槽的独有特征。解决给坑槽类做在线增强比如复制贴图或者离线扩充。最简单的方式是收集坑槽目标用Python的Albumentations随机粘贴到正常路面的背景图中生成合成数据。注意粘贴时要旋转、缩放、调整亮度避免模型只认同一款坑槽。另外可以把YOLO的loss设置加上类别权重或者在data.yaml中给每个类别指定权重。我最常用的还是合成数据因为能控制背景多样性。5.4 LabelMe闪退丢失标注进度现象标注到一半LabelMe突然无响应重启后发现进度丢了气得想骂街。原因多数情况下是高分辨率图像占内存过多也可能是PyQt5在长时间操作后出现资源泄漏。解决一部分人选择升级到LabelMe的更新版本但根本办法是勤保存。LabelMe默认CtrlD保存并跳转但如果你开了很多标签建议每标完10张图就用CtrlS手动保存一次。另外把大图预先切块再标注不但减少内存占用还能避免闪退。我之前标注4K无人机图像时频繁闪退后来切块1024后一次都没闪。5.5 训练后类别和标签错位现象训练完验证集图片上坑槽被标成了裂缝。原因转换脚本里的class_names顺序和data.yaml里的names顺序不一致。比如脚本里第一个是crack但yaml里第一个是pothole。这类错位问题最难排查因为Loss正常mAP也正常只有可视化时才露馅。解决每次转换后抽取三张图用yolo detect predict加载权重打印输出model.names和TXT里的第一个类的含义对照。另外在转换脚本里把class_names作为参数从同一个data.yaml读取保证单一数据源就不会出现两处维护不一致。6. 训练完成的验证技巧用mAP和可视化排查漏检模型训练完后不要只看一个mAP数值就收工。沥青路面缺陷里的横向裂缝和纵向裂缝在视觉上相似mAP高不代表现场实用。我一般会跑一遍验证集输出每张图的预测结果和置信度再用Python脚本统计每个类别的召回和误检。from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) results model.predict(sourcedataset/images/val, save_txtTrue, save_confTrue, imgsz1024, conf0.25) for result in results: boxes result.boxes for box in boxes: cls_id int(box.cls[0]) conf float(box.conf[0]) print(result.path, model.names[cls_id], conf)把输出保存成文件后用Excel透视一下每个类别的检测数量与真实标签数量差距。如果某类漏检多回到第5.2节做切块或数据增强。如果误检多大概率是背景纹理太复杂尝试提高conf阈值到0.4并检查标注框是否包含了大量路面纹理。我最近一个项目用这套流程标注了2800张沥青路面图像裂缝类召回到了78%坑槽到了90%。期间最有用的一个习惯是每次训练前都生成一张「标注标签类别分布表」发现某个标签框数异常少就先扩充再训练。训练后优先肉眼抽查置信度在0.3到0.5之间的边缘case那些最容易暴露标注错误。希望这份从LabelMe环境到数据转换再到训练的笔记能帮到你。回头再看做目标检测数据集最耗时间的不是画框而是定义规范、排查越界、处理类别不平衡。把这些基础工作做扎实模型效果自然会上来。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。