ITK study notes (9) simpleITK resampling data to a fixed size

1、resampleSize

This resampling is not resampling Spacing, but resampling size, in order to achieve a consistent size for all data

For example: (880, 880, 12) sample uniform (880, 880, 16)

Because if the input format of the 3DUnet network data is set to (N, C, 16, xxx, xxx), the size of each data can be resampled (16, xxx, xxx) and then input to the network.

If you directly set the Size to (16,xxx,xxx), the extra layer SimpleITK will be filled with 0, which cannot achieve real sampling. So by doing the inverse operation of Spacing sampling above

"""
统一Size
X轴和Y轴的Size和Spacing没有变化,
Z轴的Size和Spacing有变化
"""
def resampleSize(sitkImage, depth):
    #重采样函数
    euler3d = sitk.Euler3DTransform()

    xsize, ysize, zsize = sitkImage.GetSize()
    xspacing, yspacing, zspacing = sitkImage.GetSpacing()
    new_spacing_z = zspacing/(depth/float(zsize))

    origin = sitkImage.GetOrigin()
    direction = sitkImage.GetDirection()
    #根据新的spacing 计算新的size
    newsize = (xsize,ysize,int(zsize*zspacing/new_spacing_z))
    newspace = (xspacing, yspacing, new_spacing_z)
    sitkImage = sitk.Resample(sitkImage,newsize,euler3d,sitk.sitkNearestNeighbor,origin,newspace,direction)
    return sitkImage

DEPTH = 16  #需要重采样Size的层数

#读取nifit原数据 ,size为:(880, 880, 12)
NifitmPath = 'work/data/nifit/Case14.nii.gz'
sitkImage = sitk.ReadImage(NifitmPath)
print("重采样前的信息") 
print("尺寸:{}".format(sitkImage.GetSize()))
print("体素大小(x,y,z):{}".format(sitkImage.GetSpacing()) )

print('='*30+'我是分割线'+'='*30)


newsitkImage = resampleSize(sitkImage, depth=DEPTH)
print("重采样后的信息")
print("尺寸:{}".format(newsitkImage.GetSize()))
print("体素大小(x,y,z):{}".format(newsitkImage.GetSpacing()) )
重采样前的信息
尺寸:(880, 880, 12)
体素大小(x,y,z):(0.3448275923728943, 0.3448275923728943, 5.499998092651367)
==============================我是分割线==============================
重采样后的信息
尺寸:(880, 880, 16)
体素大小(x,y,z):(0.3448275923728943, 0.3448275923728943, 4.124998569488525)

Reference: Resampling (Unified Size)

2. Resampling of CT image preprocessing

The disadvantage of resampling data according to the specified spacing is that it generally cannot be resampled to the specified size. In practical applications, it is often encountered that the image size needs to be specified.

def Resampling(img,lable = False):
    original_size = img.GetSize() #获取图像原始尺寸
    original_spacing = img.GetSpacing() #获取图像原始分辨率
    new_spacing = [1, 1, 1] #设置图像新的分辨率为1*1*1

    new_size = [int(round(original_size[0] * (original_spacing[0] /1))),
                int(round(original_size[1] * (original_spacing[1] / 1))),
                int(round(original_size[2] * (original_spacing[2] / 1)))] #计算图像在新的分辨率下尺寸大小
    resampleSliceFilter = sitk.ResampleImageFilter() #初始化
    if lable == False:
        Resampleimage = resampleSliceFilter.Execute(img, new_size, sitk.Transform(), sitk.sitkBSpline,
                                                img.GetOrigin(), new_spacing, img.GetDirection(), 0,
                                                img.GetPixelIDValue())
        ResampleimageArray = sitk.GetArrayFromImage(Resampleimage)
        ResampleimageArray[ResampleimageArray < 0] = 0 #将图中小于0的元素置为0
    else:# for label, should use sitk.sitkLinear to make sure the original and resampled label are the same!!!
        Resampleimage = resampleSliceFilter.Execute(img, new_size, sitk.Transform(), sitk.sitkLinear,
                                                    img.GetOrigin(), new_spacing, img.GetDirection(), 0,
                                                    img.GetPixelIDValue())
        ResampleimageArray = sitk.GetArrayFromImage(Resampleimage)

