简体   繁体   English

更改 nifti 图像中的体素值并保存

[英]change voxel values in nifti image and save it

I am going to read a nifti image and change the values of the voxels and save the new nifti image similar to the main image but only different voxel values.我将读取一个 nifti 图像并更改体素的值并保存与主图像类似但只有不同体素值的新 nifti 图像。 In other words I want my labels in segmentation image be from 0 to 7 instead of having different numbers.换句话说,我希望分割图像中的标签从 0 到 7,而不是具有不同的数字。 o wrote the code below but I get this error: o 编写了下面的代码,但我收到此错误:

NotImplementedError: Wrong number or type of arguments for overloaded function 'WriteImage'.

Possible C/C++ prototypes are: itk::simple::WriteImage(itk::simple::Image const &,std::string const &,bool) itk::simple::WriteImage(itk::simple::Image const &,std::vector< std::string,std::allocator< std::string > > const &,bool)可能的 C/C++ 原型有: itk::simple::WriteImage(itk::simple::Image const &,std::string const &,bool) itk::simple::WriteImage(itk::simple::Image const &,std::vector<std::string,std::allocator<std::string >> const &,bool)

The code:编码:

for image_path in os.listdir(path):对于 os.listdir(path) 中的 image_path:

label_name = os.path.join(path, image_path)

img = nib.load(label_name)
data = img.get_fdata()
n=0;
u=0;
m=0;
b=0;
e=0;
r=0;
s=0;
img1=img
data1 = img1.get_fdata()
for i in range (0,img.shape[0]):
    for j in range (0,img.shape[1]):
        for k in range (0,img.shape[2]):

            if data[i,j,k]==500:
                n=n+1;
                data1[i,j,k]=1;
            elif data[i,j,k]==600:
                u=u+1;
                data1[i,j,k]=2;
            elif data[i,j,k]==420:
                b=b+1;
                data1[i,j,k]=3;
            elif data[i,j,k]==550:
                e=e+1;
                data1[i,j,k]=4;
            elif data[i,j,k]==205:
                r=r+1;
                data1[i,j,k]=5;
            elif data[i,j,k]==820:
                m=m+1;
                data1[i,j,k]=6;
            elif data[i,j,k]==850:
                s=s+1;
                data1[i,j,k]=7



OUTPUT_DIR='/Volumes/CSE_BME_AXM788/home/gxa131/labelsTr_new/'  
dir1=os.path.join(OUTPUT_DIR, image_path)
sitk.WriteImage(data1,dir1)

SimpleITK's WriteImage function is expecting a SimpleITK Image for the first argument. SimpleITK 的 WriteImage function 期望 SimpleITK 图像作为第一个参数。 The get_fdata method for an NiBabel Image returns a Numpy array. NiBabel Image 的 get_fdata 方法返回一个 Numpy 数组。 If you want to use SimpleITK to write the image, you need to convert from Numpy to SimpleITK using the GetImageFromArray function.如果要使用 SimpleITK 写入图像,则需要使用 GetImageFromArray function 将 Numpy 转换为 SimpleITK。

Note that you will lose any meta-data information that came with the original image such as pixel spacing.请注意,您将丢失原始图像附带的任何元数据信息,例如像素间距。

UPDATE:更新:

To answer your question about preserving the meta data:要回答有关保留元数据的问题:

I haven't used NiBabel myself, but the following page describes how to create a new image from a data array, copying over the header information from the original image: https://bic-berkeley.github.io/psych-214-fall-2016/saving_images.html我自己没有使用过 NiBabel,但是下面的页面描述了如何从数据数组创建新图像,从原始图像中复制 header 信息: https://bic-berkeley.ZBF2151810B5140517354437B514051745443AZ。 2016 年秋季/saving_images.html

I would use SimpleITK for the entire process myself.我自己会在整个过程中使用 SimpleITK。 If you load the image using SimpleITK and do all your processing on a SimpleITK Image object, all the meta data is preserved.如果您使用 SimpleITK 加载图像并在 SimpleITK 图像 object 上进行所有处理,则会保留所有元数据。

And for your particular code, you can use the RelabelLabelMapFilter class to map your original labels (500, 600, 520, 550, 205, 820, 850) to (1-7), assuming those are the only labels.对于您的特定代码,您可以使用 RelabelLabelMapFilter class 到 map 您的原始标签(500、600、520、550、205、820、850)到(1-7),假设只有标签。 That way you don't have to loop through all the voxels yourself.这样您就不必自己遍历所有体素。 https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1RelabelLabelMapFilter.html#details https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1RelabelLabelMapFilter.html#details

And to count the number of voxels for each label, you can use the LabelShapeStatisticsImageFilter.要计算每个 label 的体素数量,可以使用 LabelShapeStatisticsImageFilter。 Again, this avoids looping through the voxels by hand: https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1LabelShapeStatisticsImageFilter.html同样,这避免了手动循环遍历体素: https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1LabelShapeStatisticsImageFilter.html

In order to save the meta data, use nibabel.save as the example below:为了保存元数据,使用 nibabel.save 如下例所示:

new_nifti = nib.Nifti1Image(***numpy_arrray***.astype(np.float), nii_original_scan.affine)
nib.save(new_nifti, f'***path to new scan***.nii.gz')

Explanation: You should save the new NIfTI scan (NumPy array) as nii image.说明:您应该将新的 NIfTI 扫描(NumPy 数组)保存为 nii 图像。 In order to do it, use Nifti1Image to create nii object, and then nibabel.save to save it to a file.为此,请使用Nifti1Image创建 nii object,然后使用 nibabel.save 将其保存到文件中。

Numpy_array argument- is your numpy array (make sure is in float type). Numpy_array 参数 - 是您的 numpy 数组(确保是浮点类型)。 The second argument is the original NIfTI scan after loading (with affine function).第二个参数是加载后的原始 NIfTI 扫描(使用仿射函数)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM