Kvasir-SEG息肉检测数据集:YOLO格式、可视化脚本与避坑指南

发布时间:2026/10/9 11:08:43
Kvasir-SEG息肉检测数据集:YOLO格式、可视化脚本与避坑指南 简介一套可直接用于YOLO目标检测训练的息肉检测数据集面向计算机视觉初学者及医疗影像检测研究者免去数据采集、清洗与格式转换的繁琐工作。压缩包内共2000个文件主体为999张jpg图像与一一对应的1000个txt标签文件另提供1个Python可视化脚本整体大小约57MB分为训练集800张、验证集200张。数据为单类别“息肉”并随包提供类别class文件标注采用YOLO相对坐标格式边界框完整每张图像均有清晰目标。图像分辨率覆盖332x487至1920x1072均为RGB大图适用于内镜息肉识别的模型训练与验证。附带脚本可直接运行随机传入一张图片即可绘制边界框并保存到当前目录便于直观检查标注效果。目前已有315人学习下载适合需要标准格式数据集快速搭建检测训练流程或开展息肉识别实验的开发者。1. 拿到一块能直接开训的 YOLO 息肉检测数据Kvasir-SEG 的目录、标注与可视化脚本做检测训练最怕的不是模型效果差而是数据本身有问题还浑然不觉。我拿到一份 Kvasir-SEG 息肉检测数据集1 个类别、训练集 800 张、验证集 200 张、压缩后 57 MB每张图都配好了 YOLO 格式的 txt 标签还带一个无需改参数就能跑的可视化脚本——按 YOLO 项目目录保存放进去就能直接开训。这套资源适合三类人刚开始接触目标检测、想练手数据全流程的学生跑通 YOLOv5/v8 训练链路但缺一份干净标注的从业者以及只想在医疗图像小样本上快速做出一个可演示的 baseline、不想自己标框的开发者。它帮你省掉的不是训练时间而是最烦人的数据准备阶段。2. 目录结构与 YOLO 标注格式归一化坐标、train/val 划分与验证方法这份数据的目录结构是典型的 YOLO 项目组织方式所有图片和标签按训练、验证两个分支存放下载解压后不需要额外整理。动手训练之前先把结构和格式吃透后面所有脚本和调参都建立在这套约定上。2.1 目录树与文件对应关系train/val 下 images 和 labels 怎么对上解压后的数据目录大致如下datasets/ ├── images/ │ ├── train/ # 800 张 jpg │ └── val/ # 200 张 jpg ├── labels/ │ ├── train/ # 800 个 txt │ └── val/ # 200 个 txt └── classes.txt # 类别文件第一行是 polyp图片和标签是一一对应的比如cju7eea9b2m0z0801ynqv1fqu.jpg对应的标签文件就是同名主名、同扩展名规则下的cju7eea9b2m0z0801ynqv1fqu.txt。YOLO 系列的 DataLoader 默认就按这个规则找标签图片在images/下标签在labels/下主名一致训练时不需要你手工配对。我一般拿到数据集的第一件事不是打开代码而是先打印一遍文件数量确认两边一一对应for split in train val; do echo $split imgs: $(ls datasets/images/$split | wc -l) echo $split labels: $(ls datasets/labels/$split | wc -l) done如果数量对不上通常是标签目录里混入了残留文件或者某张图没有对应 txt。这种问题越早发现越省事等训练跑到一半才报FileNotFoundError排查成本会高得多。这里面有个容易被忽略的设计细节图片名是随机字符 ID比如cju0sr5ghl0nd08789uzf1raf中间没有空格、没有中文这对脚本处理非常友好用glob通配也不会踩到编码或特殊字符的坑。我见过有人嫌名字乱想改成 0001.jpg 这种顺序命名结果把全部标签路径破坏了一遍属于典型的画蛇添足。2.2 标注格式x_centre、y_centre、w、h 不只是四个数字打开任意一个标签 txt内容格式是0 0.438471 0.421621 0.291626 0.185402这行一共 5 个字段全部是归一化相对坐标第 1 个字段是类别索引这里只有 0 一种对应classes.txt第一行的polyp第 2、3 个字段是x_centre和y_centre表示目标框中心点在图片上的相对位置第 4、5 个字段是w和h表示目标框宽度和高度占图片宽高的比例。用大白话讲YOLO 标注并不是你眼睛看到的像素坐标而是告诉你“目标中心在图的百分之多少处、框宽占全图的百分之多少”。这个设计让同一套标注在不同分辨率输入下都能直接复用但也意味着你在画框、算 IoU、做数据清洗时必须把归一化坐标还原成像素坐标这一步是所有后续操作最容易翻车的地方。还原公式很简单但值得单独写出来img_w, img_h 1920, 1072 # 假设某张真实图片的宽高 x_c, y_c, bw, bh 0.438471, 0.421621, 0.291626, 0.185402 left int((x_c - bw / 2) * img_w) top int((y_c - bh / 2) * img_h) right int((x_c bw / 2) * img_w) bottom int((y_c bh / 2) * img_h) print(left, top, right, bottom)手算验证一下归一化(0.5, 0.5, 0.3, 0.2)配一张 1280x720 的图left (0.5 - 0.15) * 1280 448top (0.5 - 0.1) * 720 288right (0.5 0.15) * 1280 832bottom (0.5 0.1) * 720 432。框中心正好在(640, 360)说明换算正确。这里必须强调一个常见误解x_centre是中心点不是左上角写成左上角公式后所有框都会整体偏移半个框宽。2.3 为什么这份数据不需要预处理就能挂进 YOLO 训练链路YOLOv5 和 YOLOv8 的训练代码里data.yaml是入口配置。这份资源的数据组织方式正好匹配默认行为只需要写一个简单的配置文件path: ./datasets train: images/train val: images/val nc: 1 names: - polyp参数说明path指向数据集根目录train和val是相对路径nc1表示只有 1 个类别names列表的顺序必须和classes.txt里的顺序一致。类别名称可以随便起但索引顺序不能乱否则训练后的混淆矩阵和 mAP 计算就会“看似正常实则错位”。这份数据最省心的地方在于它跳过了三个常见的数据准备步骤不需要把分割掩码转成边界框、不需要做 VOC/COCO 与 YOLO 格式互转、不需要清洗图片名里的特殊字符解压完就能训。用这类下载即用的数据集时我通常会先跑一次单卡短训练做烟雾测试比如 10 epoch确认 loss 能从初始值往下掉再上完整训练这个习惯能帮你避开“数据集本身有毒但训练半天才发现”的尴尬。3. 数据可视化脚本实战随机抽图、画框保存与参数调优数据值不值得信最快的方法是把它画出来看。这份资源自带一个可视化脚本核心逻辑是随机抽一张图、读同名 txt、把归一化坐标还原成像素框、在图上画矩形并保存到当前目录。别小看这个脚本它能一次性验证三件事图片能否被正常解码、标签文件和图片是否对得上、归一化坐标转换是否准确。3.1 脚本逻辑链路从随机抽图到输出可视化结果脚本的工作流程可以拆成五步从指定images/val目录里随机选一张 jpg用图片主名去labels/val找同名 txt读取 txt 每一行解析出 5 个字段用图片的真实宽高把归一化坐标还原成像素框用 OpenCV 画框、标注类别保存到当前目录。默认从验证集抽图是个好设计。训练集有 800 张抽中某类特殊样本的概率摊薄了验证集只有 200 张随机抽 1~3 张更容易覆盖典型样本肉眼检查起来效率更高。3.2 一个可以直接运行的参考脚本下面的脚本按前述流程实现目录路径改成你实际解压的位置就能跑import os import random import cv2 IMG_DIR datasets/images/val # 从 val 抽图也可以改成 train LBL_DIR datasets/labels/val OUT_DIR . # 保存到当前目录 NUM_SAMPLES 1 # 随机抽几张默认 1 def draw_boxes(img_path: str, lbl_path: str, out_path: str) - None: img cv2.imread(img_path) if img is None: raise FileNotFoundError(f无法读取图片: {img_path}) h, w img.shape[:2] # 必须用真实图片尺寸作为分母 boxes [] with open(lbl_path, r, encodingutf-8) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue # 跳过异常行防止脏数据中断 cls_id, x_c, y_c, bw, bh map(float, parts) left int((x_c - bw / 2) * w) top int((y_c - bh / 2) * h) right int((x_c bw / 2) * w) bottom int((y_c bh / 2) * h) boxes.append((cls_id, left, top, right, bottom)) for cls_id, left, top, right, bottom in boxes: cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0), 2) cv2.putText(img, fpolyp:{cls_id}, (left, max(0, top - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 1) cv2.imwrite(out_path, img) print(f已保存: {out_path} (图尺寸 {w}x{h}, 框数 {len(boxes)})) def main(): os.makedirs(OUT_DIR, exist_okTrue) names [f for f in os.listdir(IMG_DIR) if f.lower().endswith(.jpg)] sample random.sample(names, min(NUM_SAMPLES, len(names))) for name in sample: base os.path.splitext(name)[0] lbl_path os.path.join(LBL_DIR, base .txt) draw_boxes(os.path.join(IMG_DIR, name), lbl_path, os.path.join(OUT_DIR, vis_ base .jpg)) if __name__ __main__: main()逻辑说明按照实际运行顺序展开先看main()。它负责列出目录下所有 jpg、随机抽样、拼接标签路径。random.sample(names, min(NUM_SAMPLES, len(names)))这里的min是为了防止抽样数量大于文件总数时抛异常。文件名用os.path.splitext去掉扩展名再拼.txt不会出现大小写或扩展名不一致的问题。再看draw_boxes()。cv2.imread读取失败时返回None脚本直接抛异常避免画出一张全黑图还误以为成功。h, w img.shape[:2]是全部逻辑里最关键的一行因为这份数据里图片尺寸跨度很大从 332x487 到 1920x1072 都有任何写死宽高的做法都会让框偏掉。坐标换算公式统一按“中心点减半宽”处理和上一章讲的还原公式一致。参数说明如下IMG_DIR和LBL_DIR分别指向图片和标签目录必须一一对应改成datasets/images/train就能抽训练集的图。OUT_DIR默认是当前目录建议改成./vis_out之类避免可视化结果污染原始数据目录。NUM_SAMPLES控制抽图数量我一般抽 5 张做一轮检查覆盖不同分辨率样本。标签编码用utf-8Windows 环境下脚本文件本身如果是 GBK中文注释可能报错可以把注释去掉或转换文件编码。3.3 跑通后怎么检查结果什么样的图算合格可视化结果不是“能画出框”就够了合格的产出要同时满足三个条件框是矩形且紧贴病灶边缘框没有明显溢出图片边界同一张图每次画出的框位置一致。如果发现框整体向上或向左漂移或者框明显比病灶大一圈基本都是坐标还原公式或分母用错的问题。实际操作时我会固定抽查两类样本一张小分辨率图比如 332x487确认框占整图比例接近归一化值一张大分辨率图比如 1920x1072看框在大图上是否还贴合。一张 640x640 缩略图里看起来正常的框放大到原图后常常能暴露边界溢出问题。这个抽查习惯能提前拦住大多数标注质量问题比训练完再回头查省太多时间。4. 避坑指南跑这份数据和可视化脚本时最容易翻车的五个问题以下五条全是实际跑这类“下载即用”数据集时踩过的坑每一条都按现象、原因、解决三个步骤拆开讲方便你遇到同样问题时直接对照排查。4.1 坑一可视化结果“框偏了”但看着又不太离谱现象部分图片上画出的框和病灶有明显错位不是完全对不上而是差个一两成宽度的偏移另一些图又完全正常。原因最常见的是脚本里把分母写成了固定值比如640或416。这份数据的图片分辨率从 332x487 到 1920x1072 参差不齐归一化坐标乘以固定宽高后只有恰好等于该尺寸的图才显示正确其余全部偏移。第二个可能原因是代码混淆了x_centre和左上角坐标框中心变成了框原点整体漂移半个框宽。解决统一改用img.shape[:2]取真实宽高。拿到任何新数据集时先跑一段脚本把图片分辨率极值打印出来确认范围后再写转换逻辑import cv2 import os for root, _, files in os.walk(datasets/images): for f in files: img cv2.imread(os.path.join(root, f)) if img is not None: h, w img.shape[:2] print(f, w, h)之后每张图都用自身宽高做分母问题自然消失。4.2 坑二训练时报标签文件找不到但目录里明明有现象训练脚本运行到某个 epoch 时报FileNotFoundError提示某个标签 txt 不存在手动去目录里查文件明明就在那里。原因不是文件缺失而是拼接路径时的扩展名不一致。比如图片是.jpg标签写成.jpeg.txt或者遍历时用了大小写敏感的匹配方式。另一个隐蔽原因是文件名含有不可见字符比如复制粘贴时混入了回车或空格。解决不要手工拼路径用os.path.splitext(name)[0] .txt这种基于图片主名的拼接方式。保持这份数据原有的随机 ID 命名不要自己重命名图片或标签重命名是这类问题最大的触发源。数据量不大时直接用fc或diff对比两个目录的文件清单一分钟就能定位到缺失项。4.3 坑三cv2.imread 返回 None文件路径和文件名都没问题现象在无显示器的 Linux 服务器或 Docker 容器里跑可视化脚本cv2.imread一直返回None程序抛“无法读取图片”。原因这类机器上没装桌面组件OpenCV 默认走 GTK/X11 显示通道虽然读图本身不依赖显示器但某些版本在无 GUI 环境下解码器会异常。另一种常见情况是安装的是opencv-python而不是opencv-python-headless两者在无桌面环境中行为不同。解决无界面机器上优先装 headless 版本pip install opencv-python-headless如果不想折腾 OpenCV也可以用 PIL 读图再转 numpy 数组能同时绕开 GUI 依赖和中文路径两个问题import numpy as np from PIL import Image img cv2.cvtColor(np.array(Image.open(img_path).convert(RGB)), cv2.COLOR_RGB2BGR)这个方案我在 Docker 环境里救过两次建议可视化脚本里直接写成 PIL 优先。4.4 坑四nc 填成 2训练前几个 epoch 的 loss 一直高位震荡现象训练启动后 loss 降不下去mAP 曲线像过山车一样上下乱跳验证集准确率在不同 epoch 之间波动极大整个训练过程看起来像在撞运气被我形容为“玄学波动”。原因把“图片里只有一个目标类别”误解成“数据集分两个 split 所以类别数也是 2”或者从别的项目抄了data.yaml忘记改nc。YOLO 的nc指的是类别数量不是训练集或验证集的个数这份数据标签里只出现类别 0nc1才对。解决打开classes.txt数一遍行数把nc固定写 1。写data.yaml时养成自查习惯nc、names列表长度、标签文件里的最大类别编号三者必须一致。顺带看一眼验证集标签里有没有编号为 0 以外的行如果有说明标注本身有隐患。4.5 坑五觉得训练集只有 800 张太小猛开数据增强后 mAP 反而下降现象拿到数据后嫌 800 张太少把旋转、裁剪、HSV 抖动、翻转全开训练 50 epoch 后 mAP 比默认增强还低小目标漏检明显变多。原因这份数据的特点是分辨率跨度大大图上息肉可能只占一个小角落小图上息肉几乎撑满整图。强几何增强例如大角度旋转会让病灶比例严重失真模型学到的不是病灶特征而是增强伪影过度 HSV 抖动又让背景纹理变得更强小目标更不易区分。57 MB 看似小但息肉图像里大片黑色或灰色背景压缩率高数据量并不能只看文件大小。解决初始阶段只用默认 mosaic 加轻度缩放scale控制在 0.5~1.5 之间关闭或保持默认fliplr先跑出基线再逐步加增强项。判断增强是否有效的标准只有一个验证集 mAP 是否真实提升。口径不提升就回退配置这个坑我交过学费之后再也不敢拿 800 张图做激进增强实验。5. 进阶验证用 mAP 曲线和框尺寸分布判断数据是否值得训练5.1 先跑 50 epoch 的默认基线看 mAP0.5 是否能爬到 0.7 以上拿到这份数据后我建议你做的第一件正经事不是调参而是用默认参数跑一个 50 epoch 的基线python train.py --data datasets.yaml --epochs 50 --batch 16 --imgsz 640训练过程中盯两个信号loss 曲线是否前 10 个 epoch 明显下降mAP0.5 是否在 20 epoch 前后进入爬升阶段。如果 50 epoch 后 mAP0.5 始终在 0.4 以下大概率不是模型能力问题而是标注坐标或类别编号有系统性错误。一份干净的单类别小数据默认参数下通常能跑到 0.7 以上。5.2 用框尺寸分布判断是否需要多尺度训练由于图像分辨率跨度大同一个归一化w值在不同图上对应的像素宽度能差好几倍。我习惯跑一段快速统计看归一化宽度的分位数import glob import numpy as np ws [] for f in glob.glob(datasets/labels/val/*.txt): for line in open(f): parts line.strip().split() if len(parts) 5: ws.append(float(parts[3])) ws np.array(ws) print(归一化宽度分位:, np.percentile(ws, [10, 25, 50, 75, 90]))如果中位数在 0.15 到 0.3 之间且分布比较集中使用 640 的输入尺寸就能覆盖大多数目标如果大量框的w低于 0.1说明小目标占比高应该考虑把imgsz提到 960 或开启多尺度训练并在推理时使用更大输入尺寸。这个判断比盲目堆数据更有效也是我评估一份数据集是否值得深挖的第一道工序。从那以后我每次拿到下载的数据都会强制走一遍“可视化 → 数量核对 → 跑默认基线 → 看框分布”这套流程肉眼确认样本没问题才让训练循环启动这个习惯帮我避开过不少表面漂亮实则坐标错乱的数据。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询