【Python】SimpleITK使用笔记

2023-05-16

文章目录

  • 1. 概念
    • 1.1 nii格式
    • 1.2 SimpleITK
    • 1.3 SimpleITK 图像
  • 2. 基本操作
    • 2.1 常见属性
    • 2.1 读取和保存图像
    • 2.2 SimpleITK图像数据和Numpy矩阵数据之间的转换

1. 概念

1.1 nii格式

nii 格式是保存医学图像非常重要一种格式,nii 格式就是后缀名为 .nii.nii.gz 的文件,该格式又叫 NIfTI-1。核磁共振成像(MRI)或者CT图像通常会以这种格式保存。详见

这种格式的作用,简单来理解就是将索引坐标映射到体素坐标。在nii格式中,为了将索引坐标(数组下标)映射到体素坐标(空间坐标),除了保存图像的数据外,即一个个离散的像素,还保存了一些额外信息,比如每个像素间的距离,原点坐标,方向等等,这样根据像素间的距离就可以计算某一像素在空间中真正的坐标了。

1.2 SimpleITK

SimpleITK 是专门处理医学影像的软件,是 ITK 的简化接口,使用起来非常便捷,SimpleITK 支持 8 种编程语言,包括c++、Python、R、Java、c#、Lua、Ruby 和 TCL。

1.3 SimpleITK 图像

在 SimpleITK 中,图像的概念与我们在计算机视觉中常用的RGB图像差异很大,后者只是一个多维矩阵,是一个数学上的概念,而在 SimpleITK 中图像是一个物理实体,图像中的每一个像素都是物理空间中的一个点,不光有着像素值,还有坐标、间距、方向等概念。

SimpleITK 图像是多维度的(2D~5D),包含以下元数据

  1. Origin:原点,起始点所在的坐标
  2. Spacing:不同维度像素之间的距离,每个体素之间的距离
  3. Size:不同维度的尺寸
  4. Direction:矩阵每个轴的方向,由于图像未必是正交,所以会用方向向量来指明不同轴的方向。

在这里插入图片描述

2. 基本操作

2.1 常见属性

sitk中有以下四种常见的属性,分别可以使用get的方式获取,代码如下所示:

# 获取图像的大小,size为图像的每一个维度的长度,即每个维度像素点的个数
# 读取的顺序为[X, Y, Z], 即先宽度,后高度,再深度,对应的三维医学图像中为:先矢状位,后冠状位,再横断位。
print(image.GetSize()) 

# 获取图像的原点坐标,读取顺序同GetSize()方法
print(image.GetOrigin()) 

# 获取每个维度上像素或体素之间的间距,单位mm,其中对于二维图像是像素,三维图像是体素
# 读取顺序同GetSize()方法, 每个维度可以具有不同的间距,且每个维度不一定是正交的。
print(image.GetSpacing()) 

# 获取图像的方向,即图像坐标系相对世界坐标系的角度,角度采用的是方向余弦矩阵
print(image.GetDirection()) 

2.1 读取和保存图像

SimpleITK 可以读取如 .mhd , .nii, .nrrd等图像数据格式。

读取图像

imagepath = "xxx.mhd"   # 图像路径
image1 = sitk.ReadImage(imagepath)
image2 = sitk.ReadImage(imagepath, sitk.sitkFloat32) # 同时可以指定读取的数据类型

保存图像

writepath = "xxx.mhd"  # 保存图像路径
sitk.WriteImage(image, writepath)

像素类型

在读取图片的时候可以指定像素类型,像素类型表示为枚举类型,下面是部分枚举类型的表

数据类型含义
sitkUInt8无符号8位整数
sitkInt8有符号的8位整数
sitkUInt16无符号16位整数
sitkInt16有符号的16位整数
sitkFloat3232位浮点

2.2 SimpleITK图像数据和Numpy矩阵数据之间的转换

SimpleITK 中,各术语对应如下

