最近在弄跟肺结节相关的东西,所以用了Luna数据集。写一点自己的理解,里面可能会有不准确的地方,希望大家指正。
ObjectType = Image
NDims = 3
BinaryData = True
BinaryDataByteOrderMSB = False
CompressedData = False
TransformMatrix = 1 0 0 0 1 0 0 0 1
Offset = -161.699997 -169.5 -316.46499599999999
CenterOfRotation = 0 0 0
AnatomicalOrientation = RAI
ElementSpacing = 0.6640620231628418 0.6640620231628418 0.625
DimSize = 512 512 471
ElementType = MET_SHORT
ElementDataFile = 1.3.6.1.4.1.14519.5.2.1.6279.6001.100530488926682752765845212286.raw
x= (x_ano-x_offset)/x_ElementSpacing
y= (y_ano-y_offset)/y_ElementSpacing
z= (z_ano-z_offset)/z_ElementSpacing
其中,x是实际对应三维矩阵中的坐标。
x_ano是肺结节在annotation.csv中的坐标.
x_offset是质心坐标.
x_ElementSpacing是在x轴方向上的步长。相当于每一个像素对应现实世界中的长度。
读取数据的流程是先读取mhd,通过MatricTransform判别三维CT值矩阵在x,y方向上是否需要翻转。然后返回三维CT矩阵。
def load_itk_image(filename):
with open(filename) as f:
contents = f.readlines()
line = [k for k in contents if k.startswith('TransformMatrix')][0]
transform = np.array(line.split(' = ')[1].split(' ')).astype('float')
transform = np.round(transform)
if np.any(transform != np.array([1, 0, 0, 0, 1, 0, 0, 0, 1])):
isflip = True
else:
isflip = False
itkimage = sitk.ReadImage(filename)
numpyimage = sitk.GetArrayFromImage(itkimage)
if(isflip == True):
numpyimage = numpyimage[:,::-1,::-1]
return numpyimage
具体成像的原理可以找详细资料,比如医学中的肺窗和纵膈窗。不同窗位和算法形成的图像也是不同的。这里我们只是从可视化的角度找了一种最简单的处理方法。
def truncate_hu(image_array):
image_array[image_array > 400] = 0
image_array[image_array <-1000] = 0
def normalazation(image_array):
max = image_array.max()
min = image_array.min()
image_array = (image_array-min)/(max-min)
avg = image_array.mean()
image_array = image_array-avg
return image_array
a = image_array.transpose(1,2,0)[:,:,0] #transpose是将(z,x,y)的三维矩阵转为(x,y,z)的矩阵
plt.gca().add_patch( plt.Rectangle((147,297), 24,24, fill=False,edgecolor='r', linewidth=3))
plt.imshow(a[:,:,1]*255)#在图中画框
plt.show()