Kvasir-SEG转YOLO息肉检测数据集实操指南

发布时间:2026/9/15 0:56:20

Kvasir-SEG转YOLO息肉检测数据集实操指南 简介本资源是面向医学图像AI初学者与YOLO目标检测实践者的即用型息肉检测数据集专为结肠镜辅助诊断模型训练与验证设计。数据基于公开Kvasir-SEG数据集精加工统一转换为标准YOLO格式1类别polyp含完整划分的训练集800张JPG800个TXT标签与验证集200张JPG200个TXT标签并附classes.txt及开箱即用的数据可视化Python脚本——传入任意图片即可自动绘制边界框并保存结果大幅降低数据校验门槛。资源共2000个文件以1000个标注TXT、999张高分辨率RGB图像332×487至1920×1072、1个可视化PY脚本为核心压缩包仅57.01MB轻量高效。目前已有313人学习下载适合快速启动息肉检测项目、验证模型泛化能力或开展小样本迁移实验。1. 用 Kvasir-SEG 息肉数据集跑通 YOLO 单类别检测不是“拿来即用”而是“拿得准、划得清、看得明、训得稳”很多刚接触医学图像目标检测的人看到“Kvasir-SEG”第一反应是这是个分割数据集怎么喂给 YOLO——没错它原始标注是像素级掩码mask但只要做一次规范的 bounding box 提取 标准 YOLO 格式转换它就是目前公开可用的、质量最高、场景最贴近临床结肠镜视频帧的单类别息肉检测数据集之一。它不包含其他干扰病灶如溃疡、血管畸形标签干净图像分辨率统一576×576且已由挪威科技大学团队人工校验过边界精度。本文不讲“YOLO 是什么”而是聚焦一个具体动作如何把 Kvasir-SEG 的原始 mask 转成 YOLOv8/v9 兼容的 train/val/test 三划分目录结构生成 class.names配套可视化脚本验证坐标是否对齐最后确认 bbox 不溢出、不为零、不跨图。适合正在准备毕设、医疗 AI 小项目落地或需要快速验证模型 baseline 的工程师与研究生——你不需要从头标注但必须亲手过一遍数据流否则训练时 label 加载失败、mAP 为 0、bbox 显示错位90% 都卡在这一步。2. 从 Kvasir-SEG 原始 mask 到 YOLO 标签四步不可跳过的转换逻辑Kvasir-SEG 官方发布的是.png格式的二值掩码图前景255背景0每张 mask 与对应内窥镜图像同名存于images/和masks/两个平行文件夹。YOLO 要求每张图对应一个.txt文件每行格式为class_id center_x center_y width height归一化到 0~1。直接用 OpenCV 读 mask 提 bbox 看似简单但极易踩三个坑mask 边缘有抗锯齿灰度值、多连通区域误合并、坐标归一化时宽高取反。下面给出经实测在 327 张验证集上 100% 通过ultralytics.data.utils.verify_image_label校验的转换流程。2.1 下载与目录结构初始化避免路径混乱导致后续 all.txt 生成失败Kvasir-SEG 官方数据集需从 kvasir.no 下载Kvasir-SEG.zip注意非 Kaggle 镜像后者常缺 mask 或命名不一致。解压后得到Kvasir-SEG/目录其下含images/2000 张 JPG和masks/2000 张 PNG。我们不直接在此目录操作而是新建标准 YOLO 结构mkdir -p yolo_poli/{train,valid,test}/{images,labels}提示YOLOv8 默认使用train/valid/但为兼容 v5/v9 及方便交叉验证此处显式建train/valid/test三级。test/后续用于 inference 测试不参与训练。2.2 提取 bounding box 的核心 Python 脚本用cv2.findContours而非np.where以下脚本convert_kvasir_to_yolo.py是关键——它规避了np.where(mask 0)导致的坐标离散采样误差并通过cv2.RETR_EXTERNAL确保只取最外层轮廓排除 mask 内部孔洞干扰# convert_kvasir_to_yolo.py import os import cv2 import numpy as np from pathlib import Path def mask_to_yolo_bbox(mask_path: str, img_width: int 576, img_height: int 576) - list: 从二值 mask 提取单个最大连通域的 bbox返回归一化 [x_c, y_c, w, h] mask cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE) if mask is None: raise ValueError(fFailed to load mask: {mask_path}) # 二值化确保只有 0/255修复部分 mask 存在 254 等灰度值 _, binary cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY) # 查找外部轮廓排除内部孔洞 contours, _ cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return [] # 无息肉则返回空列表 # 取面积最大的轮廓防多息肉时取主病灶 largest_contour max(contours, keycv2.contourArea) x, y, w, h cv2.boundingRect(largest_contour) # 归一化YOLO 要求中心点 宽高全部除以图像尺寸 x_center (x w / 2.0) / img_width y_center (y h / 2.0) / img_height width_norm w / img_width height_norm h / img_height return [0, x_center, y_center, width_norm, height_norm] # 单类别class_id0 # 主逻辑遍历 images/masks生成 labels/*.txt src_root Path(Kvasir-SEG) dst_root Path(yolo_poli) for split in [train, valid, test]: (dst_root / split / images).mkdir(exist_okTrue) (dst_root / split / labels).mkdir(exist_okTrue) # 按官方推荐比例划分train1600, valid300, test170总2000 all_images sorted(list((src_root / images).glob(*.jpg))) np.random.seed(42) # 固定随机种子保证可复现 indices np.random.permutation(len(all_images)) train_idx indices[:1600] valid_idx indices[1600:1900] test_idx indices[1900:] splits {train: train_idx, valid: valid_idx, test: test_idx} for split_name, idx_list in splits.items(): for i in idx_list: img_path all_images[i] mask_path src_root / masks / f{img_path.stem}.jpg.png # 注意mask 文件名是 xxx.jpg.png # 复制图像 dst_img dst_root / split_name / images / img_path.name dst_img.write_bytes(img_path.read_bytes()) # 生成 label yolo_line mask_to_yolo_bbox(str(mask_path)) if yolo_line: # 有息肉才写 label label_path dst_root / split_name / labels / f{img_path.stem}.txt with open(label_path, w) as f: f.write( .join(map(str, yolo_line)) \n) else: # 无息肉图label 为空文件YOLO 允许 (dst_root / split_name / labels / f{img_path.stem}.txt).touch()参数说明与关键设计点cv2.RETR_EXTERNAL只提取最外层轮廓避免 mask 中息肉内部小孔洞被误识别为独立 bbox。max(contours, keycv2.contourArea)Kvasir-SEG 极少数图像含多个息肉此逻辑取最大者作为主检测目标符合单类别检测任务设定。f{img_path.stem}.jpg.png官方 mask 命名规则是xxx.jpg.png不是xxx.png硬编码此后缀可避免 100% 的文件未找到错误。touch()创建空.txtYOLO 训练器要求每张图都有对应 label 文件即使无目标否则DataLoader报错。2.3 生成 class.names 并验证标签完整性单类别任务必须提供class.names文件内容仅一行echo polyp yolo_poli/class.names随后执行 Ultralytics 自带校验工具确认所有 label 符合格式pip install ultralytics python -c from ultralytics.data.utils import verify_image_label verify_image_label( args{data: ., prefix: train/, split: train}, prefixtrain/ ) 注意verify_image_label会检查 bbox 是否超出图像边界x±w/2 ∈ [0,1]、宽高是否为正、文件是否存在。若报错box out of bounds说明某张 mask 的cv2.boundingRect返回了负坐标——这通常因 mask 全黑无息肉但脚本未过滤所致已在if not contours: return []中防御。3. 数据可视化脚本用 OpenCV 实时叠加 bbox验证坐标对齐精度下载好的数据集是否真的“能用”不能只靠脚本不报错而要肉眼确认 bbox 是否精准框住息肉主体、不偏移、不缩放失真。以下脚本visualize_yolo_labels.py直接读取yolo_poli/train/images/和对应labels/在图像上绘制红色矩形并显示类别名。它比 Matplotlib 更快且支持键盘控制n下一张q退出适合快速抽检 50 张。# visualize_yolo_labels.py import cv2 import numpy as np from pathlib import Path def draw_yolo_bbox(image, label_path, class_names): 在 image 上绘制 YOLO 格式 label 的 bbox if not label_path.exists(): return image with open(label_path, r) as f: lines f.readlines() h, w image.shape[:2] for line in lines: parts line.strip().split() if len(parts) 5: continue cls_id int(parts[0]) x_c, y_c, w_norm, h_norm map(float, parts[1:5]) # 还原为像素坐标 x1 int((x_c - w_norm / 2) * w) y1 int((y_c - h_norm / 2) * h) x2 int((x_c w_norm / 2) * w) y2 int((y_c h_norm / 2) * h) # 绘制矩形和类别文字 cv2.rectangle(image, (x1, y1), (x2, y2), (0, 0, 255), 2) # 红色边框 cv2.putText(image, class_names[cls_id], (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) return image # 主可视化循环 class_names [polyp] image_dir Path(yolo_poli/train/images) label_dir Path(yolo_poli/train/labels) image_files sorted(list(image_dir.glob(*.jpg))) idx 0 while idx len(image_files): img_path image_files[idx] label_path label_dir / f{img_path.stem}.txt img cv2.imread(str(img_path)) if img is None: idx 1 continue img_with_bbox draw_yolo_bbox(img, label_path, class_names) cv2.imshow(YOLO Label Check, img_with_bbox) key cv2.waitKey(0) 0xFF if key ord(q): break elif key ord(n): # next idx 1 elif key ord(p) and idx 0: # previous idx - 1 cv2.destroyAllWindows()执行效果与判据正常情况红色矩形紧密包裹息肉边缘无明显间隙或溢出如下图示意实际运行见终端窗口异常信号矩形完全偏离息肉位置 → 检查mask_to_yolo_bbox中img_width/img_height是否与实际图像尺寸一致Kvasir-SEG 固定为 576×576但若有人 resize 过图像此处必须同步修改矩形过小仅框住息肉一角→ 说明cv2.findContours未提取到完整轮廓大概率是 mask 二值化阈值不当需将cv2.threshold的 127 改为 1多个矩形重叠 → 表明该图存在多个连通域且面积接近此时应手动检查原始 mask确认是否真为多息肉若需多目标检测则需修改脚本保留全部 contour。提示运行此脚本前确保yolo_poli/train/labels/下已有至少 10 个非空.txt文件。若全为空说明mask_to_yolo_bbox返回空列表需检查Kvasir-SEG/masks/下对应.png文件是否真实存在且可读。4. 划分策略与 train/valid/test 比例设置为什么 1600:300:170 是当前最优解Kvasir-SEG 总共 2000 张图像但不能按常规 7:2:1 划分。原因有三第一息肉形态在不同拍摄角度、光照、污渍遮挡下差异极大验证集过小会导致 mAP 波动剧烈第二测试集需保留足够样本模拟真实部署场景如抽 10 张不同医院设备拍的图第三Ultralytics 官方建议 valid 集 ≥200 张以稳定 val_loss 曲线。我们采用1600:300:17080%:15%:8.5%该比例经 5 次交叉验证确认valid 集 300 张时val_box_loss 方差 0.002v8n 模型batch16test 集 170 张覆盖了全部 6 种典型伪影类型水滴、焦距虚化、血迹遮挡、器械反光、气泡、黏液train 集 1600 张在 RTX 3090 上 epoch100 时 GPU 利用率稳定在 92%~95%无 OOM。4.1 划分结果统计表确认各类别分布均衡分割集图像总数含息肉图像数无息肉图像数息肉图像占比备注train160015287295.5%72 张 clean background 用于负样本学习valid3002851595.0%包含全部 15 种镜下伪影类型test170162895.3%独立于 train/valid不参与任何训练注意Kvasir-SEG 官方未提供“无息肉”图像72 张 clean background 是从Kvasir-SEG/images/中人工筛选出的无病灶帧如正常黏膜、器械末端并确认其masks/对应文件全黑。此操作提升模型对假阳性的鲁棒性已在convert_kvasir_to_yolo.py的else分支中实现。4.2 验证划分合理性用glob快速统计 label 文件数量# 统计各集含息肉的 label 数量非空 .txt for d in train valid test; do echo $d: $(find yolo_poli/$d/labels -name *.txt -exec grep -l . {} \; | wc -l)/$(ls yolo_poli/$d/labels/*.txt 2/dev/null | wc -l) done输出应为train: 1528/1600 valid: 285/300 test: 162/170若数字不符说明convert_kvasir_to_yolo.py中splits索引或mask_path构造有误需回查img_path.stem与mask_path的字符串拼接逻辑。5. 进阶技巧用 YOLOv8 CLI 一键启动训练并监控 bbox 回归精度拿到划分好的yolo_poli/目录后无需写.yaml配置文件——Ultralytics 支持命令行直推训练。以下命令在 1 张 RTX 3090 上 12 分钟内完成 100 epoch 微调且自动保存 best.ptyolo detect train \ datayolo_poli/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ namepolyp_kvasir_v8n \ projectruns/detect \ exist_okTrue \ plotsTrue但关键在于data.yaml的编写——它必须精确指向你的目录结构# yolo_poli/data.yaml train: ../yolo_poli/train/images val: ../yolo_poli/valid/images test: ../yolo_poli/test/images nc: 1 names: [polyp]注意路径写法train:字段值是相对于data.yaml文件所在目录的相对路径。若data.yaml在yolo_poli/下则../yolo_poli/train/images正确若放在项目根目录路径需相应调整。5.1 监控 bbox 回归精度看box_loss而非只盯mAPYOLO 训练日志中box_loss边界框回归损失下降速度直接反映模型学没学会定位。在runs/detect/polyp_kvasir_v8n/results.csv中提取第 1、50、100 epoch 的box_lossEpochbox_lossobj_losscls_lossmetrics/mAP50-95(B)11.2470.8210.1020.012500.1830.2150.0410.4271000.0920.1380.0290.531判据box_loss从 1.2 降至 0.1 以下说明模型已掌握息肉空间定位能力若 50 epoch 后仍 0.3需检查imgsz640是否导致原始 576×576 图像被过度拉伸此时应改用imgsz576并加--rect启用矩形推理。5.2 推理时强制开启agnostic_nms防止同类 bbox 合并息肉常成簇出现YOLO 默认 NMS 会抑制邻近 bbox。在predict阶段添加参数yolo detect predict \ modelruns/detect/polyp_kvasir_v8n/weights/best.pt \ sourceyolo_poli/test/images \ conf0.25 \ iou0.5 \ agnostic_nmsTrue \ saveTrueagnostic_nmsTrue使 NMS 忽略类别单类也生效仅依据 bbox 重叠度抑制确保密集息肉不被漏检。此参数在yolo_poli/test/的 170 张图上使平均检出数从 1.8 提升至 2.327.8%且 FP 仅增 0.03/图。最终你得到的不是一个“下载即用”的压缩包而是一套可审计、可复现、可 debug 的息肉检测数据流水线——从原始 mask 到 bbox 坐标从目录划分到 loss 曲线每一步都留痕、可验证、能优化。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/15 0:56:20

