当前位置: 首页 > news >正文

LIDC-IDRI数据集切割代码教程【pylidc库】

数据集:

通过网盘分享的文件:LIDC

链接: 百度网盘 请输入提取码 提取码: ywb8

代码:

通过网盘分享的文件:LIDC-IDRI-Preprocessing.rar

链接: 百度网盘 请输入提取码 提取码: b1za

【代码里的部分数据就不删了,方便你们照着放】

一、如何运行

1.输入

把数据集放到这个位置:

运行这个文件:

2.输出

下面文件夹里就是要的,clean文件里是过滤掉的

为方便模型分割我改成输出png格式的了,如果需要npy格式的自己改一下输出格式,复制给ai让ai改

在这里也有npy转png的工具类

二、原理和流程

核心文件

1.读取数据【把一个病人的肺部CT组合成3D图像】

  • 医院CT扫描后,一位病人的一整个肺部扫描,通常是几十上百张单独的 DICOM 文件。
  • 每一张DICOM相当于是一张灰度图片,比如 512x512 pixels。
  • 同一个病人的多张图片,沿着Z轴叠加,组成一个3D体积(Volume)。

每张DICOM除了图像,还有重要的元数据,比如:

  • Slice位置(在身体的哪个位置)
  • Pixel Spacing(像素大小,毫米)
  • Slice Thickness(切片厚度,毫米)
  • 这些元数据会影响图像在3D空间的实际物理大小。

把每个病人的 CT 扫描(DICOM文件)加载成一个3D体积数组, ,即 (height, width, slices) 这样的 numpy array。

让后续处理可以直接基于体素( 在三维医学影像里,一个小立方体就是一个体素 )操作,而不是一张张2D图片

pylidc.Scan.to_volume() ——>自动帮你把同一病人的多张 DICOM 按照 slice 位置组合成 3D Volume。

pylidc已经帮你处理了像素间距(pixel_spacing)、切片厚度(slice_thickness)的问题,所以可以直接拿来用。

2.获取结节标记【把不同医生标注的同一个结节聚集、放到一起】

读取医生的手绘结节区域,有些病人的一个结节可能有 多位医生各自独立标注。

scan.cluster_annotations()➔ pylidc的这个函数会自动根据医生的标注,把不同医生标的 同一个结节聚合(clustering) ,形成一个结节簇 (nodule cluster)。

  • 聚合之后,每个 "nodule cluster" 里面包含了1~4个医生给的单独mask。
  • 不同医生的标注大小、形状、位置会有细微差异。

3. 结节融合【生成共识掩膜、把上面放到一起的意见生成一个】

把多个医生的标注融合成一张最终的掩膜(mask), 不是简单取平均,而是根据设定的置信度(confidence_level),来决定哪些地方算是结节。

pylidc.utils.consensus()
➔ 这个函数内部会对所有医生的mask叠加,然后根据设定的置信度,比如 0.5,选取至少有一半医生认为是结节的区域。

小细节

  • padding 参数:扩展边界一点点,保证感兴趣区域 (ROI) 裁剪时不会把重要信息截断。
  • 有时候也能防止小结节被裁掉。

4. 小块裁剪(提取ROI) 【把肺上的结节裁出来】

  • 只取出 包含结节的小立方体区域
  • 不用处理整个大肺部Volume,加快后续处理速度,同时专注于结节本身。

直接索引裁剪 numpy 3D array:volume[cbbox], cbbox是 consensus 给出的bounding box,确定了x, y, z范围。 这样裁剪出来的3D小块,里面的像素就是肺部的一部分+结节。

5. 插值补齐(统一切片数量) ——可以在这里改变你想要的数量

有的裁剪块厚,有的薄,为了训练深度学习,需要统一每个样本的切片数(例如统一到120片)。如果原本切片数不够,就做插值上采样

scipy.ndimage.zoom()
➔ 对第三个维度(z轴)做缩放插值。

  • 插值后要确保最终切片数恰好是目标值(如120 slice)。
  • 这里用的是线性插值 (order=1),平滑过渡,不会产生噪点。

6. 遍历切片(过滤小面积掩膜)

每一片切片都单独检查:

  • 如果当前mask面积太小(比如很少像素是结节区域),就跳过这张片
  • 这样避免保存很多无意义的图片。

判断掩膜面积:np.sum(mask[:, :, slice_idx]), 阈值来自 config 文件里的 mask_threshold 参数。

这样可以大大减少无效样本,提升训练时数据质量。

7. 肺部分割(清理背景)【去除所有非肺部区域、 如气管、肺外的组织等】

把CT切片上除了肺以外的部分(比如骨骼、气管)剔除,只留下纯净的肺部区域。

segment_lung() 函数(项目自带的)

  • 典型实现是:
    • K-Means 聚类找出低密度的肺部。
    • 形态学操作(如闭运算)连通肺部区域。
    • 再用 largest connected component 提取左右肺叶。

1. 聚类算法:无监督学习算法、根据数据点之间的相似性来将其分组

2. K-Means: 一种聚类算法、 用于将数据分成多个类别(或簇)

