Python SimpleItk库的医学图像重采样(resample)实现代码

您所在的位置:网站首页 python中resample Python SimpleItk库的医学图像重采样(resample)实现代码

Python SimpleItk库的医学图像重采样(resample)实现代码

2023-11-15 15:11| 来源: 网络整理| 查看: 265

记:关于图像重采样(resample)最终发现的简单实现方法

需求:已有配准好的CT以及PET图像,而金标准label是在CT上勾画的,因此有一些简单的需求,一种是把PET图像重采样到与CT图像一样的大小(比如从192×192×371到512×512×484),或者把金标准Mask降到同PET的大小(即反过来)。

怎么找的方法:ITK-SNAP(3.8版本)的读图功能是支持不同大小、spacing、origin、direction的图像一起展示的,软件会相当于resample后续加入的图像; 因此,已知ITK存在解决的方法了,剩下就是找对应代码。

直接上最终的Python代码: 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 额外Tips:

一开始找到这样一份代码,是通过两个图像的spacing来计算重采样之后的图像的大小:

# 初始版本,from 网上,适用于只有spacing不同的两个图 def resize_image(itkimage, newSize, resamplemethod=sitk.sitkNearestNeighbor): print('--resize ing--') resampler = sitk.ResampleImageFilter() originSize = itkimage.GetSize() # 原来的体素块尺寸 originSpacing = itkimage.GetSpacing() newSize = np.array(newSize, float) factor = originSize / newSize newSpacing = originSpacing * factor newSize = newSize.astype(np.int) # spacing肯定不能是整数 resampler.SetReferenceImage(itkimage) # 需要重新采样的目标图像 resampler.SetSize(newSize.tolist()) resampler.SetOutputSpacing(newSpacing.tolist()) resampler.SetTransform(sitk.Transform(3, sitk.sitkIdentity)) resampler.SetInterpolator(resamplemethod) itk_img_res = resampler.Execute(itkimage) # 得到重新采样后的图像 print('--resize finish--') return itk_img_res

实际使用发现,如果通过计算得到的newsize来 resampler.SetSize(new_size) 的话,new_size不一定和目标图像的size一致,原因是两个图像在origin、direction方面很有可能不一致(尤其对于医学影像),因此使用这份代码会导致后面还需要对resample后的图像进行各种后处理操作,比如pad空矩阵或者cut图像啥的,更会涉及复杂的空间坐标变换。

最后是查看sitk.ResampleImageFilter()的各个功能函数,突然想试试如果setsize的是目标图像的大小的话,是不是应该跟软件一样直接给到正确的结果呢,结果发现,确实。。。

温馨提示: 读入ori和target的sitk图像时,要确保spacing这些信息没有丢失,如果前面有从sitk转array处理过再转回sitk的操作的话,记得用 ori_processed.CopyInformation(ori) 把原本的信息复制过来再进行resample,否则会导致输出图像为空矩阵。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3