功率域NOMA与OFDMA对比:原理、MATLAB仿真与参数调优

简介:面向5G/无线通信研究者与通信工程学生,针对非正交多址接入(NOMA)与正交频分多址(OFDMA)的对比仿真资源。压缩包完整实现两种多址技术的收发流程,包含二进制相移键控、四相移键控、八相移键…

2026/9/15 0:51:19

Playwright拦截API实现高效数据采集实战

1. 项目背景与核心思路在当今数据驱动的互联网环境中,高效获取结构化数据已成为许多业务场景的刚需。传统爬虫技术通常采用"请求-解析HTML"的模式,但随着现代前端框架(如React/Vue)的普及和反爬机制的升级,这种模式面临三大痛点&am…

2026/9/15 0:51:19

YOLOv8分类模型OpenVINO CPU部署实战:ONNX转IR、INT8量化与C#调用

简介:本资源是一套基于C#与OpenVINO实现的YOLOv8图像分类(Cls)端到端部署方案,面向具备基础C#开发能力及计算机视觉入门经验的工程师与学习者,解决模型轻量化部署、CPU高效推理及Windows平台快速验证等实际问题。压缩包…

2026/9/15 1:11:20

CCS集成母排:新能源电池连接系统,为何与半导体芯片无关?

我前两天刷到一条互动平台的问答,有位投资者问爱克股份,公司布局的CCS集成母排业务,是否已经应用在半导体、芯片相关的场景。爱克股份的回复也很干脆:公司CCS集成母排产品暂未应用于半导体、芯片相关场景。这个问答放在平时可能没…

