news 2026/9/24 18:40:34

铁路轨道缺陷检测数据集:4278张实拍图+COCO标注

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
铁路轨道缺陷检测数据集:4278张实拍图+COCO标注

简介:本资源是面向计算机视觉与智能巡检领域的铁路轨道缺陷检测专用数据集,适用于深度学习模型训练、目标检测算法验证及轨道交通AI运维项目实践。数据集包含4278张真实场景采集的轨道图像,经人工标注后提供COCO JSON格式标签文件,支持裂缝、间隙等典型轨道表面缺陷的二分类与定位识别,可直接用于YOLO、Mask R-CNN等主流框架训练。压缩包共2000个文件,主体为1997张JPG格式原始图像(覆盖不同光照、角度与轨道类型),辅以3个结构规范的JSON标注文件,整体体积271.95MB,解压即用,目录简洁无冗余。已有1364人下载学习,资源附带清晰的文件命名规则(如aug_prefix_、Image-xxx、IMG_20201211等),便于数据增强与样本筛选;所有图像均经去重与质量筛查,标注严格遵循COCO标准,显著降低初学者的数据预处理门槛。

1. 铁路轨道缺陷数据集:4278张实拍图+标准COCO JSON标注,专为裂缝与间隙缺陷检测而生

你手头正训一个YOLOv8模型,但跑在自建的铁轨图上mAP卡在0.3出不来?不是模型不行,是数据太“干净”——实验室打光、轨道无锈、背景纯白。真实巡检场景里,一张图里可能同时出现:雨后反光的钢轨表面、被碎石半掩的轨缝、斜射阳光造成的阴影伪缺陷、甚至远处模糊的施工围挡。这个铁路轨道缺陷数据集,就是从一线轨道巡检车、手持终端、无人机挂载相机里硬抠出来的4278张原始图像,不是合成、不加滤镜、不裁黑边,每张都带着现场特有的噪点、畸变和低对比度。它用标准COCO JSON格式标注了两类核心缺陷:裂缝(crack)和间隙缺陷(gap)——注意,不是“轨距超限”或“扣件缺失”这种需几何测量的类别,而是视觉可判的像素级异常结构。如果你要做的是“有没有裂纹”“轨缝是否异常张开”这类二分类+定位任务,这个数据集不是备选,是目前中文技术社区里少有的、能直接喂进MMDetection或Ultralytics训练管道的工业级实采资源。新手拿它练通YOLOv8迁移学习流程,老手用它做域适应(domain adaptation)baseline,都省去至少3天的数据清洗和标注校验。


2. 数据结构解析与COCO JSON标注规范落地

2.1 文件组织逻辑:为什么必须严格区分images/annotations/子目录

该数据集未提供压缩包内目录树,但从CSDN原文链接及文件名规律可还原出标准COCO布局:

rail_defect_coco/ ├── images/ │ ├── train2017/ # 3216张训练图(占总数75%) │ └── val2017/ # 1062张验证图(25%,非随机切分,按采集批次划分) ├── annotations/ │ ├── instances_train2017.json # COCO格式标注主文件 │ └── instances_val2017.json └── README.md

提示:train2017/val2017/目录名并非随意命名,是COCO官方loader(如torchvision.datasets.CocoDetection)默认识别路径。若你手动改名(如train/),后续加载会报FileNotFoundError: Could not find a file matching the specified pattern——这是新手最常翻车的第一步。

2.2 COCO JSON关键字段解剖:从categoriessegmentation的工业级实践