3. SKIMAGE.TRANSFORM - both scales are available

# 1、按目标大小缩放resize
skimage.transform.resize(image, output_shape, order=1, mode='reflect', cval=0, clip=True, preserve_range=False, anti_aliasing=True, anti_aliasing_sigma=None)
# 2、按缩放因子缩放rescale
skimage.transform.rescale(image, scale, order=1, mode='reflect', cval=0, clip=True, preserve_range=False, multichannel=False, anti_aliasing=True, anti_aliasing_sigma=None)

# The order of interpolation. The order has to be in the range 0-5:
# 0: Nearest-neighbor
# 1: Bi-linear (default)
# 2: Bi-quadratic
# 3: Bi-cubic
# 4: Bi-quartic
# 5: Bi-quintic

Reference: Resampling of CT Image Preprocessing

4. Medical image resampling (resample) implementation code of Python SimpleItk library

Requirements: There are already registered CT and PET images, and the gold standard label is drawn on the CT, so there are some simple requirements, one is to resample the PET image to the same size as the CT image (for example, from 192 ×192×371 to 512×512×484), or reduce the gold standard Mask to the same size as PET (ie, vice versa).

How to find the method: The image reading function of ITK-SNAP (version 3.8) supports images of different sizes, spacing, origin, and direction to be displayed together, and the software will be equivalent to the images added later by resample; The method, the rest is to find the corresponding code.

import SimpleITK as sitk

def resize_image_itk(ori_img, target_img, resamplemethod=sitk.sitkNearestNeighbor):
    """
    用itk方法将原始图像resample到与目标图像一致
    :param ori_img: 原始需要对齐的itk图像
    :param target_img: 要对齐的目标itk图像
    :param resamplemethod: itk插值方法: sitk.sitkLinear-线性  sitk.sitkNearestNeighbor-最近邻
    :return:img_res_itk: 重采样好的itk图像
    使用示范:
    import SimpleITK as sitk
    target_img = sitk.ReadImage(target_img_file)
    ori_img = sitk.ReadImage(ori_img_file)
    img_r = resize_image_itk(ori_img, target_img, resamplemethod=sitk.sitkLinear)
    """
    target_Size = target_img.GetSize()      # 目标图像大小  [x,y,z]
    target_Spacing = target_img.GetSpacing()   # 目标的体素块尺寸    [x,y,z]
    target_origin = target_img.GetOrigin()      # 目标的起点 [x,y,z]
    target_direction = target_img.GetDirection()  # 目标的方向 [冠,矢,横]=[z,y,x]

    # itk的方法进行resample
    resampler = sitk.ResampleImageFilter()
    resampler.SetReferenceImage(ori_img)  # 需要重新采样的目标图像
    # 设置目标图像的信息
    resampler.SetSize(target_Size)		# 目标图像大小
    resampler.SetOutputOrigin(target_origin)
    resampler.SetOutputDirection(target_direction)
    resampler.SetOutputSpacing(target_Spacing)
    # 根据需要重采样图像的情况设置不同的dype
    if resamplemethod == sitk.sitkNearestNeighbor:
        resampler.SetOutputPixelType(sitk.sitkUInt8)   # 近邻插值用于mask的,保存uint8
    else:
        resampler.SetOutputPixelType(sitk.sitkFloat32)  # 线性插值用于PET/CT/MRI之类的,保存float32
    resampler.SetTransform(sitk.Transform(3, sitk.sitkIdentity))    
    resampler.SetInterpolator(resamplemethod)
    itk_img_resampled = resampler.Execute(ori_img)  # 得到重新采样后的图像
    return itk_img_resampled
    

Reference: Medical image resampling (resample) implementation code of Python SimpleItk library

