医学影像中用 python 读取 nrrd 文件,nrrd转nii,以及遇到的一些问题和解决方法

遇到的问题:

TypeError: Cannot handle this data type: (1, 1, 237), <f8

如果只想看解决方法,直接跳到第四点

用 python 读取 nrrd 文件:

用 python 读取 nrrd 文件一般使用 pynrrd 这个库

1、安装pynrrd:

// pip 安装
pip install pynrrd

完成后进入python IDLE

// 检查nrrd是否安装成功
import nrrd

如果是正常使用的话,这样安装就完全OK了,但是如果相对 nrrd 做出一些贡献:

pip install git+https://github.com/mhe/pynrrd.git
cd pynrrd
pip install .  // 注意不要忘了最后的小点 

完成后像上面一样测试一下是否安装成功

2、安装成功之后读取 nrrd 文件

//先导入 nrrd 库
import nrrd
data_path=r'你自己的 nrrd 文件路径’
data,options=nrrd.read(data_path)  # 读入 nrrd 文件
'''
data:保存图片的多维矩阵;
nrrd_options:保存图片的相关信息
'''
可以打印查看data 和 nrrd_options 里面的内容:
print(data)
print(options)

输出结果:

data:
[[[-3024 -3024 -3024 … -3024 -3024 -3024]
[-3024 -3024 -3024 … -3024 -3024 -3024]
[-3024 -3024 -3024 … -3024 -3024 -3024]



[-3024 -3024 -3024 … -3024 -3024 -3024]
[-3024 -3024 -3024 … -3024 -3024 -3024]
[-3024 -3024 -3024 … -3024 -3024 -3024]]]

options:
OrderedDict([(‘type’, ‘int’), (‘dimension’, 4), (‘space’, ‘right-anterior-superior’), (‘sizes’, array([ 3, 512, 512, 237])), (‘space directions’, array([[ nan, nan, nan],
[-0.703125, 0. , 0. ],
[ 0. , -0.703125, 0. ],
[ 0. , 0. , 1.25 ]])), (‘kinds’, [‘RGB-color’, ‘domain’, ‘domain’, ‘domain’]), (‘endian’, ‘little’), (‘encoding’, ‘gzip’), (‘space origin’, array([ 200.2, 186.2, -279. ])), (‘measurement frame’, array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])), (‘DICOM.instanceUIDs’, ‘…’), (‘MultiVolume.DICOM.EchoTime’, ‘’), (‘MultiVolume.DICOM.FlipAngle’, ‘’), (‘MultiVolume.DICOM.RepetitionTime’, ‘’), (‘MultiVolume.FrameIdentifyingDICOMTagName’, ‘AcquisitionTime’), (‘MultiVolume.FrameIdentifyingDICOMTagUnits’, ‘ms’), (‘MultiVolume.FrameLabels’, ‘0.0,12131.054999999702,24276.126000000164’), (‘MultiVolume.NumberOfFrames’, ‘3’)])

3、查看 nrrd 文件的形状

print(data.shape)

(512, 512, 237)

正常情况下读取出来的 nrrd 数据应该都是类似这种的格式:[w, h, n]
第三维度保存的是图像的序号;
但是在一些情况先我们读出来的数据格式是:[c, w, h, n] ;这乍一看没啥为题,就是多了第一维度的通道信息。
这没毛病,但是在后面我们进一步处理的时候可能就会报错,因为这毕竟是医学影响数据,我们是要将其转换为图像数据的吧。

**

4、将 nrrd 矩阵转换为图像数据

我的 nrrd 文件转成图像后是用于深度学习,
data.shape = (3, 512, 512, 237)
所以就先将其转换为PIL 格式(需要用到PIL库)

//安装PIL库
pip install pillow
import PIL  # 测试PIL库是否安装成功

from PIL import Image
img=Image.fromarray(data[:,:,20]) # 截取前20张图片

但是就在这里,报了一个错:

TypeError: Cannot handle this data type: (1, 1, 237), <f8

究其原因,是因为[c, w, h, n]中,c的原因;如果要想成功的将其转换为图像数据,可以使用下面这条命令

img=Image.fromarray(data[1,:,:,20]) # 截取第一个通道的前20张图片

但是我经过对比,发现三个通道上的信息不同,如果随意选择一个进行提取,那么就会丢失另外两个通道的信息。后面我问其他人,他们说第一个维度上的数值还有为 2 的,瞬间就给我整懵了。
后来经过查询以及对三个通道的图像对比,怀疑第一维度上面的信息可能表示 患者接受扫描的期相,1 表示平扫,只有一期;2 表示增强,有动脉期和静脉期;3 表示造影,有动脉期、静脉期和平衡期。
同时从扫描角度考虑,在这几个扫描期相中,患者的位置是相对固定的,也就是说我们可以随意选择其中一个期相都可以;但是反过来,我们可以将所有期相的数据都利用上。
如果只是想随意选择其中的一个期相,使用上面一个命令即可,如果想将所有的期相都用起来,那么需要增加一个循环。

for j in range(img.shape[0]):
	for i in range(img.shape[3]):
		img=Image.fromarray(data[j,:,:,i]) # 截取第j个通道的前i张图
//循环结束后,就可以将所有数据都提取出来并直接转换为图片数据

//最后贴一个相对比较完整的代码
import PIL
import nrrd
import os

data_path=./data/PA1.nrrd # nrrd 文件的保存路径
save_path=./data/save     # 图片数据的保存文件夹

# 检查路径
assert os.path.exists(data_path), data_path+' : path error !'
if not os.paht.exists(save_path):
	os.makedir(save_path)
	
data, options = nrrd.read(data_path)
for j in range(data.shape[0]):
	for i in range(data.shape[3]):
		img=Image.fromarray(data[j,:,:,i]) # 截取第j个通道的前i张图
		temp_path=save_path + '/' + str(j) + '_' + str(i) +'.png'
		img.convert('RGB').save(tmp_path) # 保存图像数据
//循环结束后,就可以将所有数据都提取出来并直接转换为图片数据

5、nrrd 转nii

import nrrd
import nibabel as nib
import numpy as np

# nrrd 文件保存路径
data_path=r'./data/1.nrrd'
save_path='./data/1.nii'

data,options=nrrd.read(data_path)  # 读取 nrrd 文件
img=nib.Nifti1Image(data,np.eye(4)) # 将 nrrd 文件转换为 .nii 文件
nib.save(img,save_path) # 保存 nii 文件

nibabel 库是用来读取 nii 数据的,它和 numpy 需要另外安装

pip install bibabel
pip install numpy

这是我在遇到这个问题后想到的可能的解决方法,如果大家有好的想法、解决方式,欢迎补充。

参考文章:
1、https://blog.csdn.net/Michelexie/article/details/81907613?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161681364616780271592594%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161681364616780271592594&biz_id=0
2、https://blog.csdn.net/qwer7512090/article/details/100163481?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161681364616780271592594%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=161681364616780271592594&biz_id=0

  • 3
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: 首先,我们需要将nrrd文件读取到Matlab中。这可以通过调用nrrdread函数实现,该函数可以从nrrd文件读取数据和元数据。 接下来,我们需要利用Matlab中的NIfTI工具箱将读取nrrd数据换为nii格式。这可以通过使用make_nii函数实现,该函数可以将读取nrrd数据换为nii格式,并创建一个NIfTI数据结构。 最后,我们需要将换后的nii数据存储在硬盘上,以便将其用于后续的分析。这可以通过调用save_nii函数实现,该函数将nii数据保存为文件。 下面是一个简单的Matlab代码示例,演示如何读取nrrd数据并将其换为nii格式: % 导入nrrd数据 [nrrd_data, metadata] = nrrdread('example.nrrd'); % 换为nii格式 nii_struct = make_nii(nrrd_data, metadata.spacing, metadata.origin); % 保存为nii文件 save_nii(nii_struct, 'example.nii'); 通过运行这个代码示例,我们可以将名为"example.nrrd"的文件换为"example.nii"文件,方便后续分析。 ### 回答2: MATLAB是一种常用的工具,为医学图像处理和分析提供了强大的支持。在读取nrrd数据的过程中,MATLAB提供了读取nrrd文件的函数nrrdread,可以将nrrd格式的数据读入MATLAB,并直接使用MATLAB对其进行分析和处理。 当读取nrrd数据后,我们可以使用MATLAB中的mat2niix函数,将nrrd文件换为nii格式。该函数使用方法如下: ```matlab mat2niix('input_file.nrrd', 'output_file.nii') ``` 其中,input_file.nrrd表示要换的nrrd文件的路径和文件名,output_file.nii表示换后的nii文件的路径和文件名。 需要注意的是,换后的nii文件格式可能与原始nrrd文件不完全相同,需要在进一步的分析过程中进行确认和调整。 除了使用MATLAB自带的函数,也可以使用一些第三方的工具箱来处理nrrdnii格式的数据,如NITRC-CE, NiftyReg, ANTS等。 总之,MATLAB提供了方便和灵活的工具来处理医学图像数据,并支持多种数据格式的读取、处理和存储,可以在医学图像分析和研究中起到很大的作用。 ### 回答3: MATLAB是一种很强大的科学计算软件,它支持读取和处理多种数据格式,包括常见的NRRD和NIFTI格式。下面我们将介绍如何使用MATLAB读取NRRD数据并将其换成NII格式。 首先,我们需要下载并安装一个开源的NRRD阅读器——nrrdread。可以在MATLAB应用商店中查找到此工具,并安装至MATLAB中。完成安装后,我们可以开始读取NRRD数据了。 读取NRRD数据的方法如下: ```matlab [data, meta] = nrrdread('yourfile.nrrd'); ``` 其中,'yourfile.nrrd'是待读取文件名,data是数据矩阵,meta是元数据。 读取了数据后,我们需要将它换成NII格式,可以使用MATLAB自带的nifti工具箱实现。将NRRD数据换成NII格式的方法如下: ```matlab nii = make_nii(data, voxel_size, origin); save_nii(nii, 'yourfile.nii'); ``` 其中,voxel_size和origin是数据体素大小和原点信息,可以从元数据中获取得到。make_nii函数将数据和元数据化为一个NII对象,而save_nii函数将NII对象保存为NII文件。 完成上述步骤后,我们就成功地将一个NRRD格式的数据换成NII格式,并保存到本地了。这样,我们就可以使用MATLAB或其他支持NII格式的软件进一步处理和分析这些数据了。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值