将数据中的样本点分配到预定数量的簇中,使得簇内的样本点相似度尽可能高,而簇之间的样本点相似度尽可能低。

a. K-Means 算法的工作原理:
  1. 初始化:选择 K 个初始簇的中心(通常随机选择 K 个点)。
  2. 分配:将每个数据点分配到离它最近的簇中心。
  3. 更新:计算每个簇的平均值,并将这个平均值作为新的簇中心。
  4. 迭代:重复步骤 2 和 3,直到簇中心不再变化,或者变化非常小,达到收敛条件。
b. K-Means 算法应用在肺部分割中的作用:
  • 我们可以将这些点分成两个簇,一个簇表示肺部的低密度区域,另一个簇表示高密度区域(如骨骼)
  • 低密度区域(肺部)会被分到一个簇中。——我们要的
  • 高密度区域(骨骼、血管等)会被分到另一个簇中。

3. 形态学操作:处理图像中形状的方法

更简单举个例子

想象一张黑白图片:

  • 白色代表肺部
  • 黑色代表背景

但这张图可能:

  • 有很多小白点噪声(误判成肺)
  • 肺部有小黑洞(断开的地方)

这个时候,

  • 形态学操作可以帮我们"修修补补",
    让真正的肺叶连起来,让错误的小噪声消失掉

就像是在清洗、修整一张地图,让肺部轮廓干净漂亮。

常见四种形态学操作

操作

直白解释

用在哪

腐蚀 (Erosion)

白色区域缩小、收缩,小白点会被吃掉

去掉小的噪声点

膨胀 (Dilation)

白色区域变大、扩张,小洞被补起来

连通断开的部分

开运算 (Opening)

腐蚀 + 膨胀

清理小白点,但不影响大块肺部

闭运算 (Closing)

膨胀 + 腐蚀

填补小黑洞,连接断裂的肺叶

腐蚀:用一个5X5的滑动窗口扫描,如果周围都是0,那就把中间这个像素填成0

用 K-Means 聚类找出低密度的肺部+ 形态学操作(如闭运算)连通肺部区域可以减少模型搜索的60%空间:

  • 肺只占整幅CT的约30%~40%,剩下的60%~70%都是没用的背景、骨头——> 感兴趣区域
  • 跳过背景噪声

传统的方法是: 灰度阈值分割——>肺部分割精度差,边界不平滑、无法处理复杂区域(气管、血管等)和小结节

(原始的肺部区域体积-优化后的区域体积)/原始肺部区域体积X100%=减少的模型搜索空间

8. 保存图像(肺部切片 + 掩膜)

  • 把分割好的单张切片(肺部图像)和对应的掩膜(mask)分别保存为 PNG 文件
  • 每个病人有单独的文件夹,按slice编号存。
  • matplotlib.pyplot.imshow() + savefig()
  • 保存时关掉坐标轴(axis('off')),并去除白边(bbox_inches='tight', pad_inches=0)。
  • 保存一张图后用 plt.clf() 清空画布,防止内存泄漏。

9. 保存Meta信息表

  • 记录每一张图片的元数据(病人ID、结节编号、切片编号、图像文件名、掩膜文件名、恶性程度、是否癌症、是否是干净片)
  • 最后把所有记录保存成CSV表格,供训练/验证时检索。
  • 是否癌症、是否清洁图(is_cancer, is_clean)也是直接存在meta里面,免得推理时重复计算。
http://www.xdnf.cn/news/160993.html

相关文章:

  • 【Linux】web服务器的部署和优化
  • 大规模数据同步后数据总条数对不上的系统性解决方案:从字段映射到全链路一致性保障
  • dav_pg12_表膨胀系列一 优化
  • Android学习总结之自定义View绘制源码理解
  • 正确应对监管部门的数据安全审查
  • AI算法优化建筑形态与能耗管理 实现方案和技术架构
  • RT-Thread学习笔记(四)
  • 财务管理域——经营决策支持系统
  • Day102 | 灵神 | 二叉树 合并二叉树
  • 开发首个Spring Boot应用
  • 访问Redis时遇到 unknown command ‘FT.INFO‘, with args beginning with 错误的解决方案
  • MATLAB中调用CPLEX求解工具箱
  • Python + Playwright:如何在Docker 容器运行测试?
  • 0x27 A* + 0x28 IDA*
  • Adobe Photoshop(PS)2022 版安装与下载教程
  • 前端开发本地配置 HTTPS 全面详细教程
  • HackMyVM - Chromee靶机
  • 人工智能:入门阶段学习路径
  • per-task affinity 是什么?
  • 30天通过软考高项-第四天
  • Python循环语句-for循环(基础语法,range语句,临时变量作用域,嵌套应用)
  • 【计算机视觉】CV实战项目- DFace: 基于深度学习的高性能人脸识别
  • leetcode201.数字范围按位与
  • S参数的含义
  • 如何搭建和管理 FTP 服务器
  • 电商秒杀系统技术栈与难点解析 - Java架构师面试实战
  • 《Vue3学习手记5》
  • Redux和MobX有什么区别
  • 通过Golang实现快速实现MCP Server
  • 如何创建成员内部类数组