5. Use SimpleITK to interpolate volume files

When analyzing dicom files, interpolation or resampling is often performed, which can be easily done with SimpleITK.

import SimpleITK as sitk

def getDicomSeriesVolumeImage(folderPath):
	'''
	读取dicom序列文件
	:para folderPath:dicom文件夹
	:return volumeImage:volume
	'''
    reader = sitk.ImageSeriesReader()
    dicomNames = reader.GetGDCMSeriesFileNames(folderPath)
    reader.SetFileNames(dicomNames)
    volumeImage = reader.Execute()

    return volumeImage

def interpolate(volumeImage, newSpacing):
	'''
	插值处理
	:para volumeImage:volume格式
	:para newSpaceing:想要插值或者重采样处理后得到的三个物理间隔,格式为列表
	:return newVolumeImage:插值处理后的到的volume文件
	'''
    resampleFilter = sitk.ResampleImageFilter()
    resampleFilter.SetInterpolator(sitk.sitkLinear) 	##此处为线性插值,其他插值方式可以去官网查询
    resampleFilter.SetOutputDirection(volumeImage.GetDirection())
    resampleFilter.SetOutputOrigin(volumeImage.GetOrigin())

    newSpacing = np.array(newSpacing, float)
    newSize = volumeImage.GetSize() / newSpacing * volumeImage.GetSpacing()
    newSize = newSize.astype(np.int)

    resampleFilter.SetSize(newSize.tolist())
    resampleFilter.SetOutputSpacing(newSpacing)
    newVolumeImage = resampleFilter.Execute(volumeImage)

    return newVolumeImage

Reference: Interpolate volume files with SimpleITK

6. Medical Image Resampling

1. Resampling

In the process of medical image preprocessing, it is often necessary to resample the data to the scale we need. Because medical images correspond to the physical size of real space. For example, the size of a voxel is 0.97mm 0.97mm 2.5mm, we want to sample the size of the voxel block to 1mm 1mm 1mm, which can help us in the next step. This can be done using sitk.

2. Code

import SimpleITK as sitk
"""
resample
"""

def resampleVolume(outspacing,vol):
    """
    将体数据重采样的指定的spacing大小\n
    paras:
    outpacing:指定的spacing,例如[1,1,1]
    vol:sitk读取的image信息,这里是体数据\n
    return:重采样后的数据
    """
    outsize = [0,0,0]
    inputspacing = 0
    inputsize = 0
    inputorigin = [0,0,0]
    inputdir = [0,0,0]

    #读取文件的size和spacing信息
    
    inputsize = vol.GetSize()
    inputspacing = vol.GetSpacing()

    transform = sitk.Transform()
    transform.SetIdentity()
    #计算改变spacing后的size,用物理尺寸/体素的大小
    outsize[0] = int(inputsize[0]*inputspacing[0]/outspacing[0] + 0.5)
    outsize[1] = int(inputsize[1]*inputspacing[1]/outspacing[1] + 0.5)
    outsize[2] = int(inputsize[2]*inputspacing[2]/outspacing[2] + 0.5)

    #设定重采样的一些参数
    resampler = sitk.ResampleImageFilter()
    resampler.SetTransform(transform)
    resampler.SetInterpolator(sitk.sitkLinear)
    resampler.SetOutputOrigin(vol.GetOrigin())
    resampler.SetOutputSpacing(outspacing)
    resampler.SetOutputDirection(vol.GetDirection())
    resampler.SetSize(outsize)
    newvol = resampler.Execute(vol)
    return newvol    

def main():
    #读文件
    vol = sitk.Image(sitk.ReadImage("input.mha"))

    #重采样
    newvol = resampleVolume([1,1,1],vol)

    #写文件
    wriiter = sitk.ImageFileWriter()
    wriiter.SetFileName("output.mha")
    wriiter.Execute(newvol)

Reference: Medical Image Resampling

Guess you like

Origin blog.csdn.net/juluwangriyue/article/details/123723564