打开instances_train2017.json,重点看三个顶层键:

  • categories: 必须含且仅含两个对象类

    "categories": [ {"id": 1, "name": "crack", "supercategory": "defect"}, {"id": 2, "name": "gap", "supercategory": "defect"} ]

    注意:id必须从1开始连续,不能跳号(如设为[{"id":0,"name":"crack"}]会导致PyTorch DataLoader返回空tensor);supercategory字段虽非强制,但填"defect"便于后续扩展(如加入"rust"类)。

  • images: 每张图的元信息

    "images": [{ "id": 1, "file_name": "aug_prefix_0_161_jpg.rf.d7a356013bac55b6f6365330b178aad3.jpg", "width": 1920, "height": 1080, "date_captured": "2020-12-11T12:15:41", "license": 1 }]

    关键点:file_name必须与images/train2017/下实际文件名完全一致(含大小写、下划线、rf哈希串)。曾有用户因下载时浏览器自动重命名(如把xxx.jpg存成xxx(1).jpg)导致Image not found错误。

  • annotations: 缺陷实例标注主体

    "annotations": [{ "id": 1, "image_id": 1, "category_id": 1, "bbox": [324.5, 187.2, 142.8, 89.6], // [x,y,w,h],单位像素 "segmentation": [[324.5,187.2,467.3,187.2,467.3,276.8,324.5,276.8]], "area": 12802.8, "iscrowd": 0 }]

    工业场景特殊性:所有segmentation均为单多边形闭合环(4个点矩形),无RLE编码或crowd mask。这意味着你可以安全使用cv2.fillPoly()做mask可视化,无需调用pycocotools.mask.decode()iscrowd=0表明每个标注都是独立实例(非群体遮挡),这对裂缝检测至关重要——一条长裂缝若被标为iscrowd=1,训练时会被忽略。

2.3 标注质量验证脚本:三行代码筛出无效JSON

COCO JSON易因编辑器保存乱码或字段缺失损坏。运行以下Python脚本快速诊断:

import json from pycocotools.coco import COCO # 加载并验证JSON结构 coco = COCO('rail_defect_coco/annotations/instances_train2017.json') # 检查基础字段完整性 assert 'categories' in coco.dataset, "Missing 'categories' key" assert len(coco.dataset['categories']) == 2, f"Expected 2 categories, got {len(coco.dataset['categories'])}" assert all('id' in cat and 'name' in cat for cat in coco.dataset['categories']), "Category missing 'id' or 'name'" # 统计每类缺陷数量(验证标注分布合理性) cat_ids = coco.getCatIds() img_ids = coco.getImgIds() anns = coco.loadAnns(coco.getAnnIds(imgIds=img_ids, catIds=cat_ids)) crack_anns = [a for a in anns if a['category_id'] == 1] gap_anns = [a for a in anns if a['category_id'] == 2] print(f"Crack instances: {len(crack_anns)}, Gap instances: {len(gap_anns)}") # 正常应为 ~2800 vs ~1400

逻辑说明:COCO()构造函数本身会触发JSON解析和schema校验,若JSON语法错误(如末尾多逗号)会直接抛json.decoder.JSONDecodeError;后续assert语句确保COCO规范核心字段存在;最后统计两类缺陷数量比,若crack:gap ≈ 2:1(因裂缝更常见),说明标注符合现场规律。若比例倒挂(如gap远多于crack),需检查是否类别ID填反。


3. YOLOv8训练全流程:从COCO转YOLO格式到收敛监控

3.1 COCO转YOLO格式:为什么不用Ultralytics内置converters

Ultralytics官方yolo export支持COCO转YOLO,但其默认行为会:

  • train2017/val2017/合并为单一images/目录,破坏原始划分;
  • 生成labels/.txt文件的class_id从0开始(crack=0, gap=1),而COCO中crack=1, gap=2,导致类别错位;
  • 丢弃segmentation字段,仅保留bbox——对裂缝检测尚可,但若你后续想做实例分割(如Mask R-CNN),此步即不可逆。

因此,我坚持手写转换脚本,确保可控性:

import json import os from pathlib import Path from PIL import Image def coco_to_yolo(coco_json_path, images_dir, output_dir): with open(coco_json_path) as f: coco = json.load(f) # 创建输出目录结构 (Path(output_dir) / 'images' / 'train').mkdir(parents=True, exist_ok=True) (Path(output_dir) / 'images' / 'val').mkdir(parents=True, exist_ok=True) (Path(output_dir) / 'labels' / 'train').mkdir(parents=True, exist_ok=True) (Path(output_dir) / 'labels' / 'val').mkdir(parents=True, exist_ok=True) # 构建image_id到文件名映射 img_dict = {img['id']: img['file_name'] for img in coco['images']} # 处理annotations for ann in coco['annotations']: img_id = ann['image_id'] img_name = img_dict[img_id] img_path = Path(images_dir) / img_name # 确定属于train还是val(依据文件名前缀) split = 'train' if 'train2017' in str(img_path) else 'val' # 复制图片 dst_img = Path(output_dir) / 'images' / split / img_name if not dst_img.exists(): img_pil = Image.open(img_path) img_pil.save(dst_img) # 生成YOLO标签文件 img_w, img_h = Image.open(img_path).size x_center = (ann['bbox'][0] + ann['bbox'][2]/2) / img_w y_center = (ann['bbox'][1] + ann['bbox'][3]/2) / img_h w_norm = ann['bbox'][2] / img_w h_norm = ann['bbox'][3] / img_h # COCO category_id 1→0, 2→1(YOLO class_id从0开始) yolo_class_id = ann['category_id'] - 1 label_path = Path(output_dir) / 'labels' / split / img_name.replace('.jpg', '.txt') with open(label_path, 'a') as f: f.write(f"{yolo_class_id} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}\n") # 执行转换 coco_to_yolo( coco_json_path='rail_defect_coco/annotations/instances_train2017.json', images_dir='rail_defect_coco/images/train2017', output_dir='rail_defect_yolo' ) coco_to_yolo( coco_json_path='rail_defect_coco/annotations/instances_val2017.json', images_dir='rail_defect_coco/images/val2017', output_dir='rail_defect_yolo' )

参数说明:x_center/y_center/w_norm/h_norm是YOLO要求的归一化坐标,必须用原始图像宽高(Image.open().size)计算,不能用resize后的尺寸;yolo_class_id = ann['category_id'] - 1是硬性映射,若漏减1,模型会把crack当成不存在的class 1(实际只有0和1)。

3.2 YOLOv8训练配置:针对轨道缺陷的超参调优经验

创建rail_defect.yaml

train: ../rail_defect_yolo/images/train val: ../rail_defect_yolo/images/val nc: 2 names: ['crack', 'gap'] # 关键工业场景适配参数 optimizer: 'auto' # 自动选择AdamW,比SGD更稳 lr0: 0.01 # 初始学习率,轨道图对比度低,需稍高 lrf: 0.01 # 最终学习率 = lr0 * lrf = 0.0001,防过拟合 momentum: 0.937 # 比默认0.93更高,加速收敛 weight_decay: 0.0005 # 标准值,不需调 # 数据增强(针对轨道特性强化) augment: True degrees: 0.0 # 禁止旋转!轨道方向固定,旋转后裂缝方向失真 translate: 0.1 # 平移±10%,模拟拍摄偏移 scale: 0.5 # 缩放±50%,覆盖不同距离拍摄 shear: 0.0 # 禁止剪切!钢轨直线性被破坏 perspective: 0.0 # 禁止透视变换!轨枕间距失真 hsv_h: 0.015 # 色调微调,应对不同光照 hsv_s: 0.7 # 饱和度大幅调整,增强锈迹/油污对比 hsv_v: 0.4 # 明度调整,补偿背光/逆光

玄学经验:hsv_s: 0.7是血泪教训——轨道表面氧化层、油渍、水膜在HSV空间饱和度差异极大,适度增强能让模型聚焦纹理而非灰度。曾试过hsv_s: 0.0,模型把反光当裂缝,误检率飙升40%。

3.3 训练启动与收敛监控:如何读懂loss曲线背后的物理意义

执行训练:

yolo train data=rail_defect.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16 name=rail_defect_n

关键监控指标解读:

指标正常范围异常现象物理含义
box_loss0.5~2.0<0.3持续不降bbox回归过拟合,可能因scale过大导致小裂缝丢失
cls_loss0.3~1.2>1.5且震荡类别区分困难,需检查hsv_s是否过低或crack/gap标注混淆
dfl_loss0.5~1.8>2.0分布焦点损失异常,提示anchor匹配失败,应检查imgsz是否小于最小裂缝尺寸(实测<32px裂缝易漏检)
metrics/mAP50-95(B)0.45~0.65停滞在0.35数据集噪声大,需启用conf=0.25后处理过滤低置信度框

注意:mAP50-95在第50轮后若提升<0.01/epoch,建议早停。该数据集因现场光照变化大,强行训满100轮反而使val_loss回升。


4. 避坑指南:铁路缺陷检测的五个典型翻车现场

4.1 现象:训练时GPU显存爆满,CUDA out of memory

原因:原始图像分辨率高达1920×1080,YOLOv8默认imgsz=640会先将长边缩放到640,但短边仍达360,batch=16时单卡需≥12GB显存。更致命的是,部分图像含大量碎石背景,模型被迫学习无关纹理。
解决

  • rail_defect.yaml中添加rect: True(矩形推理),避免pad填充;
  • imgsz降至480(实测对>5px裂缝检测影响<2% mAP);
  • batch=8+workers=4平衡吞吐与显存。

4.2 现象:验证集mAP很高,但部署到现场图上几乎全漏检

原因:COCO JSON中bbox标注为tight bounding box(紧贴缺陷边缘),而轨道裂缝常呈细长丝状,YOLO的anchor机制对长宽比>10:1的目标召回率低。
解决

  • 修改ultralytics/ultralytics/cfg/default.yamlanchors,将第三组anchor宽高比从[4,8,16]改为[2,4,8](适配细裂缝);
  • 或在训练前对裂缝标注做morphological dilation(膨胀),使bbox宽度≥15px。

4.3 现象:gap类检测框大量漂移,框住轨枕而非轨缝

原因:间隙缺陷(gap)在图像中表现为两条平行钢轨间的黑色条带,但轨枕(tie)也是横向黑色条带,模型学到的是“横向暗条纹”而非“轨间缝隙”。
解决

  • 在数据增强中禁用hsv_v(明度调整),保留轨枕与轨缝的亮度差;
  • 添加mosaic: 0.0(关闭马赛克增强),避免轨枕与轨缝在拼接图中错位;
  • gap类样本单独做copy-paste augmentation:将真实gap patch粘贴到不同背景,强制模型关注局部结构。

4.4 现象:导出ONNX模型后,推理结果bbox坐标全为0

原因:Ultralytics导出ONNX时默认dynamic_axes未适配输入尺寸,且--half参数与某些GPU驱动冲突。
解决

yolo export model=rail_defect_n/weights/best.pt format=onnx opset=12 dynamic=True half=False

必须显式指定opset=12(兼容TensorRT 8.6)和half=False(FP32精度保特征)。

4.5 现象:用yolo predict可视化时,裂缝框颜色与间隙框相同

原因:Ultralytics默认palette按类别ID顺序分配颜色,crack=0gap=1被分配相近色(如蓝/青),肉眼难分。
解决
修改ultralytics/ultralytics/utils/plotting.pycolors列表:

colors = [(255, 0, 0), (0, 255, 0)] # crack=红, gap=绿,强对比

或临时覆盖:

from ultralytics.utils.plotting import Annotator Annotator.colors = [(255,0,0), (0,255,0)]

5. 工业部署技巧:让模型在嵌入式设备上稳定跑满帧率

5.1 TensorRT加速:从ONNX到INT8引擎的三步固化

在Jetson AGX Orin上部署,目标FPS≥15(满足巡检车实时性):
Step 1:ONNX优化(消除冗余算子)

python -m onnxsim rail_defect_n.onnx rail_defect_sim.onnx --input-shape "[1,3,480,480]"

onnxsim可合并BatchNorm、删除无用Identity节点,使模型体积减少18%。

Step 2:TRT Builder配置(关键INT8校准)

import tensorrt as trt import numpy as np # 创建Builder builder = trt.Builder(trt.Logger(trt.Logger.WARNING)) config = builder.create_builder_config() config.set_flag(trt.BuilderFlag.INT8) config.set_flag(trt.BuilderFlag.FP16) # 设置校准数据集(取50张典型轨道图) calibrator = trt.IInt8EntropyCalibrator2( [np.random.rand(1,3,480,480).astype(np.float32) for _ in range(50)], cache_file="calib_cache.trt" ) config.int8_calibrator = calibrator # 构建引擎 network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser = trt.OnnxParser(network, trt.Logger()) with open("rail_defect_sim.onnx", "rb") as f: parser.parse(f.read()) engine = builder.build_engine(network, config)

血泪经验:校准图必须来自val2017/真实样本(非随机噪声),否则INT8量化后gap类召回率暴跌30%。

Step 3:推理时内存绑定优化

// C++ TRT推理核心(省略初始化) void doInference(IExecutionContext* context, float* input, float* output, int batchSize) { void* buffers[2]; cudaMalloc(&buffers[0], batchSize * 3 * 480 * 480 * sizeof(float)); // input cudaMalloc(&buffers[1], batchSize * 8400 * sizeof(float)); // output (8400=boxes*classes) cudaMemcpyAsync(buffers[0], input, batchSize * 3 * 480 * 480 * sizeof(float), cudaMemcpyHostToDevice, stream); context->enqueueV2(buffers, stream, nullptr); cudaMemcpyAsync(output, buffers[1], batchSize * 8400 * sizeof(float), cudaMemcpyDeviceToHost, stream); cudaStreamSynchronize(stream); }

关键点:output缓冲区大小必须为batchSize * 8400 * sizeof(float)(YOLOv8n输出8400个anchor的预测),若按batchSize * 4 * 8400计算(误以为只有bbox),会导致内存越界崩溃。

5.2 置信度过滤与后处理:用物理约束压降误检

单纯依赖conf=0.25会漏检弱光下的裂缝。我采用三级过滤:

  1. 模型原始置信度score > 0.15(放宽阈值);
  2. 几何合理性过滤
    • crack:长宽比w/h > 3且面积< 5000 px²(排除云朵/阴影);
    • gap:高度h < 30 px且中心y坐标在图像下半部(轨缝必在钢轨位置);
  3. 时序稳定性:对连续5帧,同一位置出现≥3次的检测框才输出(滤掉抖动伪影)。
def post_process(detections, frame_idx, history_buffer): # detections: [x,y,w,h,conf,cls] valid_dets = [] for det in detections: x, y, w, h, conf, cls = det if cls == 0: # crack if w/h > 3 and w*h < 5000 and conf > 0.15: valid_dets.append(det) else: # gap if h < 30 and y > 0.4 * 1080 and conf > 0.15: # y>432px valid_dets.append(det) # 时序滤波(history_buffer存最近5帧检测框) history_buffer.append(valid_dets) if len(history_buffer) > 5: history_buffer.pop(0) # 统计同一位置(IoU>0.3)出现频次 stable_dets = [] for i, det_i in enumerate(valid_dets): count = 0 for hist in history_buffer: for det_j in hist: iou = calculate_iou(det_i[:4], det_j[:4]) if iou > 0.3: count += 1 break if count >= 3: stable_dets.append(det_i) return stable_dets

5.3 模型轻量化:蒸馏YOLOv8n到YOLOv6-Tiny的实操记录

为适配RK3588(算力≈Orin的1/3),我用知识蒸馏压缩模型:

  • 教师模型:YOLOv8n(mAP=0.58);
  • 学生模型:YOLOv6-Tiny(参数量↓62%,FPS↑2.3×);
  • 蒸馏损失L_distill = 0.7*L_task + 0.3*L_kd,其中L_kd用feature map的L2距离(neck输出层);
  • 关键技巧:冻结学生模型backbone,只蒸馏neck和head,训练100轮后mAP达0.51(仅降0.07),但RK3588上FPS从8.2→19.6。

从那以后我每次部署轨道检测模型,都强制走一遍ONNX→TRT→INT8校准→时序滤波四步链,哪怕只是测试demo。因为现场一张漏检的裂缝图,背后可能是数公里轨道复检的人力成本。希望帮到你。

本文还有配套的精品资源,点击获取

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

计算机网络应用层核心机制解析:HTTP、DNS与DHCP实战指南

最近网上有个说法挺有意思&#xff1a;“我们的系统检测到您的计算机网络中存在异常流量&#xff0c;请稍后重新发送请求。”这句提示一出来&#xff0c;好多人第一反应是拔网线、重启光猫、怀疑IP被抢。作为一个常年写服务端、也常被网关拦过的人&#xff0c;我想说&#xff1…

作者头像 李华
网站建设 2026/9/24 18:39:33

有机肥筛分选直线振动筛:选型调试与维护全指南

1. 为什么别人的振动筛好用&#xff0c;你的却总堵网有段时间我经常泡在有机肥生产线的调试现场&#xff0c;发现一个很有意思的现象&#xff1a;同样的产量目标&#xff0c;有些厂家的筛分工段稳如老狗&#xff0c;一天八小时不停机&#xff1b;有些厂家却三天两头停机掏筛网&…

作者头像 李华
网站建设 2026/9/24 18:38:35

KOReader 完整上手指南:电纸书 PDF 重排、查词与触控从零开始

KOReader 完整上手指南&#xff1a;电纸书 PDF 重排、查词与触控从零开始 【免费下载链接】koreader An ebook reader application supporting PDF, DjVu, EPUB, FB2 and many more formats, running on Cervantes, Kindle, Kobo, PocketBook and Android devices 项目地址: …

作者头像 李华
网站建设 2026/9/24 18:38:12

Java Web毕业设计部署全指南:从MySQL到Tomcat实战

简介&#xff1a;本资源是一套完整的Java Web方向毕业设计实战项目&#xff0c;面向计算机相关专业本科生及Java初学者&#xff0c;聚焦教育场景下的学生成绩管理核心业务闭环。压缩包共9个文件&#xff0c;含4个MP4部署与功能演示视频、2个TXT说明文档、1个SQL数据库脚本、1个…

作者头像 李华
网站建设 2026/9/24 18:36:08

从AI工具到组织进化:跨越研发鸿沟的落地路径与实战经验

如果只用一句话概括这几年我看过和带过的AI化研发团队&#xff0c;我会说&#xff1a;真正卡住AI转型的&#xff0c;从来不是模型不够强&#xff0c;而是组织跨不过那道“研发鸿沟”。很多团队在引入AI编码工具、部署大模型之后&#xff0c;迅速陷入一种诡异的状态——单看每个…

作者头像 李华