医学图像处理(二):医学图像nii格式下的spacing和size

数据读取

在对医学图像进行深度学习时,需要先对图像进行预处理
在pytorch中需要把图片读取到nparray三维数组类型
假设图片size是512*512*247

# sitk.ReadImage读取图像的顺序为(x,y,z)即(width,height,depth),512*512*247
ct = sitk.ReadImage(ct_path, sitk.sitkInt16) 
# 转化为三维数组后为(z,y,x),即247*512*512
ct_array = sitk.GetArrayFromImage(ct)

spacing和size的关系

由实战(一)可知,nii格式具有voxel size(体素大小)属性:毫米单位的x,y,z大小,也叫spacing
ct.GetSpacing() # 取得当前ct的spacing,按照(x,y,z)顺序
举例说明:Spacing(0.78125, 0.78125, 1.0)表示的是原始图像体素的大小,也可以将Spacing想象成大小为(0.78125, 0.78125, 1.0)的长方体。
而原始图像的Size为 (512, 512, 247),表示的是原始在X轴,Y轴,Z轴中体素的个数。
原始图像的size对应的Spacing既可以得到真实3D图像大小(5120.78125,5120.78125,2471 ),
在图像重采样只是修改体素的大小,而真实3D图像大小是保持不变的,因此假设我们将Spacing修改成(1.0, 1.0, 2.0)的时候,
则修改之后其对应的size应该为((5120.78125)/ 1.0,(5120.78125)/ 1.0,(247*1 ))即(400, 400, 124)。
再重采样过程中也可以把spacing理解为采样点间距,在一幅图像中每隔一个spacing取一点作为像素点
spacing越大像素点就越少,图像越模糊,也就是下采样。spacing越小像素点就越多,图像越清晰,也就是上采样。

改变size

在array坐标系下计算机只能读取到维度,也就是ct的size
预处理时,需要将不同xy维度的图像转变为相同xy维度,方便之后导入网络进行计算(slice轴不需要保持一致)
这里可以采用插值法

#双线性插值将是order = 1,
#最临近插值的是order = 0,mask使用
#立方体是默认值order = 3,原图使用,why?
#输入的zoom按(z,y,x的顺序)
ct_array = ndimage.zoom(ct_array, zoom=
                                (1,
                                 0.5,
                                 0.5), order=3)

会将array的size变成(256,256,247)

改变spacing

由于在上面改变了size,而spacing没有改变(实际上经过array操作后,spacing会统一重置为(1,1,1)),
最后真实图像的大小会发生改变
要保持真实图像大小不变,需要改变spacing,
并且要保持原来的Direction和Oringin不变(将原始CT的Direction,Origin,以及spacing变化后赋予新的CT图像)

new_ct = sitk.GetImageFromArray(ct_array)
new_ct.SetDirection(ct.GetDirection())
new_ct.SetOrigin(ct.GetOrigin())
new_ct.SetSpacing((ct.GetSpacing()[0] * int(1 / 0.5),
                   ct.GetSpacing()[1] * int(1 / 0.5),
                   ct.GetSpacing()[2] * int(1 / 1)))
# 改变的size通过改变spacing弥补回来
# 保证size和spacing乘积不变,图像大小保持不变
# slice轴上的spacing数值影响不大,可以就直接设置为1

参考链接

以上是改变Size时需要改变的spacing,如果是需要改变spacing时,应该改变Size保持图像大小的不变

参考:医学图像预处理之重采样

posted @ 2022-04-23 14:14  梅雨明夏  阅读(8015)  评论(0编辑  收藏  举报