使用 Monai 和 PyTorch 预处理 3D Volumes以进行肿瘤分割

news2025/1/11 19:50:10

1.介绍

针对在使用传统图像处理工具时可能遇到的困难,深度学习已成为医疗保健领域的主要解决方案。

因为医学图像比标准图像更难处理(高对比度、人体的广泛变化……)深度学习用于分类、对象检测,尤其是分割任务。

在分割方面,深度学习用于分割人体器官,如肝脏、肺和……或分割来自身体不同部位的肿瘤。

医学图像有很多不同的类型,例如 MRI(主要用于脑肿瘤分割)、CT 扫描、PET 扫描等。

本文将重点介绍 CT 扫描,但同样的操作也适用于其他类型。

所以我们知道执行深度学习任务需要许多步骤,其中一个是数据预处理,这是我们在开始训练之前必须做的第一件事。这是本文的主题;我们将讨论可用于执行此预处理的工具。

准备数据因任务而异;例如,分类是最简单的,因为我们只需要准备图像,而对象检测和分割则需要我们准备图像以及标签(用于分割的边界框或掩码)。

在本文中,我们将以分割为例,它可以用于肿瘤或器官的分割。

在医学成像中,我们可以处理 2D 图像,可以是 dicom、JPG 或 PNG,也可以是 3D 卷(volumes),它们是一组切片,每个切片是一个 2D 文件(大多数时候是 dicom),而这个组是一个nifti 文件,代表整个患者或仅代表他身体的一部分。

2.我们将使用的工具

为了完成这个任务,我们将使用一个名为 monai 的开源框架,它基于我在实习期间使用的 PyTorch,发现它非常有用。

如果您想阅读其文档,请参阅此链接。

3.方法

现在将开始编写我们的函数来执行 CT 扫描中肿瘤分割的预处理。第一步是使用 pip 或 conda 安装库,具体取决于您使用的环境。

pip install monai

我强烈建议你为你的项目设置一个虚拟环境,因为这个库直接安装在系统中时并不总是有效。

然后你需要安装 PyTorch 和一些 monai 的依赖。

pip install torch

pip install torch-vision

pip install "monai-weekly[gdwon, nibabel,tqdm]"

然后你需要包含你需要的库。

在这里插入图片描述
现在我们将讨论如何加载数据。对此有两种方法。

1- 第一种是单独加载图像和掩码(如果您想进行图像分类,可以使用这种方式,但它也适用于分割)。

2- 第二种方法是创建一个带有两列的Python字典,一列用于图像路径,一列用于标签路径。然后在每一行输入具有相应掩码的图像的路径。

就个人而言,我更喜欢第二种方法,因为当我们应用变换时,我们将能够只选择图像或标签或两者的关键工作,而不是为图像创建变换并为标签创建变换(掩码)。

您现在必须创建一个包含整个数据集路径的变量。就我而言,我有四个文件夹:TrainData、TrainLabels 训练图像和掩码和ValData、ValLabels 验证图像和掩码。

因此,要创建一个字典来存储路径,请使用以下代码行:
在这里插入图片描述

4.变换

要将多个变换应用于同一患者,我们将使用 monaicompose功能,它允许您组合所需的任何变换(在 monai 文档中定义的变换)。

在应用任何转换时,您应该注意一些事情:一些步骤是必需的,而另一些是可选的。

使用 monai 时,主要的转换是“Load image”以加载nifty的文件,以及“ToTensor”将转换后的数据转换为torch张量,以便我们可以将其用于训练。

现在我们已经介绍了基本的转换,我们将继续讨论其他转换。我将讨论在实习期间特别重要的五个转换。

AddChanneld:这个函数会为我们的图像和标签添加一个通道(当我说图像时,我是指多个切片的volume),因为我们在做肿瘤分割时,需要一个通道来扮演背景或肿瘤的角色。

Spacingd:这个函数将帮助我们改变体素维度,因为我们不知道医学图像数据集是通过相同扫描还是不同扫描获得的,因此它们可能具有不同的体素维度(宽度、高度、深度),所以我们需要将它们推广到相同的维度。

ScalIntensityRanged:这个函数将帮助我们同时执行两个任务:第一个是将密集视觉的对比度改变为更明显的东西,第二个是将体素值归一化并将它们置于 0 和 1 之间这样训练会更快。

CropForegroundd:这个功能将帮助我们裁剪掉我们不需要的图像的空白区域,只留下感兴趣的区域。

Resized:最后,这个函数是可选的,但在我看来,如果你使用了cropforeground函数,它是必需的,因为将进行裁剪的函数将根据每个患者的不同得到随机尺寸的输出,所以如果我们不添加为所有患者提供相同尺寸的操作,我们的模型将不起作用。
在这里插入图片描述
如您所见,我们使用的每个函数的末尾都有一个“d” ,这表示使用字典(如果您不使用字典,则需要将其删除)。我们为每个操作添加了参数“keys”,以指定我们是否希望将该变换应用于图像、标签或两者。您可以看到我们几乎将所有函数都应用于标签和图像,但在 ScaleIntensityRange 中我们只将其应用于图像,因为我们不需要更改标签的强度或标准化标签的值。

5.数据加载器

现在,与任何深度学习代码一样,我们必须先加载数据及其转换,然后才能开始训练;为此,必须使用两个基本功能。

Dataset:此函数将定义数据及其转换,因此如果您有训练集和验证集,则需要创建两个“数据集”函数,一个用于将训练数据与其转换组合,另一个用于组合验证数据及其转换。当然,如果对训练集和验证集应用相同的变换,则必须在函数dataset的参数transform中使用相同的变换。

Dataloader:这个函数将以特定的批处理大小将数据加载到RAM中。 将有两个数据加载器,一个用于训练,一个用于验证。
在这里插入图片描述

6.绘制一个例子

应用转换后,您可以绘制一些切片以查看使用和不使用转换的数据有何不同。

您可以使用 monai 函数“first”从数据加载器中获取第一个项目,这将是第一个患者。

以下是一些代码行,可帮助您绘制示例。
在这里插入图片描述
现在让我们看看有和没有转换的输出:
在这里插入图片描述
左边是没有变换的切片,中间是有变换的切片,右边是对应的标签。

这就是您使用 monai 准备进行 3D volumes分割的方式。如果你想看更多的变换,去monai的网站。但是,一些转换是为数据增强而不是预处理而设计的。

7.完整代码

import os
from glob import glob

import torch
from monai.transforms import (
    Compose,
    LoadImaged,
    ToTensord,
    AddChanneld,
    Spacingd,
    ScaleIntensityRanged,
    CropForegroundd,
    Resized,

)

from monai.data import Dataset, DataLoader
from monai.utils import first
import matplotlib.pyplot as plt

data_dir = 'D:/3_Stage/ALL_THE_DATA/fixed_data_03_august/all_together'

train_images = sorted(glob(os.path.join(data_dir, 'TrainData', '*.nii.gz')))
train_labels = sorted(glob(os.path.join(data_dir, 'TrainLabels', '*.nii.gz')))

val_images = sorted(glob(os.path.join(data_dir, 'ValData', '*.nii.gz')))
val_labels = sorted(glob(os.path.join(data_dir, 'ValLabels', '*.nii.gz')))

train_files = [{"image": image_name, 'label': label_name} for image_name, label_name in zip(train_images, train_labels)]
val_files = [{"image": image_name, 'label': label_name} for image_name, label_name in zip(val_images, val_labels)]


# load the images
# do any transforms
# need to convert them into torch tensors

orig_transforms = Compose(

    [
        LoadImaged(keys=['image', 'label']),
        AddChanneld(keys=['image', 'label']),
        
        ToTensord(keys=['image', 'label'])
    ]
)

train_transforms = Compose(

    [
        LoadImaged(keys=['image', 'label']),
        AddChanneld(keys=['image', 'label']),
        Spacingd(keys=['image', 'label'], pixdim=(1.5, 1.5, 2)),
        ScaleIntensityRanged(keys='image', a_min=-200, a_max=200, b_min=0.0, b_max=1.0, clip=True),
        CropForegroundd(keys=['image', 'label'], source_key='image'),
        Resized(keys=['image', 'label'], spatial_size=[128,128,128]),
        ToTensord(keys=['image', 'label'])
    ]
)


val_transforms = Compose(

    [
        LoadImaged(keys=['image', 'label']),
        AddChanneld(keys=['image', 'label']),
        Spacingd(keys=['image', 'label'], pixdim=(1.5, 1.5, 2)),
        ScaleIntensityRanged(keys='image', a_min=-200, a_max=200, b_min=0.0, b_max=1.0, clip=True),
        ToTensord(keys=['image', 'label'])
    ]
)


orig_ds = Dataset(data=train_files, transform=orig_transforms)
orig_loader = DataLoader(orig_ds, batch_size=1)

train_ds = Dataset(data=train_files, transform=train_transforms)
train_loader = DataLoader(train_ds, batch_size=1)

val_ds = Dataset(data=val_files, transform=val_transforms)
val_loader = DataLoader(val_ds, batch_size=1)

test_patient = first(train_loader)
orig_patient = first(orig_loader)

print(torch.min(test_patient['image']))
print(torch.max(test_patient['image']))
# tensor(-3024.)
# tensor(1911.7750)

plt.figure('test', (12, 6))

plt.subplot(1, 3, 1)
plt.title('Orig patient')
plt.imshow(orig_patient['image'][0, 0, : ,: ,30], cmap= "gray")

plt.subplot(1, 3, 2)
plt.title('Slice of a patient')
plt.imshow(test_patient['image'][0, 0, : ,: ,30], cmap= "gray")

plt.subplot(1,3,3)
plt.title('Label of a patient')
plt.imshow(test_patient['label'][0, 0, : ,: ,30])
plt.show()

参考目录

https://pycad.co/preprocessing-3d-volumes-for-tumor-segmentation-using-monai-and-pytorch/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/76436.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]计算机毕业设计健身生活系统论文Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

SQL注入漏洞 | updatexml报错注入

文章目录前言MySQL updatexml报错注入前言 XML XML 被设计用来传输和存储数据,是各种应用程序之间进行数据传输的最常用的工具。 xpath XPath 是一门在 XML 文档中查找信息的语言。XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在…

传统机器学习算法-支持向量机模型详解

原文链接 引言 本篇我们要讲解的模型是大名鼎鼎的支持向量机 SVM,这是曾经在机器学习界有着近乎「垄断」地位的模型,影响力持续了好多年。直至今日,即使深度学习神经网络的影响力逐渐增强,但 SVM 在中小型数据集上依旧有着可以和…

申请澳洲八大,IB成绩多高才有胜算?

鉴于IB文凭项目是全球通用的国际课程,因此几乎所有澳洲大学都可以接受IB文凭直接申请本科,包括澳洲八大。 首先我们要知道,澳洲八大究竟是哪八个顶级大学?澳洲的大学是按星级来分类的,五星级大学就是澳洲八大&#xff…

计算机网络期末复习题含解析(第一章)

目录 单项选择 填空题 判断题 单项选择 题号:25995 1.1.15 互联网服务提供商的英文缩写是()。 A、ISA B、ISP C、IXP D、RFC 答案: B ISP:Internet Service Provider 题号:25986 1.1.6 网络体系…

如何熟练掌握JDBC编程?

目录 🐳今日良言:未来可期,人生值得 🐂一、JDBC 🐼1.概念 🐼2.背景 🐼3.使用 🐯二、编写数据库代码 🐼1.增/删/改数据 🐼2.查数据 🐳今日良言:未来可期,人生值得…

机器学习笔记之受限玻尔兹曼机(六)对数似然梯度求解

机器学习笔记之受限玻尔兹曼机——对数似然梯度求解引言回顾:含隐变量能量模型的对数似然梯度受限玻尔兹曼机的对数似然梯度模型参数求解主体思路求解过程引言 上一节介绍了含隐变量能量模型的对数似然梯度求解。本节针对受限玻尔兹曼机,对模型参数进行…

