尧图精选

YOLOv8下水道缺陷检测实战:2364张图七类缺陷训练与调参要点

🕒 发布时间:2026/10/1 7:29:23 📁 来源:尧图网络
简介面向目标检测算法学习与工程项目验证的下水道缺陷数据集覆盖关节偏移、障碍物、裂纹、带扣、洞、公用设施入侵、碎片等多类典型缺陷适合使用YOLOv5至YOLO11系列模型开展训练、验证与测试。压缩包内共2000个文件包含364个YOLO格式txt标签与1636个VOC格式xml标签无需额外转换且已按训练需求划分数据集并附data.yaml配置文件可快速接入主流YOLO工作流。标签格式说明清晰坐标与宽高均按图像归一化便于二次加工。资源包仅7.43MB轻量紧凑适合在网络环境受限时离线获取和使用。目前已有66人学习浏览对于需要快速搭建市政管网缺陷检测基线或验证YOLO系列改进效果的开发者是一份实用的小型数据集同时适合用作品类均衡分析、迁移学习或检测精度对比的基准数据。1. YOLO算法遇上 2364 张下水道缺陷图这块家底到底值不值得接拿到一个「YOLO算法-下水道缺陷数据集-2364张图像带标签-关节偏移-障碍物-裂纹-带扣-洞-公用设施入侵-碎片.zip」多数人的第一反应是解压、开训、跑个 mAP 发朋友圈。但真做过管道检测的人会先问三件事标签是 VOC 还是 YOLO、七类缺陷各自多少张、同一条管道的连续帧有没有混进同一个集合。这个数据集的吸引力不只是 2364 这个数字而是它把管检行业最常见的七类缺陷都收了进去其中关节偏移、带扣、碎片这三类恰恰是通用检测模型最容易翻车的地方。这篇笔记按我自己跑市政管道缺陷检测的流程来拆先体检 zip再转格式然后调参训练最后用混淆矩阵而不是 mAP 判断能不能上机器人。适合正在做管网检测算法、市政巡检产品验证或者准备用 YOLO 做工业缺陷识别的人读。2. 七类缺陷逐个拆解真正难认的是哪三类拿到数据先别急着训练把每个类别的视觉特征搞清楚比调任何参数都值钱。下水道缺陷检测和工业质检不一样缺陷不是长在干净的传送带上而是长在潮湿、反光、有泥浆遮挡的管壁里。同一个类别在不同管段里长相差异极大模型很容易把阴影当裂纹把带扣当障碍物。2.1 七个标签分别指什么视觉特征、易混项与检测难点先按我日常看标注图的经验把这七类过一遍后面训练和调阈值都用得上。类别典型视觉特征容易与谁混淆检测难点关节偏移joint offset两节管道的接缝处出现环形错位呈台阶状阴影通常在镜头正前方环向裂纹、安装缝隙光照不均匀时接缝阴影极像裂纹且框与裂纹框大面积重叠障碍物obstacle管道内石头、树根、淤泥堆体积大、占画面比例高碎片堆积、带扣形态差异大同一类里可能有整块巨石也有散落土块裂纹crack管壁上的线状裂缝分纵向、横向、环向关节偏移阴影、碎裂纹路细长形小目标低分辨率特征层容易直接丢带扣strap环形钢筋或管壁连接金属件U 形、矩形有明显金属反光障碍物、洞尺寸小反光区域会盖住边缘框的宽高比不稳定洞hole管壁破洞圆形或不规则形边缘较清晰深色污渍、阴影暗环境下洞内全黑和背景一起被当成正常管壁公用设施入侵utility intrusion其他管线或电缆横穿管道内部障碍物、粗裂纹长条状贯穿画面NMS 阶段容易与裂缝框合并碎片debris砖块、垃圾、残渣散落小而密集障碍物、带扣小目标且密集分布遮挡严重漏检率通常最高这套分类本身设计得不算刁钻但它覆盖了《城镇排水管道检测与评估技术规程》里最常见的判废缺陷。关节偏移和洞属于结构性缺陷直接决定管道要不要修障碍物和碎片属于功能性缺陷决定要不要马上疏通。如果模型把碎裂的砖块当成带扣上报现场人员过去一看是误报阈值就白调了。七类里我最担心的是三类关节偏移、带扣、碎片。关节偏移的问题是边界模糊标注的人可能把台阶阴影画成裂纹同一个区域出现两个框训练时 YOLO 不知道该学哪一个带扣是特征被反光破坏金属高光区域在 JPEG 压缩后可能整块变成白色碎片则是典型的「小、多、密」一张图上十几个框互相压着NMS 一收就少掉三分之一。2.2 下水道图像的三个特点反光、暗角与运动模糊CCTV 管道机器人拍的图和普通街景数据是两个世界。第一是光照极端机器人自带环形 LED 灯画面中心亮、四周黑管壁的弧度会造成大面积高光反射裂纹在强光下会「消失」洞在暗角里会「隐身」。第二是运动模糊机器人行进中拍摄镜头离管壁近稍微抖动就是一片糊标注框比实际缺陷大一圈是常有的事。第三是色彩通道退化下水道里几乎只有黄褐色、灰色和黑色RGB 三通道的区分度很低模型很难像在自然图像上那样靠颜色提特征。这些特点直接影响预处理和训练参数的选择。很多教程默认做 CLAHE 对比度增强或直方图均衡但在这类图像上全局均衡化会让暗角区域出现过曝反光更严重。我一般保留原始曝光只在训练时做轻微的亮度抖动让模型自己去适应光照变化。输入尺寸上2364 张图里大量是 512x512 或 768x576 的老式 CCTV 截图直接 resize 到 640 会损失裂纹的细节这个在第 4 章专门讲。2.3 2364 张图够不够训类不均衡与数据规模判断先说结论2364 张带标签图对 YOLO 来说够起步但远不够端到端直接部署。按七类平均算每类只有 330 张左右真实数据集里分布通常很不均衡碎片和障碍物可能占掉一半带扣可能只有 100 多张。在小样本场景下类别少的模型训练时会出现「多数类反客为主」的现象——碎片把 loss 占满带扣和公用设施入侵学不出来。数据规模推荐做法预期效果500 张以内加载预训练权重冻结 backbone只训 head能跑通流程类别多的类能成形500–2000 张微调全部层重增强加早停大目标类效果可用小目标仍会漏2000–5000 张本数据集区间正常训练 YOLOv8s/m按类统计样本量补强多数类可接近部署少数类需人工补数据5000 张以上可尝试 YOLOv8l/x考虑多尺度训练各类别趋于稳定短板在标注一致性2364 张在这个分级里正好处于「能训练但每类平均样本少」的尴尬区。破解办法是迁移学习加定向增强而不是加大训练轮数。用 COCO 预训练权重做初始化模型已经学会基础纹理和边缘特征转来学下水道缺陷只需要几十个 epoch 就能收敛。我在这种量级的数据上从来不跑超过 300 epoch超过 150 epoch 后验证集 loss 基本不动反而开始记住个别样本的噪声。还要提一句数据集带标签不等于标注一致。如果七类缺陷分由不同人标注关节偏移和裂纹之间、碎片和障碍物之间很可能存在标准漂移。训练前随机挑 50 张图把框画出来人工过一遍比自己闷头调参省时间得多。3. 用 YOLOv8 把这包数据跑通从 zip 解压到首个 mAP 的完整流程这一章给出一个能直接照抄的落地路径。前提是你电脑上已经装了 Python 3.8 以上和 ultralytics 库没有的话pip install ultralytics一条命令搞定。整个流程分三步先体检压缩包再统一标签格式并拆分数据集最后跑一个 50 epoch 的基础训练。3.1 先做 zip 解压与数据体检目录、标签与 zip 伪加密拿到压缩包先别用鼠标双击解压。在命令行里解压能看清文件结构和有没有隐藏问题。Linux 或 Windows Terminal 里执行unzip -o YOLO算法-下水道缺陷数据集-2364张图像带标签-关节偏移-障碍物-裂纹-带扣-洞-公用设施入侵-碎片.zip -d sewer_data/ find sewer_data -type f | head -20-o表示覆盖已有文件-d指定解压目录避免把一包文件直接摊在工作目录里。解压后先看目录结构通常是images/和labels/两个文件夹也可能是 VOC 风格的JPEGImages/和Annotations/。接着确认标注格式ls sewer_data/labels | head -5 cat sewer_data/labels/0001.txt如果 txt 里每行是class_id x_center y_center width height这种五段数字就是 YOLO 格式的归一化坐标如果看到 XML 文件是 VOC 格式需要走下一节的转换脚本。这一步很多人跳过结果训练时 data.yaml 路径写错程序报错找不到标签浪费一晚上。解压时如果提示「需要密码」或者解压到一半报错不一定是真有密码。zip 文件头上有一串通用位标记general purpose bit flag第 0 位是加密标志位。有些工具会把这一位置 1 但内容并没有真正加密这就是常说的 zip 伪加密。先用一个短脚本检查import struct def check_zip_header(zip_path): with open(zip_path, rb) as f: header f.read(30) if header[:4] ! bPK\x03\x04: print(不是标准 zip 文件) return flags struct.unpack(H, header[6:8])[0] print(加密标志位bit0:, flags 0x01) print(压缩方法:, struct.unpack(H, header[8:10])[0]) check_zip_header(YOLO算法-下水道缺陷数据集-2364张图像带标签.zip)这段代码读出第一个本地文件头的标志位。如果 bit0 是 1但你又确定这包数据公开可用大概率是伪加密。修复办法是用 Python 把文件重新打包顺便清掉加密标志import zipfile with zipfile.ZipFile(bad.zip) as zin, \ zipfile.ZipFile(fixed.zip, w, zipfile.ZIP_DEFLATED) as zout: for item in zin.infolist(): item.flag_bits ~0x01 # 清除加密标志位 data zin.read(item.filename) zout.writestr(item, data)注意zipfile.ZipFile(bad.zip)在读伪加密包时如果报错说明它确实按加密文件处理了这种情况先尝试zip -FF bad.zip --out repaired.zip修复再走重打包。伪加密这个坑在公开数据集里出现频率不低别一看到要密码就放弃。3.2 把标注统一成 YOLO 格式VOC 转 txt 与训练验证拆分如果标签是 VOC 的 XML需要转成 YOLO 的 txt并同步拆分训练集和验证集。下面这段脚本是实践验证过的可以直接存成prepare_data.py运行import xml.etree.ElementTree as ET import os, random, shutil # 按你的实际目录调整我一般习惯把路径写在脚本顶部 IMG_DIR sewer_data/JPEGImages XML_DIR sewer_data/Annotations OUT_IMG sewer_data/images OUT_LBL sewer_data/labels TRAIN_RATIO 0.85 # 类别映射表必须和解压后标签里的 class_id 一一对应 CLASS_MAP { joint_offset: 0, obstacle: 1, crack: 2, strap: 3, hole: 4, utility_intrusion: 5, debris: 6 } os.makedirs(f{OUT_IMG}/train, exist_okTrue) os.makedirs(f{OUT_IMG}/val, exist_okTrue) os.makedirs(f{OUT_LBL}/train, exist_okTrue) os.makedirs(f{OUT_LBL}/val, exist_okTrue) xml_files [f for f in os.listdir(XML_DIR) if f.endswith(.xml)] random.seed(42) random.shuffle(xml_files) split_idx int(len(xml_files) * TRAIN_RATIO) train_files, val_files xml_files[:split_idx], xml_files[split_idx:] def convert(xml_path, img_name): tree ET.parse(xml_path) root tree.getroot() size root.find(size) img_w int(size.find(width).text) img_h int(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in CLASS_MAP: continue # 标注里有非目标类直接跳过 box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{CLASS_MAP[name]} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) return lines这段代码把 XML 里的绝对坐标转成归一化的 YOLO 格式并按照 85% / 15% 拆分成训练集和验证集。三个参数值得注意一是TRAIN_RATIO用 0.85 而不是 0.8因为总量只有 2364 张验证集太小会导致 mAP 波动大二是random.seed(42)固定随机种子保证每次拆分一致方便对比实验三是CLASS_MAP里的类别顺序一旦定下来就不要改训练和推理共用同一份映射改一个数字前面所有训练白费。跑完后检查一下输出训练集和验证集里每类应该都有样本如果某一类在验证集里一张都没有后面 val 的 mAP 就会虚高需要重新调拆分比例。3.3 用 YOLOv8 跑第一个训练data.yaml 与完整命令标签就绪后写一个sewer.yaml放到数据集根目录path: ./sewer_data train: images/train val: images/val names: 0: joint_offset 1: obstacle 2: crack 3: strap 4: hole 5: utility_intrusion 6: debrispath字段是数据集根目录train和val是相对路径names必须和转换脚本里的CLASS_MAP顺序完全一致。然后执行训练yolo detect train \ datasewer.yaml \ modelyolov8s.pt \ epochs50 \ imgsz640 \ batch16 \ device0modelyolov8s.pt会加载 COCO 预训练权重这是小数据量训练的关键别用yolov8s.yaml从零训练。imgsz640是 YOLOv8 的默认输入尺寸显存 8G 的卡上batch16刚好跑得动如果中途显存溢出把 batch 降到 8不要动 imgsz除非你确认自己知道改 imgsz 的后果。epochs50是基础跑法目标是看曲线走势不是直接出最终模型。训练结束后看runs/detect/train/下的results.png和weights/best.pt。如果 loss 曲线前 10 个 epoch 没有明显下降先检查标签文件名和图片文件名是否一一对应这是新手翻车率最高的地方后面避坑章节专门展开。4. 训练参数怎么定输入尺寸、损失权重与增强策略的取舍第一次训练能跑通不算本事把参数调到「验证集 mAP 不虚高、现场测试不翻车」才是关键。YOLOv8 相比老版 YOLOv5 简化了很多 anchor 配置但输入尺寸、类别权重、增强策略这三个旋钮仍然直接决定下水道这类暗光小目标数据集的最终效果。4.1 输入尺寸选 640 还是 1280小目标召回与显存的取舍下水道缺陷里裂纹、带扣、碎片都是典型小目标在 640x640 输入下一个宽度只有 20 像素的裂纹经过 5 次下采样到特征层只剩 1 个像素不到检测头根本拿不到有效信息。换 1280 输入能明显提升小目标召回但代价是显存占用和训练时间翻倍。输入尺寸显存占用batch8训练时间50 epoch小目标召回适用阶段640约 6–8 GB基准一般快速验证跑通流程1024约 10–12 GB约 1.8 倍较好常规训练1280约 16 GB 以上约 2.5 倍好最终模型微调我的习惯是先 640 跑通确认数据没问题再用 1024 跑最终版本。直接上 1280 不是不行但训练时间拉长调参效率太低。还有一个折中方案保持 640 输入把 mosaic 增强里的 copy-paste 打开让模型在小目标位置多学几次这个后面细说。值得注意的是YOLOv8 是 anchor-free 架构没有传统意义上的预设 anchor 框但标签里目标的宽高比分布仍然影响回归损失的计算。裂纹是典型的极端宽高比目标宽高比可能到 1:10而洞接近 1:1。如果数据里洞的数量远多于裂纹回归分支会被圆形目标主导细长目标会学得慢。所以输入尺寸之外还要看一下标签分布。4.2 先统计标签宽高比再谈训练一个小脚本看清类别构成训练前花五分钟统计标签里的宽高比和类别数量能避免很多玄学调参。下面这段脚本不依赖额外库直接用标准库跑from glob import glob from collections import Counter label_files glob(sewer_data/labels/train/*.txt) cls_counter Counter() wh_by_cls {} for f in label_files: for line in open(f): parts line.split() cls_id parts[0] cls_counter[cls_id] 1 w, h float(parts[3]), float(parts[4]) # 存归一化的宽高后面按类别算宽高比 wh_by_cls.setdefault(cls_id, []).append((w, h)) for cls_id in sorted(wh_by_cls): ratios [w / h for w, h in wh_by_cls[cls_id] if h 0] avg_w sum(w for w, h in wh_by_cls[cls_id]) / len(wh_by_cls[cls_id]) avg_h sum(h for w, h in wh_by_cls[cls_id]) / len(wh_by_cls[cls_id]) print(f类 {cls_id}: 样本数 {cls_counter[cls_id]}, 平均宽高比 {sum(ratios)/len(ratios):.2f}, 平均目标占比 {avg_w*avg_h*100:.2f}%)cls_id对应sewer.yaml里的类别顺序输出能直接看出两个关键信息哪一类样本太少哪一类目标太小。如果带扣的平均目标占比只有 0.5%说明整张图里带扣只有十几个像素这个类别的召回率注定上不去后面要做专门的小目标增强。宽高比极端的两类裂纹和公用设施入侵如果样本量接近回归分支会互相拉扯。看过分布再决定要不要调损失权重。YOLOv8 原生训练命令里不能直接给每个类设置 loss 权重需要通过自定义数据集类或者替换损失函数实现这对新手太折腾。更实用的办法是在 data.yaml 的同级目录放一份custom_augment配置重点照顾小目标类。4.3 数据增强哪些操作适合下水道哪些是坑增强策略的选择一定要结合场景。管道 CCTV 图像里管道方向固定缺陷不会上下颠倒所以flipud上下翻转建议直接关掉fliplr左右翻转可以保留因为机器人正反两个方向拍摄都有可能。旋转增强要谨慎超过 45 度的旋转会产生大量黑色填充区域模型学到的是「黑色背景上的缺陷」部署时反而掉点。下面是我在这个数据集上常用的增强参数配合 YOLOv8 的 augmentation 参数使用hsv_h: 0.02 hsv_s: 0.5 hsv_v: 0.3 degrees: 10 translate: 0.1 scale: 0.4 shear: 5 perspective: 0.0 flipud: 0.0 fliplr: 0.5 mosaic: 0.8 mixup: 0.2hsv_v调到 0.3 模拟不同光照强度这是下水道图像最重要的增强项比什么旋转都管用。shear用 5 度以内模拟机器人镜头偏移。perspective保持 0管道内本来就是正面视角强透视变换会破坏缺陷形状。mosaic开到 0.8 保持小目标样本量mixup开 0.2 帮助类别边界模糊的碎片和障碍物。这套参数在 2364 张图上能稳定把验证集的 mAP0.5 从 0.6 左右拉到 0.7 以上。增强参数不是越多越好。我见过有人把degrees开到 90训练集 loss 降得很快验证集 mAP 也不差但一到真实管道视频就疯狂漏检原因就是模型学到了大量现实中不会出现的旋转角度把精力浪费在无效特征上。增强的本质是让模型在合理的数据扰动范围内更鲁棒不是把所有可能的变化都塞进去。5. 避坑从 zip 解压到 mAP 的五个翻车现场这个数据集从解压到部署坑比想象中多。下面五条是我实际踩过的按出现频率排序每一条都写清了现象、原因和解决办法。5.1 zip 解压报错、提示要密码先查伪加密别急着换工具现象双击解压时 7-Zip 弹出输入密码窗口输入什么都是错的换 WinRAR 直接报压缩包损坏。原因zip 文件的通用位标记第 0 位被置为 1表示「文件已加密」但实际内容并没有真正加密文件头后面也没有加密所需的数据块。这是典型的 zip 伪加密公开数据集里偶尔会出现。解决按 3.1 节里的 Python 脚本检查标志位确认是伪加密后用重打包方式清除加密位或者直接换zip -FF修复。注意不要乱下载所谓的「zip 密码移除工具」伪加密用脚本就能处理。5.2 训练张数对不上标签后缀大小写与中文路径现象yolo detect train启动后日志显示images: 1800但明明解压出来是 2364 张图。原因第一图片后缀可能是.JPG而程序匹配的是.jpg第二数据集放在带中文的路径下部分 Windows 环境下文件读取被截断程序只读到部分文件名。解决解压后先统一后缀和路径把JPG、png全部改成小写.jpg并把整个数据集放到纯英文路径下。可以用一条命令完成find sewer_data -name *.JPG -exec mv {} {}.tmp \; find sewer_data -name *.JPG.tmp -exec sh -c mv $1 ${1%.JPG.tmp}.jpg _ {} \;文件名和后缀统一后再数一遍文件个数再训练。少数据训练不是不能跑但你会白白浪费一晚上去怀疑自己的模型设计。5.3 类别编号错位loss 正常下降验证集指标全乱现象训练时 loss 曲线正常下降val 的 mAP 也有 0.6但把验证集图片可视化出来裂纹的框画在洞上碎片的框画在带扣上类别全部错位。原因VOC 转 YOLO 时CLASS_MAP写错了顺序或者在调整类别后没有同步更新sewer.yaml。YOLOv8 训练时不会校验类别名和类别顺序它只认数字编号。解决训练第一次跑完后用model.predict对验证集跑几张图把预测结果画出来人工看一眼from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) results model.predict(sourcesewer_data/images/val, saveTrue, conf0.25)这一步只要 30 秒但能拦住大部分标签错位问题。不要只看 mAPmAP 是一个均值类别错位情况下它照样能算出来一个不错的值。5.4 关节偏移和裂纹叠在一起NMS 把两个框并成一个现象单张图上同时存在关节偏移和裂纹模型只出一个框而且框的坐标介于两者之间。原因这两个类别在真实场景里确实会叠加——管节错位处的应力集中会引发环向裂纹。同一片区域两个高度重叠的框在 NMS 阶段低置信度的那个会被直接抑制。解决第一把 NMS 的 IoU 阈值从默认 0.45 调低到 0.3允许同类别的重叠框多保留一个代价是误检略增第二更彻底的办法是把这两个类别在标注时就合并成「关节偏移裂纹」复合缺陷避免模型在训练时反复纠结该学哪个框。如果数据集里这种情况占比超过 10%我建议直接在模型输出阶段做后处理合并而不是强行让 YOLO 分开。5.5 验证集 mAP 高、现场表现差同一条管道的连续帧混进了验证集现象验证集 mAP0.5 有 0.78结果拿一段新拍的管道视频去测召回率掉到 0.4碎片几乎全漏。原因数据集按文件序号随机拆分成 train 和 val但同一条管道拍摄的几百帧连续图像内容高度相似随机拆分导致验证集里混入了训练集的「近亲」——模型其实已经见过这些画面mAP 自然虚高。解决按视频片段或管道编号分组拆分而不是按单张图像随机拆分。给数据集的图片文件名里带上拍摄管道 ID拆分时以管道 ID 为最小单位from collections import defaultdict import random # 假设文件名形如 pipe01_seg0023.jpg groups defaultdict(list) for f in xml_files: pipe_id f.split(_)[0] groups[pipe_id].append(f) pipe_ids list(groups.keys()) random.seed(42) random.shuffle(pipe_ids) split_idx int(len(pipe_ids) * 0.85) train_pipes set(pipe_ids[:split_idx])这段代码先把所有图像按管道分组再按管道编号拆分。验证集里的画面和训练集来自完全不同的管道mAP 会下降但更接近真实部署水平。这个坑最隐蔽很多人 mAP 很好看一到现场就崩九成是这个原因。6. 用混淆矩阵和 PR 曲线做最终验收挑出能上机器人的模型训练结束不等于验收结束。YOLOv8 自带的验证命令就能输出两张最重要的诊断图yolo detect val \ modelruns/detect/train/weights/best.pt \ datasewer.yaml命令跑完后在runs/detect/val/下会生成confusion_matrix.png和PR_curve.png。混淆矩阵看的是「谁被认成了谁」PR 曲线看的是「每个类别在哪个阈值下能平衡精度和召回率」。看混淆矩阵时重点扫两个位置对角线外的高亮块以及带扣和碎片之间的互混。如果关节偏移大量被认成裂纹说明这两个类的视觉边界在模型眼里不够清晰最直接的办法不是调参而是回到标注层统一判定标准如果碎片被认成障碍物说明碎片的样本量不够模型选择把置信度押在更大、更完整的障碍物上。PR 曲线则是用来定部署阈值的。下水道检测属于召回优先的场景——漏掉一个洞可能直接导致管道塌陷多报几个误检让人工复核的成本远小于漏检。所以最终部署时我会把置信度阈值从默认 0.25 降到 0.15NMS 的 IoU 从 0.45 提到 0.5给每个缺陷多一些存活空间。代价是单帧框数变多但下游的筛选程序可以按缺陷严重等级排序把优先级低的误检过滤掉。最后分享一个自己的习惯每次训练完除了看指标还会挑 20 张验证集里最暗的图单独跑一遍predict输出标注图。模型在暗光图上的表现往往比整体 mAP 更能说明它能不能上管道机器人。这个习惯帮我拦下过两次看起来指标合格、实际根本没法用的模型。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →