【问题标题】:change voxel values in nifti image and save it更改 nifti 图像中的体素值并保存
【发布时间】:2021-04-10 15:52:45
【问题描述】:

我将读取一个 nifti 图像并更改体素的值并保存与主图像类似但只有不同体素值的新 nifti 图像。换句话说,我希望分割图像中的标签从 0 到 7,而不是具有不同的数字。 o 写了下面的代码,但我得到了这个错误:

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

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

代码:

对于 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)

【问题讨论】:

    标签: python-3.x image-segmentation simpleitk nifti nibabel


    【解决方案1】:

    为了保存元数据,使用 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')
    

    说明: 您应该将新的 NIfTI 扫描(NumPy 数组)保存为 nii 图像。 为此,请使用Nifti1Image 创建 nii 对象,然后使用 nibabel.save 将其保存到文件中。

    Numpy_array 参数 - 是你的 numpy 数组(确保是浮点类型)。第二个参数是加载后的原始 NIfTI 扫描(带仿射函数)。

    【讨论】:

      【解决方案2】:

      SimpleITK 的 WriteImage 函数需要一个 SimpleITK 图像作为第一个参数。 NiBabel Image 的 get_fdata 方法返回一个 Numpy 数组。如果你想使用 SimpleITK 写图像,你需要使用 GetImageFromArray 函数将 Numpy 转换为 SimpleITK。

      请注意,您将丢失原始图像附带的任何元数据信息,例如像素间距。

      更新:

      回答有关保留元数据的问题:

      我自己没有使用过 NiBabel,但以下页面描述了如何从数据数组创建新图像,并从原始图像中复制标题信息: https://bic-berkeley.github.io/psych-214-fall-2016/saving_images.html

      我自己会在整个过程中使用 SimpleITK。如果您使用 SimpleITK 加载图像并在 SimpleITK Image 对象上进行所有处理,则所有元数据都会保留。

      对于您的特定代码,您可以使用 RelabelLabelMapFilter 类将您的原始标签(500、600、520、550、205、820、850)映射到(1-7),假设这些是唯一的标签。这样您就不必自己遍历所有体素。 https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1RelabelLabelMapFilter.html#details

      要计算每个标签的体素数量,您可以使用 LabelShapeStatisticsImageFilter。同样,这避免了手动循环遍历体素: https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1LabelShapeStatisticsImageFilter.html

      【讨论】:

      • 如何在不丢失元数据图像的情况下做到这一点?
      猜你喜欢
      • 2020-05-08
      • 1970-01-01
      • 2015-05-20
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 2017-06-28
      相关资源
      最近更新 更多