如何可视化你的3D医学影像文件

背景

笔者最近在和医院合作开发一款3D医学影像软件,用的PyQt,其中需要把3D医学影像文件进行可视化,但是在可视化上出现了问题。 这里记录下解决问题的过程。

问题描述

在可视化的过程中,出现了下图所示的问题。

AMOS_Err.png

数据来自AMOS,文件格式nii.gz

可以看到除了第一个视角正常外,其他视角出现了问题,看样子似乎是图片被压扁了。 然而这并不是数据的问题,如果同样的文件用别的现有的可视化软件打开,是不会出现这些问题的。

AMOS_Err.png

软件来源:ITK-SANP

怎么解决

如果我们输出图片的维度会发现,正常视角的图片是(512,512)的,然而其他视角都是(512,149)的。 所以其他视角看上去扁扁的。

data.shape
# (512,512,149)

后来笔者思来想去,决定用ITK-SNAP软件打开图片,放大后发现了问题!

AMOS_Err.png

正常视角和非正常视角

可以看到正常视角的图片像素是正方形的,而其他视角是长条形的。这就有解决思路了。我们直接把“拉长”图片不就行了 这里使用numpy.repeat,将图片进行“拉长”。于是这个问题就解决了。

data_repeated=[]
for i in range(data.shape[2]):
    img = data_arr[:,:,i:i+1].copy()
    img = np.repeat(img, 512//149, axis=2)  
    data_repeated.append(img)
data = numpy.concatenate(data_repeated, axis=2)

AMOS_Err.png

正常显示的图片

问题的根源

笔者用了简单粗暴的方法直接把图片“拉长”了(512//149)倍,但是我们需要这个问题的通解

我们可以思考,难道ITK-snap也是用这种简单粗暴的方法解决问题的? 我们不妨从gz.nii文件的格式进行入手,这里具体两个网站参考网站

simpleitk官方文档

  • https://simpleitk.readthedocs.io/en/master/fundamentalConcepts.html

NIFTI文件格式标准:其记录了nii.gz文件的各种具体信息

  • https://brainder.org/2012/09/23/the-nifti-file-format/

在simpleitk官方文档中,我们直接看到了这个问题的全貌。 AMOS_Err.png 问题的关键就在于图中的Spacing参数,这个参数告诉了我们像素与像素之间的距离,这也是为什么在其他视图中我们会看到长条像素的原因。

这个参数在NIFTI文件格式中有具体介绍。其中Spacing参数对应的是NIFTI文件格式中的pixdim,除此之外,xyzt_units参数表示的是单位。 关于这个参数,笔者认为pixdim采样之间的距离,xyzt_units是单位。

我们不妨可以把数据的这些参数输出出来看看:

import nibabel as nib
img = nib.load(data_path)
print(img.header)
# ....
# pixdim          : [-1.     0.782  0.782  5.     0.     0.     0.     0.   ]
# xyzt_units      : 10
# ....

这样我们就知道我们应该具体该怎么“拉长”图像了:

img = np.repeat(img, pixdim[3]//pixdim[1], axis=2)