Width: 宽度,X轴,矢状面(Sagittal
Height: 高度,Y轴,冠状面(Coronal
Depth: 深度, Z轴,横断面(Axial

SimpleITK图像顺序是x,y,z三个方向的大小;而numpy矩阵的顺序是z,y,x三个方向的大小, 要注意索引位置。

SimpleITK2Numpy

GetArrayFromImage():返回图像数据的副本。然后可以自由地修改数据,因为它对原始SimpleITK图像没有影响。

# sitk image to numpy 
shape_img = image.GetSize() #输出形状为:(Width, Height, Depth),即原始SimpleITK数据的存储形式
print("image size:", shape_img) # image size:(320, 250, 80)

datanp_array = sitk.GetArrayFromImage(image)
print("np_array size:", np_array.shape) # np_array size:(80, 250, 320)

因为在训练时一般是[x, y, z],所以我们在dataset中需要将图像的坐标轴转换一下,即做一个transpose(2, 1, 0)操作。

Numpy2SimpleITK

GetImageFromArray():返回一个SimpleITK图像,原点设置为0,所有维度的间距设置为1,方向余弦矩阵设置为identity,强度数据从numpy数组中复制。在大多数情况下需要设置适当的元数据值。

# numpy data to sitk 
imagesitk_image = sitk.GetImageFromArray(np_array) 

# 转换完成后,设置元数据
sitk_image.SetOrigin(origin)
sitk_image.SetSpacing(spacing)
sitk_image.SetDirection(direction)

参考:
Python中SimpleITK库的常用函数
使用SimpleITK读取、保存、处理nii文件
SimpleITK学习笔记

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Python】SimpleITK使用笔记 的相关文章

  • 如何手动计算分类交叉熵?

    当我手动计算二元交叉熵时 我应用 sigmoid 来获取概率 然后使用交叉熵公式并平均结果 logits tf constant 1 1 0 1 2 labels tf constant 0 0 1 1 1 probs tf nn sigm
  • 使用 python requests 模块时出现 HTTP 503 错误

    我正在尝试发出 HTTP 请求 但当前可以从 Firefox 浏览器访问的网站响应 503 错误 代码本身非常简单 在网上搜索一番后我添加了user Agent请求参数 但也没有帮助 有人能解释一下如何消除这个 503 错误吗 顺便说一句
  • 需要在python中找到print或printf的源代码[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在做一些我不能完全谈论的事情 我
  • 使用 kivy textinput 的 'input_type' 属性的问题

    您好 我在使用 kivy 的文本输入小部件的 input type 属性时遇到问题 问题是我制作了两个自定义文本输入 其中一个称为 StrText 其中设置了 input type text 然后是第二个文本输入 名为 NumText 其
  • 如何使用 Pandas、Numpy 加速 Python 中的嵌套 for 循环逻辑?

    我想检查一下表的字段是否TestProject包含了Client端传入的参数 嵌套for循环很丑陋 有什么高效简单的方法来实现吗 非常感谢您的任何建议 def test parameter a list parameter b list g
  • datetime.datetime.now() 返回旧值

    我正在通过匹配日期查找 python 中的数据存储条目 我想要的是每天选择 今天 的条目 但由于某种原因 当我将代码上传到 gae 服务器时 它只能工作一天 第二天它仍然返回相同的值 例如当我上传代码并在 07 01 2014 执行它时 它
  • 从Python中的字典列表中查找特定值

    我的字典列表中有以下数据 data I versicolor 0 Sepal Length 7 9 I setosa 0 I virginica 1 I versicolor 0 I setosa 1 I virginica 0 Sepal
  • Python,将函数的输出重定向到文件中

    我正在尝试将函数的输出存储到Python中的文件中 我想做的是这样的 def test print This is a Test file open Log a file write test file close 但是当我这样做时 我收到
  • 如何使用python在一个文件中写入多行

    如果我知道要写多少行 我就知道如何将多行写入一个文件 但是 当我想写多行时 问题就出现了 但是 我不知道它们会是多少 我正在开发一个应用程序 它从网站上抓取并将结果的链接存储在文本文件中 但是 我们不知道它会回复多少行 我的代码现在如下 r
  • 如何通过索引列表从 dask 数据框中选择数据?

    我想根据索引列表从 dask 数据框中选择行 我怎样才能做到这一点 Example 假设我有以下 dask 数据框 dict A 1 2 3 4 5 6 7 B 2 3 4 5 6 7 8 index x1 a2 x3 c4 x5 y6 x
  • 加快网络抓取速度

    我正在使用一个非常简单的网络抓取工具抓取 23770 个网页scrapy 我对 scrapy 甚至 python 都很陌生 但设法编写了一个可以完成这项工作的蜘蛛 然而 它确实很慢 爬行 23770 个页面大约需要 28 小时 我看过scr
  • Jupyter Notebook 找不到 Python 模块

    不知道发生了什么 但每当我使用 ipython 氢 原子 或 jupyter 笔记本时都找不到任何已安装的模块 我知道我安装了 pandas 但笔记本说找不到 我应该补充一点 当我正常运行脚本时 python script py 它确实导入
  • 仅第一个加载的 Django 站点有效

    我最近向 stackoverflow 提交了一个问题 标题为使用mod wsgi在apache上多次请求后Django无限加载 https stackoverflow com questions 71705909 django infini
  • 根据列 value_counts 过滤数据框(pandas)

    我是第一次尝试熊猫 我有一个包含两列的数据框 user id and string 每个 user id 可能有多个字符串 因此会多次出现在数据帧中 我想从中导出另一个数据框 一个只有那些user ids列出至少有 2 个或更多string
  • Python ImportError:无法导入名称 __init__.py

    我收到此错误 ImportError cannot import name life table from cdc life tables C Users tony OneDrive Documents Retirement retirem
  • 使用for循环时如何获取前一个元素? [复制]

    这个问题在这里已经有答案了 可能的重复 Python 循环内的上一个和下一个值 https stackoverflow com questions 1011938 python previous and next values inside
  • 模拟pytest中的异常终止

    我的多线程应用程序遇到了一个错误 主线程的任何异常终止 例如 未捕获的异常或某些信号 都会导致其他线程之一死锁 并阻止进程干净退出 我解决了这个问题 但我想添加一个测试来防止回归 但是 我不知道如何在 pytest 中模拟异常终止 如果我只
  • Scipy Sparse:SciPy/NumPy 更新后出现奇异矩阵警告

    我的问题是由大型电阻器系统的节点分析产生的 我基本上是在设置一个大的稀疏矩阵A 我的解向量b 我正在尝试求解线性方程A x b 为了做到这一点 我正在使用scipy sparse linalg spsolve method 直到最近 一切都
  • Django-tables2 列总计

    我正在尝试使用此总结列中的所有值文档 https github com bradleyayers django tables2 blob master docs pages column headers and footers rst 但页
  • 如何应用一个函数 n 次? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 假设我有一个函数 它接受一个参数并返回相同类型的结果 def increment x return x 1 如何制作高阶函数repeat可以

随机推荐