资讯详情

资讯详情

桥梁裂缝数据集:COCO标注解析、YOLOv8转换与细长目标训练避坑

简介桥梁裂缝缺陷数据集采用COCO标注格式是面向计算机视觉研究者和土木工程检测人员的图像分割数据可用于桥梁裂缝识别、像素级语义分割及智能巡检场景下的模型训练与评估。数据集整体规模约4500张训练图像和200张验证图像当前压缩包共包含2000个文件含1998张jpg原始图像和2个json标注文件压缩包整体大小约557.74MB。jpg图像覆盖不同角度、光照和裂缝形态的桥梁表面json文件遵循COCO标准格式提供对应的目标分割标注信息便于直接接入主流深度学习框架减少数据预处理和格式转换成本。目前已有316人学习下载说明该资源在桥梁病害检测相关研究中具有一定参考价值。借助这份数据可快速搭建裂缝检测或分割实验尤其适合进行数据增强、模型调优、算法复现等实战无论是论文实验、课程设计还是工程项目预研都能获得真实数据支撑。1. 拿到桥梁裂缝缺陷数据集.zip先别急着解压训练干桥梁检测这行的人多多少少都下载过类似“桥梁裂缝缺陷数据集.zip”的东西。打开一看几百张混凝土桥面或桥墩的图片外加一个coco标注格式的 json。很多人第一反应是解压、按 YOLO 的目录结构一股脑塞进去然后坐等训练结果。可实际上这个 zip 里真正值钱的不是图片而是那份 COCO 标注COCO 格式从顶层字段到每个 bbox 的定义都藏着细节稍微读错一点模型练出来的效果就差一大截。这篇笔记从一个常见且具体的 COCO 标注格式数据集出发讲清楚怎么读 json、怎么转成 YOLOv8 能用的 txt、怎么体检数据以及桥梁裂缝这种细长目标特有的踩坑点。适合准备训练裂缝检测模型的工程师和相关专业学生尤其适合被“loss 正常但 mAP 很低”折磨过的人。2. 读懂COCO标注格式json里藏着裂缝的坐标和类别2.1 五个顶层字段先过一遍info/licenses/images/annotations/categoriesCOCO 格式最早来自 COCO2017 数据集后来被大量检测任务沿用。顶层结构固定的五个字段info、licenses、images、annotations、categories。info 描述数据集生产者licenses 是版权声明这两部分对训练没有直接影响可以跳过。真正决定训练质量的是后三个images 列出每张图片的 id、文件名、宽高annotations 存每个缺陷目标的位置、尺寸、所属图片categories 定义类别 id 和名称。拿到 zip 后我从来不做的事是直接解压然后对着目录看图片。我会先把 json 加载进来建好三个索引类别 id 到类别名的映射、图片 id 到文件名的映射、图片 id 到该图片所有标注的映射。这一步看着多余但它是后续所有脚本的地基。import json from collections import defaultdict with open(bridge_crack/annotations/instances_train.json, r, encodingutf-8) as f: anns json.load(f) cat_map {c[id]: c[name] for c in anns[categories]} img_map {img[id]: img[file_name] for img in anns[images]} img_to_anns defaultdict(list) for a in anns[annotations]: img_to_anns[a[image_id]].append(a) print(类别映射:, cat_map) print(图片数量:, len(anns[images])) print(标注数量:, len(anns[annotations]))这段代码做了三件事把 categories 数组转成 id 到名称的字典把 images 数组转成 id 到文件名的字典再把 annotations 按 image_id 聚合。之所以聚合而不是直接遍历是因为后面做类别统计、划分训练验证集时需要频繁按图片取标注每次都遍历全量 json 太慢。注意字段名必须严格写成 image_id、category_id很多第三方数据集会写成 ImageID 或 category_id 混用先用print(list(anns[annotations][0].keys()))看一眼字典键再写逻辑。2.2 images与annotations的id对应关系一张图可以有多个裂缝目标一张桥梁大图上往往同时存在多条裂缝还可能伴随剥落、露筋、蜂窝等缺陷。COCO 用同一 image_id 挂多条 annotation 来表达这种一对多关系。每个 annotation 对象里必填的是 bbox格式是[x, y, width, height]x、y 是目标左上角在图片上的像素坐标width、height 是框宽高。segmentation 字段一般存多边形形式是扁平数组[x1,y1,x2,y2,...]iscrowd 为 0 表示独立目标为 1 表示密集群体。这个环节最常见的问题不是关系搞错而是 bbox 的数值类型和内容异常。我见过不少数据集把 bbox 里的数字存成字符串也见过把[x1,y1,x2,y2]四个角点直接塞进来还有把 width 和 height 写反的。这些异常在 json 里看不太出来但转换时一定会炸。建议在动手前先做一次全量扫描。for a in anns[annotations]: b a[bbox] if len(b) ! 4 or not all(isinstance(v, (int, float)) for v in b): print(异常 bbox, annotation id, a[id], value, b) if b[2] 0 or b[3] 0: print(零面积 bbox, annotation id, a[id])这段代码检查两个点bbox 是否是四个数值以及宽高是否大于 0。裂缝标注里特别容易出现零面积框因为人工标注裂缝时经常只画了一条短线段或者忘了拖拽闭合。零面积框如果不过滤转到 YOLO 格式后会出现除零或负坐标轻则训练 loss 震荡重则直接 NaN。这类行建议直接丢弃后面用统计信息确认丢弃数量占比如果超过 5% 就说明标注质量有问题值得重新评估这个数据集。2.3 categories的写法和验证桥梁裂缝常见的类别标签桥梁裂缝缺陷数据集的类别设计差别很大。简单的单类数据集只有 crack 一类json 里 categories 数组就一个元素。复杂一点的会包含 crack裂缝、spalling剥落、exposed rebar露筋、honeycomb蜂窝、leakage渗水等。类别名的写法也各不相同有纯英文有中文还有crack_001这种带编号的。不管叫什么训练前必须先统计每个类别的目标数和涉及的图片数防止某个类别只在两三张图上有标注。cat_stat defaultdict(int) img_cat_stat defaultdict(set) for a in anns[annotations]: cat_stat[a[category_id]] 1 img_cat_stat[a[category_id]].add(a[image_id]) for cid, name in cat_map.items(): print(f{name}: 目标数 {cat_stat[cid]}, 涉及图片数 {len(img_cat_stat[cid])})这里有两个关键点。第一COCO 的 category_id 不一定从 0 开始常见的有从 1 开始也有从 4 开始的而 YOLO 训练要求类别索引是连续的 0、1、2。所以后面做转换时必须有一步 id 重映射不能把原始 category_id 直接当成 YOLO 类别。第二如果某个类别的涉及图片数只有个位数训练时几乎学不到这个类的特征要么想办法做类别重采样要么干脆放弃这个类把它的标注并到 background 或者相邻类别里。这类决策越早定越好因为会影响整个训练流程设计。提示看到 json 里类别名是中文时不需要慌txt 标注文件本身只存数字索引中文名只影响可视化显示和训练无关。3. 从zip到可训练样本解压、校验与COCO转YOLO格式落地3.1 解压并固定目录结构别让路径问题成为第一个翻车点zip 解压看似简单实际是翻车高发区域。很多人双击解压后发现图片、json、说明文档全堆在同一个目录里连个二级文件夹都没有。更麻烦的是某些数据集 zip 自带一层顶层目录解压后里面又是一个相同的文件夹名导致后续代码路径反复匹配。我一般先用unzip -l查看归档结构再决定解压到哪里。unzip -l bridge_crack_defect_dataset.zip | head -50-l只列出内容不真正解压。拿到文件清单后手动规划成固定结构images 目录放图片annotations 目录放 jsonlabels 目录留空给转换后的 txt。建议所有目录都用英文小写不要带空格和中文。图片文件名字如果带中文也要统一重命名成纯英文和数字否则后续 OpenCV 读取和 Windows/Linux 之间传输会有各种编码问题。解压过程中如果遇到提示需要密码且数据集简介里没有给密码要警惕伪加密。zip 伪加密是文件头把通用位标志的第 0 位加密位置了 1但数据实际没有加密。普通 unzip 会要求输密码输了正确密码也解不开。这种情况可以用 7z 强制解压7z x bridge_crack_defect_dataset.zip -o./bridge_crack -y7z 对伪加密的容忍度比 Info-ZIP 高多数伪加密包用7z x -y直接解出。如果 7z 也卡住那就需要手动修改 zip 的通用位标志这个放到第 5 章的避坑部分展开。解压完成后把 json 文件名改成简单可读的instances_train.json和instances_val.json后面所有脚本统一用这个名字省掉路径里每次拼字符串的麻烦。3.2 写一个coco2yolo转换脚本bbox归一化与txt输出从 COCO 转 YOLO 是训练前必须跨过的一步。YOLOv8 训练自己的数据集时需要每张图片对应一个 txt 文件每行五个值类别索引、中心点 x、中心点 y、宽度、高度前四个坐标都归一化到 0~1。COCO 里 bbox 是左上角加宽高所以转换公式为x_center (x width / 2) / image_widthy_center (y height / 2) / image_heightwidth_norm width / image_widthheight_norm height / image_height这里最大的坑是 COCO 的 x、y 是左上角不是中心点。很多人写着写着就忘了 /2 那一步导致所有框往右下角偏移。我建议把转换写成一个独立函数并且每次跑完都打印几条样例人工对一下。import json import os from pathlib import Path def coco_to_yolo(ann_file, out_dir, cat_id_map): with open(ann_file, r, encodingutf-8) as f: anns json.load(f) img_info {img[id]: img for img in anns[images]} imgs_anns {} for a in anns[annotations]: if a[iscrowd] 1: continue imgs_anns.setdefault(a[image_id], []).append(a) os.makedirs(out_dir, exist_okTrue) written 0 for img_id, targets in imgs_anns.items(): img img_info[img_id] w, h img[width], img[height] lines [] for t in targets: x, y, bw, bh t[bbox] if bw 0 or bh 0: continue if x bw w: bw w - x if y bh h: bh h - y cls cat_id_map[t[category_id]] cx (x bw / 2) / w cy (y bh / 2) / h lines.append(f{cls} {cx:.6f} {cy:.6f} {bw/w:.6f} {bh/h:.6f}) if lines: txt_path Path(out_dir) / (Path(img[file_name]).stem .txt) txt_path.write_text(\n.join(lines) \n, encodingutf-8) written 1 print(f已生成 {written} 个txt文件) cat_id_map {1: 0, 2: 1, 3: 2} coco_to_yolo(bridge_crack/annotations/instances_train.json, bridge_crack/labels/train, cat_id_map)注意几个细节。iscrowd 为 1 的目标在裂缝数据集里极少见但如果存在它是群体目标不适合用单个矩形框表示直接跳过。宽高越界处我做了一次裁剪把超出边界的部分截到图片边缘代替报错因为标注者偶尔会把框拖出画布。cat_id_map 必须根据你的 json 里 categories 定义手动写示例里的{1:0, 2:1, 3:2}是在假设裂缝的 category_id 是 1剥落是 2露筋是 3。如果你的数据集只有一类裂缝就写成{1: 0}。txt 文件名用图片名的 stem也就是去掉后缀的部分这样 YOLO 的 images 目录和 labels 目录能自动对应前提是 labels 目录结构里没多项。3.3 训练集/验证集划分与标注可视化看一遍再进训练如果数据集里已经分好 train 和 val 两份 json这个节可以跳过。但很多桥梁裂缝数据集只给了一份全量 json需要自己划分。划分必须按图片 id 切不能按标注行切。如果按标注行切同一张图片的裂纹可能一半在训练集一半在验证集造成数据泄漏验证时 mAP 虚高一部署就露馅。import random random.seed(42) img_ids list(img_info.keys()) random.shuffle(img_ids) val_n int(len(img_ids) * 0.2) val_ids set(img_ids[:val_n]) train_ids set(img_ids[val_n:]) print(f训练图片: {len(train_ids)}, 验证图片: {len(val_ids)})固定random.seed(42)是为了让每次划分结果一致版本可复现。8:2 的比例对裂缝检测够用因为通常各类别目标数量都不少。真正天然易碎的是某些图片同时包含 train 和 val如果后续删除某些标注时不小心把 image_id 弄乱了这个泄漏问题会重新出现。所以划分完之后我建议把 train_ids 和 val_ids 各保存一个 txt 清单文件方便后续对照。划分结束后先画框可视化。用 OpenCV 把 YOLO 格式的归一化坐标还原回像素坐标随机抽 10~20 张图叠加框人眼核对框是否贴合裂缝。这一步是整个流程里最有性价比的检查能一次性发现 id 错位、坐标颠倒、类别映射错乱等问题。import cv2 def draw_yolo_boxes(img_path, txt_path, out_path): img cv2.imread(img_path) H, W img.shape[:2] for line in open(txt_path): parts line.strip().split() cls, cx, cy, nw, nh map(float, parts) x int((cx - nw / 2) * W) y int((cy - nh / 2) * H) w int(nw * W) h int(nh * H) cv2.rectangle(img, (x, y), (x w, y h), (0, 0, 255), 2) cv2.imwrite(out_path, img)代码里的 x、y 是框左上角所以减去半宽半高。如果画出来的框偏到图片左上角外面说明 cx、cy 写的不是中心坐标而是左上角坐标。如果 h 出现负数说明 nh 转成整数前就小于 0需要回头查归一化是否用了原图宽高。这种可视化脚本我每次转换都会保留它是转换脚本的“后悔药”。4. 训练前的数据体检用YOLOv8跑通前必须确认的三个维度4.1 坐标范围与归一化异常bbox会让你白train一夜直接拿转换后的 txt 塞给 YOLOv8 训练很多人第一晚就能收到 loss 为 NaN 的“惊喜”。最常见原因是坐标归一化后越界cx 或 cy 大于 1width 或 height 为 0还有少量标注读出来是空行。这些异常在训练脚本里往往不报错而是默默变成无意义的梯度导致 loss 曲线一路走高或震荡。我在任何训练任务前都会写一个全量校验脚本扫描所有 txt 文件列出越界行和异常行。from pathlib import Path import numpy as np label_dir Path(bridge_crack/labels/train) all_wh [] invalid [] for txt in label_dir.glob(*.txt): for line in txt.read_text().strip().splitlines(): parts line.split() if len(parts) ! 5: invalid.append((txt.name, line)) continue cls, cx, cy, nw, nh map(float, parts) if not (0 cx 1 and 0 cy 1 and nw 0 and nh 0): invalid.append((txt.name, line)) if cx 0.02 or cx 0.98 or cy 0.02 or cy 0.98: print(f边缘目标: {txt.name} cx{cx:.3f} cy{cy:.3f}) all_wh.append([nw, nh]) all_wh np.array(all_wh) print(f总标注数: {len(all_wh)}, 异常/边缘提示行数: {len(invalid)})这段脚本把两类问题分开完全非法的行格式不对或坐标越界和接近边缘的目标。前者直接拒训后者属于提示因为边缘目标经过随机缩放和裁剪增强后很容易被裁掉一半导致模型学到残缺特征。输出里如果边缘目标占比超过 20%建议在数据增强配置里关闭随机裁剪或者对边缘目标做标注外扩。4.2 细长裂缝的aspect ratio分布决定用不用旋转框桥梁裂缝是目标检测里最特殊的形状之一。一条裂缝的宽度通常只有几个像素到十几个像素长度可达几十像素甚至上百像素长宽比经常超过 10:1。用水平矩形框去框这种目标时框内大部分是混凝土背景模型要花大量容量学习忽略背景才会真正聚焦到裂缝上。所以我会在训练前统计 aspect ratio 分布用第 4.1 节里的all_wh算出每个标注的宽高比ratios all_wh[:, 0] / (all_wh[:, 1] 1e-6) print(f长宽比均值: {ratios.mean():.2f}, 中位数: {np.median(ratios):.2f}) print(f长宽比 10 的标注占比: {(ratios 10).mean() * 100:.1f}%)注意我用宽度除以高度没有固定方向因为横裂缝和竖裂缝在图像里都有。统计结果如果显示长宽比大于 10 的标注占比超过 30%那这个数据集就是典型的细长目标数据集。此时有两个选择一是继续用 YOLOv8 的水平框但需要把输入分辨率从默认 640 提到 1280 甚至 1600让裂缝在特征图上占据足够多的像素二是改用旋转框方案比如 mmrotate 训练 DOTA 数据集那种思路。旋转框能够贴合裂缝走向框内背景面积大幅减少召回率通常能提升 5~10 个点。mmrotate 训练 DOTA 格式数据需要把 COCO 的多边形 segmentation 转成旋转框四参数(cx, cy, w, h, angle)。最常见做法是用 OpenCV 的cv2.minAreaRect求出最小外接旋转矩形import cv2 import numpy as np def seg_to_rbox(seg): pts [(seg[i], seg[i1]) for i in range(0, len(seg), 2)] pts np.array(pts, dtypenp.float32) (cx, cy), (w, h), angle cv2.minAreaRect(pts) return [cx, cy, w, h, angle]cv2.minAreaRect返回的 angle 范围是 [-90, 0)而 mmrotate 各检测器约定的角度定义不一样比如 DOTA 转 le90 格式时通常要处理角度偏移。这里不展开全部换算但提醒一点先用三五个样本算出来 rbox再叠加到图上人工看方向确认角度对了再批量转换。旋转框训练时除了数据集格式还要把 mmrotate 数据配置里的类别数和图片路径改对这个属于现成工具箱的常规操作。4.3 类别不平衡与缺失标注损坏样本的识别失败率高在这桥梁裂缝数据集的类别不平衡比普通目标检测数据集更隐蔽。很多 zip 里标注了大量 crack但 spalling 或者 exposed rebar 可能只有几十个目标。直接用默认 trainer 训练模型会把所有精力放在学习 crack 上少数类基本学不到。这里的损失不只是那个类别的 mAP 低还可能让 crack 类误检率升高——模型会把剥落区域也当成裂缝因为它在训练里没见过足够多的剥落样本。我的处理办法是先量化不平衡程度。统计每个类别的目标数如果某个类别目标数占总目标的 5% 都不到就考虑三类做法一是对该类别做重复采样让每个 epoch 里这个类出现的次数至少是原来的 3 到 5 倍二是放弃该类把它的标注从训练集移除在报告里注明该类未参与训练三是如果只有少数图片有这个类但又必须识别那就先不管只看 crack 单类结果。另一个更隐蔽的问题是缺失标注。桥梁大图里某些区域明显有裂缝但 json 里对应图片没有任何 annotation。这通常不是故意设置的负样本而是人工标注漏标。如果这些图片进入训练集且没有标签模型会把“这里没有裂缝”当成正确答案推理时对类似区域产生漏检。排查很简单import random img_files list(Path(bridge_crack/images/train).glob(*.jpg)) label_files {p.stem for p in Path(bridge_crack/labels/train).glob(*.txt)} neg_samples [p for p in img_files if p.stem not in label_files] print(f无标注图片数量: {len(neg_samples)})无标注图片数量如果小于 1%可以保留作为负样本如果超过 3%我更倾向于把可明确看到缺陷的图拉回标注检查一遍。桥梁巡检场景对误报容忍度极低误报一条裂缝会触发人工复检成本远高于漏检算力成本。所以在数据清洗阶段多花一小时比训练完后悔划算得多。5. 避坑与排查桥梁裂缝COCO数据集使用中的5个高频问题5.1 现象zip解压后json文件打不开或解析失败现象用unzip解压时提示输入密码输入任何密码都报错或者勉强解压后json 文件大小只有几 KB明显是截断的。原因数据集压缩包做了 zip 伪加密通用位标志的第 0 位被置 1但文件实际没有加密内容。普通解压工具检测到加密位后直接跳进密码流程不处理数据。另一种可能是 zip 包带了多层目录解压时 Windows 资源管理器把路径截断导致 json 写入不完整。解决先用 7z 命令行强制解压7z x bridge_crack_defect_dataset.zip -o./bridge_crack -y如果 7z 仍然报错确认是伪加密后用 Python 修改 zip 里每个条目的通用位标志去掉第 0 位然后再解压。具体做法是读取原始 zip 的 central directory逐条把 general purpose bit flag 的 bit 0 清零后重写所有条目。这个操作有一定破坏性建议先复制一份 zip 再动。解压成功后立刻重新压缩一份干净版本后续不再用原始 zip。5.2 现象用pycocotools加载annotations时报b64解码错误现象想用pycocotools做 mAP 评估调用loadRes或loadAnns时抛出base64 decode error。原因pycocotools 内部把 segmentation 当成 RLE 格式解析但桥梁裂缝数据集的 segmentation 存的是多边形坐标或者根本是空字段。COCO 官方物体检测的标注允许 segmentation 为空但 pycocotools 的某些版本在loadAnns时仍然尝试读取遇到空值就抛错。解决不用loadRes直接用 json 手工读取 annotation 列表评估时把多边形补齐成与 bbox 一致的矩形def add_dummy_seg(ann): x, y, w, h ann[bbox] ann[segmentation] [[x, y, xw, y, xw, yh, x, yh]] return ann这样补齐后pycocotools 能算出 box AP但 mask AP 没有意义。裂缝检测工程里我只看 box APmAP 这个指标不区分框和掩膜时要把默认设置改成仅框评估。5.3 现象转换后的txt里出现无数行全0标注现象运行 coco2yolo 脚本后生成的 txt 里大量行的 cx、cy、nw、nh 全部是 0或者 nw 和 nh 为负数。原因大概率把 COCO 的 bbox 格式理解成了[x1, y1, x2, y2]于是计算宽度时变成了x2-x1如果 x2 小于 x1宽度为负数归一化后变成 0。另一种可能是 json 里 bbox 实际存的是[cx, cy, w, h]但转换脚本按左上角处理中心点减半宽后变成负数。解决先打印三条 annotation 原始 bbox 看数值。然后转换脚本里加一条断言assert all(v 0 for v in t[bbox]), fnegative bbox in {t[id]}转换完成后统计所有 txt 里 cx 或 cy 等于 0 的行数。如果一行都没有不代表没问题需要配合可视化确认。全 0 行的另一个来源是 img_info 里的 width/height 字段没读到导致所有除法除数为 0。检查 json 里 images 项如果宽高字段名是 image_width 而不是 width脚本会用到缺省值产生 0。5.4 现象训练时loss正常但mAP始终很低现象loss 曲线平滑下降验证集 mAP 却一直在 0.2 以下徘徊甚至十几个 epoch 不动。原因这个现象在桥梁裂缝数据集上很常见原因有三层。第一类别映射错误比如 COCO 的 crack category_id 是 4但 yolo 的类别索引写成 0 时模型能学到特征却把类别标错mAP 按类计算后接近随机第二训练集和验证集划分时按标注切而非按图片切验证集出现训练过的图mAP 虚高第三裂缝本身细长模型默认输入分辨率下特征太弱。解决先查类别映射打印出一张图的预测结果和对应真值框看类别 id 对不对。然后验证集里随机抽 50 张图确认这些图片没有出现在训练集的 labels 目录中。如果这两项都没问题把输入分辨率从 640 提到 1280batch size 减半看看 mAP 是否显著上升。如果还是不动考虑换旋转框方案对这个数据集来说水平框的上限可能就在那里。5.5 现象裂缝细长目标被漏检尤其是横向裂缝现象训练完进行推理竖向裂缝检测效果尚可横向裂缝漏掉一大半或者完整的长裂缝被切成好几段只检测出其中一小段。原因横裂缝在图像里高度很小经过 YOLO 下采样后在 8 倍或 16 倍下采样的特征层上目标高度可能只覆盖一个特征点模型很难从中提取稳定特征。mosaic 增强又会对图片做随机缩放横裂缝缩放后更矮干脆被丢弃。解决训练阶段关闭 mosaic或者把mosaic超参数设为较低值例如在 YOLOv8 配置里把augment中的 mosaic 概率调到 0.3 以下。推理阶段采用切片推理把大图切成 640 或 512 的 patch每张 patch 单独推理再合并。合并时要注意跨 patch 的目标只保留一次重复框用 NMS 过滤。这个方案对裂缝召回率的提升非常直接尤其适合桥梁巡检这类原始图片都是几千像素大图的应用。6. 进阶用旋转框和切片推理把细长裂缝的召回率提上来如果第 4.2 节里长宽比大于 10 的标注占比超过 30%我的建议是两条路并行训练侧改旋转框推理侧用切片。旋转框可以把水平框内那大半背景甩掉。mmrotate 训练 DOTA 格式数据最关键的一步是角度约定。COCO 的 segmentation 多边形经过cv2.minAreaRect求出的角度和 mmrotate 各检测器的定义经常差 90 度或正负号不一致。我习惯的做法是先转 10 个样本把 rbox 画在图上人工看一遍确认裂缝方向跟 rbox 的长轴一致再批量转换。角度如果反向标注出来的框会横跨裂缝而不是包住裂缝训练效果直接崩掉。切片推理不用改模型适合落地优先级更高的情况。SAHI 这类工具把原图按固定大小切片重叠比例一般取 0.2 到 0.3。裂缝是细长目标如果重叠太小跨切片的裂缝会被切断成两段合并时出现一个目标被框两次。我自己常用的参数是切片尺寸 640、重叠 0.2推理时再把 patch 坐标回映射到原图。回映射时的偏移量必须加上 slice 的左上角坐标这是最容易写错的地方。我自己的血泪经验是细长目标检测不要迷信更大更强的模型。YOLOv8x 看不到的横裂缝换成 YOLOv8s 加切片推理往往就能看到。曾经有一次因为转换脚本里把 bbox 宽高对调整个团队训了两天loss 平滑下降但 mAP 停在 0.2 附近最后逐个比对可视化才发现是坐标问题。从那以后我所有训练流程都强制先出 20 张叠加框的图人眼看一遍再提交训练任务。这个习惯一直留到现在。拿到任何桥梁裂缝缺陷数据集.zip我都先解压、看 json、转格式、体检三件套再把图叠框过一遍眼睛然后才轮到 GPU 上工。希望这套路径能帮你也少踩几个坑让细长裂缝的召回率真正提上来。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →