使用 MONAI 加载和保存各种格式的医学图像

本教程属于实战,手把手教你加载各种医学图像数据(nii.gz, .dcm, .png等)。并学会查看医学图像数据的元数据(shape, affine, orientation)。学会使用monai全方位了解你的数据,并把它用于之后的深度学习训练。以及学会保存transform处理后的图像以及分割结果。干货很多,动手跟着一起来。

查看本教程前,请自行下载参考代码,边跑代码边看教程,学习效率更高哦

使用默认 image reader 加载 Nifti 图像

monai 根据文件后缀选择默认阅读器:

  • nii、nii.gz -> NibabelReader
  • png、jpg、bmp -> PILReader
  • npz、npy -> NumpyReader
  • 其他 -> ITKReader

开始实验前准备你的 nifti 格式图像,

filename = '/Users/Downloads/WORD-V0.1.0/imagesTr/word_0002.nii.gz'

如果没有,可以下载monai的示例

# download a test image
tempdir = tempfile.mkdtemp()
test_url = "https://github.com/Project-MONAI/MONAI-extra-test-data/releases/download/0.8.1/avg152T1_RL_nifti.nii.gz"
filename = os.path.join(tempdir, "avg152T1_RL_nifti.nii.gz")
monai.apps.download_url(test_url, filepath=filename)

接下来使用LoadImage加载图像

data = LoadImage(image_only=True, ensure_channel_first=True, simple_keys=True)(filename)
print(f"image data shape: {data.shape}")
print(f"meta data: {data.meta.keys()}")

参数解析

  • image_only: 默认为True,只返回图像;if False, 返回的data就是tuple, image=data[0], metadata(元数据)=data[1]
  • ensure_channel_first:默认为False, if True, 会给图像加一个channel,假如图像shape=[512, 512, 64], 加了channel就变成[1, 512, 512, 64]. 这在深度学习训练中基本都是要设为True, 向本教程的目的是加载图像的话,就不必设为True
    其余参数可以在pycharm源代码里查看

接下来,重点解释一下元数据,这是医学图像独有的信息。可以使用data.meta获取所有的元数据。包括

打勾的几个数据就是我平时用的比较多的,比如做图像分割的时候,要保存图像和分割结果,就需要知道affine信息。分割结果命名想同图像命名对应的时候,就需要知道filename_or_obj.

加载进来的3D图像如何展示出来呢?可以使用monai.visualize.matshow3d功能。

