医学图像处理(二):医学图像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保持图像大小的不变
参考:医学图像预处理之重采样