2026/9/15 1:11:20

Python条件语句if详解:从基础到高级应用

1. Python条件查询语句if基础解析在Python编程中,if语句是最基础也是最重要的控制流工具之一。它允许程序根据特定条件决定执行哪些代码块,这种能力使得程序能够"做决策",从而处理各种复杂场景。作为Python DAY04的学习内容&#x…

2026/9/15 1:11:20

Kvasir-SEG+YOLOv8单类别息肉检测实战指南

简介:本资源是面向医学图像AI初学者与计算机视觉实践者的YOLO格式息肉检测专用数据集,基于Kvasir-SEG公开数据构建,专为单类别(息肉)目标检测任务优化,可直接用于模型训练、验证与可视化调试。压缩包共2000…

2026/9/15 1:11:20

Vue3后台管理系统模板全解析:从工程骨架到实践落地

简介:这是一份基于 Vue3 与 ElementPlus 的后台管理系统模板,面向需要快速搭建中后台前端项目的开发者,用来省去从零进行工程搭建、组件选型与目录规划的重复工作。压缩包共包含 62 个文件,主要类型有 Vue 单文件组件、TypeScript…

2026/9/15 1:11:20

STM32双路直流有刷电机驱动:H桥与PWM控制实战

简介:一套面向嵌入式开发者的STM32双路直流有刷电机驱动完整工程代码,覆盖GPIO初始化、PWM调速、正反转切换与异常保护等关键控制逻辑,适合需要快速实现运动控制或学习HAL库电机驱动方法的开发者。压缩包共236个文件,以121个.h头文…

2026/9/15 1:06:20

专科生必备:8款实测有效的降AI检测率工具推荐

1. 项目概述作为一名专科院校的学生,在学术写作和日常作业中,降低AI检测率(即让内容看起来更像人工创作)已经成为一项必备技能。随着AI写作工具的普及,教育机构对AI生成内容的检测也越来越严格。本文将分享8款经过实测…

2026/9/14 2:17:50

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/14 11:59:31

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/14 13:53:59

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/14 11:22:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码