data1 = monai.transforms.Orientation("IPL")(data) # (Left, Right), (Posterior, Anterior), (Inferior, Superior).
fig = monai.visualize.matshow3d(volume=data1, # title='abdomen CT', figsize=(20,20),frames_per_row=6, frame_dim=-3,channel_dim=0,every_n=5,vmin=-300, vmax=600,cmap='gray',fill_value=255)

关于matshow3d函数的更多使用技巧,参考这篇文章【添加文章地址】

加载3D DICOM 图像

LoadImage同样支持加载DICOM图像和DICOM文件夹

filenames = ['/Users/Downloads/CBA60D87FAB145C3A9EB31A1C371C07E/0F9B3029D79B4B7DBE18776D284BB713.dcm','/Users/Downloads/CBA60D87FAB145C3A9EB31A1C371C07E/0F9B3029D79B4B7DBE18776D284BB713.dcm']folder_path = '/Users/Downloads/CBA60D87FAB145C3A9EB31A1C371C07E'# load single image
# data = LoadImage(image_only=True)(filenames)# load  DICOM series
data = LoadImage(image_only=True, ensure_channel_first=True)(folder_path)
print(f"image data shape: {data.shape}")

使用data.meta也可以查看元数据

加载 2D PNG图像

# 下载png图像
tempdir = tempfile.mkdtemp()
filename = os.path.join(tempdir, "MONAI-logo_color.png")
monai.apps.download_url("https://monai.io/assets/img/MONAI-logo_color.png", filepath=filename)data, meta = LoadImage(image_only=False, reader="PILReader", reverse_indexing=False)(filename)
fig = monai.visualize.matshow3d(data, frame_dim=-1)
print(f"image data shape: {data.shape}")
print(f"meta data: {meta}")

保存图像

例如在图像分割中,想保存分割结果或者预处理后的图像。可以使用SaveImage方法。代码以Nifti图像格式为例

假设加载图像并进行了一些transform

# 假设加载图像并进行了一些transform
filenames = '/Users/Downloads/WORD-V0.1.0/imagesTr/word_0002.nii.gz'
transform = Compose([LoadImaged(keys="image", image_only=True, ensure_channel_first=True),Resized(keys="image", spatial_size=[256, 256, 240])]
)
test_data = {"image": filenames}
result = transform(test_data)
print(f"image data shape:{result['image'].shape}")
print(result["image"].affine)

保存处理后的图像

img = result["image"]
saver = SaveImage(output_dir='./output',output_ext=".nii.gz",output_postfix="trans",# output_dtype=np.uint8, # type改变,保存出来的图像变化大,慎重选择typeresample=False,squeeze_end_dims=True,writer="NibabelWriter",
)
img = saver(img)

SaveImage将图像(可以是torch tensor或numpy ndarray的形式)和元数据字典保存到文件中。

保存的文件名将为{input_image_name}_{output_postfix}{output_ext},其中input_image_name是从提供的元数据字典中提取的。如果没有提供元数据,将使用从0开始的递增索引作为文件名前缀。

重要参数解析

  • output_ext:输出扩展名
  • output_postfix:输出后缀,默认为trans,如果输出是分割结果,可以设为seg, 最后文件名就是:{input_image_name}_seg.nii.gz
  • resample: 布尔值。if True, 就会重采样到原始图像大小。适用于在transform中对image做了采样后,保存分割结果又重新采样回去。使得分割结果同原始图像一样大小。此操作会利用原始图像元数据信息的spatail_shape以及original_affine.
  • squeeze_end_dims:if True, 去掉为1的维度,比如chanenl维度一般为1,保存的时候【C,H,W,D】-> 【H, W, D】
  • writer: 可以设置为 None,自动根据 output_ext 来选择合适的读写器。也可以是[“NibabelWriter”、“ITKWriter”、“PILWriter”]

当然,你也可以手动指定 metadata, 以及 filename

saver(img, meta_data=img.meta, filename='img_trans.nii.gz')

注意:这个要看版本,1.3版本没有filename

总结:图像的输出非常依赖于元数据(metadata), 对医学图像不是很熟悉的,重点关注本次内容中关于元数据的部分。monai的好处是加载图像后,图像的元数据(image dir, affine, spatial shape等信息全部都保存下来了,只需要img.meta就可以调出来)。

文章持续更新,可以关注微公【医学图像人工智能实战营】获取最新动态,一个关注于医学图像处理领域前沿科技的公众号。坚持以实践为主,手把手带你做项目,打比赛,写论文。凡原创文章皆提供理论讲解,实验代码,实验数据。只有实践才能成长的更快,关注我们,一起学习进步~

我是Tina, 我们下篇博客见~

白天工作晚上写文,呕心沥血

觉得写的不错的话最后,求点赞,评论,收藏。或者一键三连
在这里插入图片描述

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

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

相关文章

Leetcod面试经典150题刷题记录 —— 链表篇

Leetcod面试经典150题刷题记录-系列Leetcod面试经典150题刷题记录——数组 / 字符串篇Leetcod面试经典150题刷题记录 —— 双指针篇Leetcod面试经典150题刷题记录 —— 矩阵篇Leetcod面试经典150题刷题记录 —— 滑动窗口篇Leetcod面试经典150题刷题记录 —— 哈希表篇Leetcod面…

pytorch安装

pytoch安装 1. 准备工作1.1 需要提前安装的软件 2. 安装pyTorch我遇到的问题 3. 显卡测试4. CPU与GPU切换方法4.1 创建张量4.2 第一种切换方法4.3 第二种切换方法 1. 准备工作 1.1 需要提前安装的软件 Anaconda 史上最全最详细的Anaconda安装教程CUDA CUDA安装教程&#xff0…

让充电器秒供多个快充口,乐得瑞推出1拖2功率分配快充线方案

随着PD3.1协议的市场应用越来越多,一些充电器的Type-C接口的输出功率达到百瓦及以上,如何充分利用好这类充电器设备,乐得瑞电子推出1拖2快充线缆解决方案,支持智能功率分配策略支持私有快充协议。 如上图是乐得瑞1拖2功率分配快充…

WWDG---窗口看门狗

一.简介 窗口看门狗跟独立看门狗一样,也是一个递减计数器不断的往下递减计数,必须在一个窗口的上限值(用户定义)和下限值(0X40,固定不能变)之间喂狗不会复位,在上限值之前和下限值之…

Flink自定义Source模拟数据流

maven依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.…

OpenCV | 光流估计

光流估计 光流是空间运动物体在观测成像平面上的像素运动的“瞬时速度”&#xff0c;根据各个像素点的速度的速度矢量特征&#xff0c;可以对图像进行动态分析&#xff0c;例如目标跟踪 高度恒定&#xff1a;同一点随着时间的变化&#xff0c;其亮度不会发生改变。小运动&…

ProtoBuf一些踩坑记录

一、Protobuf学习基础 学习的资料很多也很全&#xff0c;这里添加几个链接进行Protobuf的基础学习的链接&#xff0c;链接中的案例使用C编辑&#xff1a; 链接&#xff1a;Protobuf介绍及简单使用(上&#xff09;_google_protobuf_version-CSDN博客 Protobuf介绍及简单使用(下&…

MFC综合实验二学习记录

文章目录 如何确定消息映射宏中命令对应的菜单项资源虚函数和纯虚函数的区别&#xff1f;MFC中什么是UPDATE_COMMAND_UI 消息如何查看控件对应的成员变量模态对话框的理解HGDIOBJ" 类型的值不能用于初始化 "CBrush *" 类型的实体错误MFC编程中CDC类型和HDC类型有…

TOP 9 安卓手机系统和应用程序修复工具,可修复各种Android 系统问题

您的新 Android 手机可能因其令人兴奋的性能而印象深刻。然而&#xff0c;随着时间的推移&#xff0c;您可能会发现系统有些地方与以前不太一样。您可能会遇到屏幕无响应、 Android应用程序崩溃、连接问题、电池耗尽等现象。 好吧&#xff0c;在这些情况下您不必感到不安&…

centos通过yum安装redis

1. 安装yum添加epel源(此步根据环境&#xff0c;如果有源则可跳过&#xff0c;在阿里去可跳过&#xff09; yum install epel-release 2 使用yum安装Redis yum install redis 出现如下图所示的内容&#xff0c;默认的安装路径是在 /usr/bin目录下&#xff1a; 文件安装路径…

uniapp 微信小程序跳转至其他小程序

一、背景&#xff1a; 需要在目前的小程序中跳转到另一个小程序&#xff0c;跳转的目标小程序需要已经发布上线了 二、具体实现 使用uni.navigateToMiniProgram打开另一个小程序 官网指引&#x1f449;&#xff1a;uni.navigateToMiniProgram(OBJECT) | uni-app官网 <t…

iview 选择框远程搜索 指定筛选的参数

问题&#xff1a;开启了filterable之后&#xff0c;选择框是允许键盘输入的&#xff0c;但是会对选择列表进行过滤&#xff0c;如果不想使用再次过滤&#xff0c;可以试下下面这个方法。 场景&#xff1a;输入加密前的关键字筛选&#xff0c;选择框显示加密后的数据 说明一&a…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存&#xff08;C&#xff09;&#xff09; Baumer工业相机Baumer工业相机的图像高速保存的技术背景Baumer工业相机通过NEOAPI SDK函数图像高速保存在NEOAPI SDK里实现线程高速图像保存&#xff1a;工业相机高…

rke2 offline install kubernetes v1.26

文章目录 1. 准备2. 安装 ansible3. 基础配置3.1 配置 hosts3.2 安装软件包3.3 内核参数3.4 连接数限制3.5 关闭swap 、selinux、防火墙3.6 时间同步 4. RKE2 安装4.1 下载安装4.2 配置其他管理节点4.3 新增 worker 节点 1. 准备 7 台主机 主机名ipcpu内存diskos角色user密码…

11.3编写Linux串口驱动

编写串口驱动主要步骤 构建并初始化 struct console 对象&#xff0c;若串口无需支持 console 可省略此步骤 //UART驱动的console static struct uart_driver virt_uart_drv; static struct console virt_uart_console {//console 的名称&#xff0c;配合index字段使用&…

unity C#中Array、Stack、Queue、Dictionary、HashSet优缺点和使用场景总结

文章目录 数组 (Array)列表 (List<T>)栈 (Stack<T>)队列 (Queue<T>)链表 (LinkedList<T>)哈希表 (Dictionary<TKey, TValue>) 或 HashSet<T>集合 (Collection<T>) 数组 (Array) 优点&#xff1a; 高效访问&#xff1a;通过索引可以…

1-04C语言执行过程

一、概述 本小节主要讲解一个C程序从源代码到最终执行的过程&#xff0c;这个过程又可以细分为两部分&#xff1a; 源代码到可执行文件的过程可执行文件在内存中执行 本小节是C语言基础当中&#xff0c;比较容易被初学者忽视的知识点。而实际上&#xff1a; 熟悉C程序从源文…

前端超好玩的小游戏合集来啦--周末两天用html5做一个3D飞行兔子萝卜小游戏

文章目录 💖飞行兔子萝卜小游戏💟效果展示💟代码展示源码获取💖飞行兔子萝卜小游戏 💟效果展示 💟代码展示 <body> <script src=

如何选猫粮:买主食冻干猫粮需要注意什么?

随着养猫的人越来越多&#xff0c;铲屎官们对猫咪的饮食也越来越注重。除了猫粮&#xff0c;很多铲屎官还会给猫咪准备小零食。那么&#xff0c;猫咪是不是除了猫粮就没有其他可吃的了呢&#xff1f;答案当然不是。猫咪还有猫冻干、冻干猫粮、猫条等可以选择。每个铲屎官都希望…

【MySQL】索引基础

文章目录 1. 索引介绍2. 创建索引 create index…on…2.1 explain2.2 创建索引create index … on…2.3 删除索引 drop index … on 表名 3. 查看索引 show indexes in …4. 前缀索引4.1 确定最佳前缀长度&#xff1a;索引的选择性 5. 全文索引5.1 创建全文索引 create fulltex…