c#入门-完全限定名,引用命名空间

完全限定名 包含完整命名空间的类名,称为完全限定名。 namespace 黄野平原.古堡 {class 蜡烛怪 { } }例如 黄野平原.古堡.蜡烛怪 a new 黄野平原.古堡.蜡烛怪();引用命名空间 但是很多的类都会写在命名空间下,如果全都这么写代码太长了。 为了省略掉…

Unity-Photon Pun2个人总结

进入房间前的配置 1、使用设定好的Setting private void Start(){PhotonNetwork.ConnectUsingSettings();} 2、MonoBehaviour改为MonoBehaviourPunCallbacks public class NetworkLauncher : MonoBehaviourPunCallbacks{} 这样我们才可以获得Photon服务端的一些反馈资料 3…

高考题改成IB试题,会是什么样子?

从2019年浙江高考语文卷的一篇现代文阅读说起的,振语看过了这道题和推文作者的解读后,一时兴起,就想着能不能把它改成一道IB考题,顺带着也把这篇选文细读评点了一番。(一)高考试题再现: 这道高考…

百趣代谢组学分享:HSFB2b通过促进类黄酮生物合成赋予大豆耐盐能力

​我国大豆的产量远远不能满足国内需求,提高大豆的耐逆性可以充分利用边际土地增加大豆种植面积从而提高大豆产量。百趣代谢组学分享,热激转录因子基因在植物生长过程中发挥了重要作用,然而在大豆耐盐反应中热激转录因子的功能及机理仍不清楚…

A-Level商务例题解析及练习Cash flow forecasting

今日知识点: Cash flow forecasting Cash inflows Cash outflows Limitations of cash flow forecasting例题 Q: Discuss the view that cash flow forecasts for a newly operating international airport may be of limited use to its senior managers. 解析 Ans…

Mysql 进阶(面向面试篇)事务篇

1、事务 1.1 事务简介 事务 是一组操作的集合,它是不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。保证原子性 就比如: 张三给李四转账1000块钱&#x…

仿英雄联盟网页HTML代码 学生网页设计与制作期末作业下载 大学生网页设计与制作成品下载 DW游戏介绍网页作业代码下载

🎉精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

推荐系统CTR方向相关论文一句话总结

Fearure Interaction // CTR纯FM模型及其演变Factorization Machines. 2010Field-aware Factorization Machines for CTR Prediction. 2016Neural Factorization Machines for Sparse Predictive Analytics. 2017Attentional Factorization Machines: Learning the Weight of F…

StringBuffer类

StringBuffer基本介绍 StringBuff代表可变的字符串,可以对字符串内容进行增删很多方法与String相同,但StringBuff是可变长度的StringBuff是一个容器 了解StringBuffer StringBuffer的继承关系: 可以看到StringBuffer继承AbstractStringBu…

【计网实验】思科CiscoPacketTracer仿真实验

本文参考B站up主:湖科大教书匠 软件版本:Cisco Packet Tracer 6.1.1sv ❓ 实验01的内容较为简单,所以不写了~ 🌹 因作者水平有限,若有遗漏、错误等地方,请大佬批评指正 实验02:访问Web服务器 实…

设计必备,5个png免抠素材网站,建议收藏

做设计、PPT都需要用到大量的免抠素材,职场中熟练使用Photoshop的人毕竟是少数,也很少有人愿意花费时间去精细抠图。那这5个免抠素材网站一定要收藏好,可以有效帮你节省时间,提高工作效率。1、菜鸟图库 https://www.sucai999.com/…

计算机毕业设计php+vue基于微信小程序的员工宿舍报修系统

项目介绍 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代,员工宿舍报修系统就是信息时代变革中的产物之一。 任何系统都要遵循系…

进程被杀Task被移除

现象 Kill查杀 Task被移除 当Task处于前台&Task中唯一的activity不处于onStop(可能处于onResume/onPause等)状态时,当前进程被kill查杀,当前activity会被finish导致task中因无activity而被移除。 12-08 15:20:54.991 18018…