如何调整.mhd文件的查看窗口,以更好地查看医学图像?

时间:2019-04-27 12:57:46

标签: python-3.x dicom medical pydicom simpleitk

我加载了一些.mdh和.raw文件用于医学图像,但是有一件事困扰着我。我了解在.dicom文件中,您可以使用rescale.slope和rescale.intercept将像素强度转换为HU,而该.mhd文件无法包含该强度。因此,我想知道如何从.mdh和.raw文件中更好地查看图像数据。这就是我生成的image,这就是我想要的image完成。
在这里,我从数据中加载一个切片,并绘制每个“像素”值的histogram(不确定是将其称为像素还是体素)。
尽管我确实有一个想法,就是简单地将像素重置为最小值,但是我真的很想听听经验丰富的同行提供的解决方案。

itk_img = SimpleITK.ReadImage(mhd_file) 
img_array = SimpleITK.GetArrayFromImage(itk_img)
plt.imshow(img_array[80], cmap=plt.cm.gray) # show a slice from a 3D data
plt.show()

plt.hist(img_array[80].flatten(), bins=80, color='c')
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.show()

由于我尚未上传图片,所以我已将所有图片上传到github,所以请随时单击。

非常感谢!

3 个答案:

答案 0 :(得分:2)

上一个答案很好地解释了为什么窗口是您想要的,而不是强度值的重新缩放。但是,@ Czorio提出的解决方案需要您在第三方软件(ITK-Snap或MeVisLab)中可视化图像。

虽然我也建议您使用这些应用程序,但在您的帖子中看起来,您正在尝试使用Matplotlib在Python中可视化图像。如果要在Python中更改窗口,建议在clim中修改plt.imshow参数。例如:

import numpy as np

itk_img = SimpleITK.ReadImage(mhd_file) 
img_array = SimpleITK.GetArrayFromImage(itk_img)
plt.imshow(img_array[80], cmap=plt.cm.gray, clim=np.percentile(img_array, (1,99)))
plt.show()

plt.hist(img_array[80].flatten(), bins=80, color='c')
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.show()

在上面的修改后的代码中,我只是将色图plt.cm.gray重新缩放为图像中值的1%到99%。您将需要处理这些百分位数,直到获得您喜欢的图像为止(这将取决于您正在可视化的解剖结构等因素)。您也可以使用直方图来帮助您做出决定。

您可以进一步修改cmapclim以实现非线性色彩映射,您可能希望再次依赖于要可视化的解剖结构。

答案 1 :(得分:1)

.mhd / .mha文件中存储的值已经是HU值。您在想的是图像查看器的Window and Level,它将HU值重新映射为可以在监视器上显示的像素值。

我不建议重新调整文件本身中的值,因为那样会导致信息丢失。相反,我建议下载一个能够显示图像的程序,例如ITK-Snap和/或MeVisLab,该程序可让您调整窗口和水平

答案 2 :(得分:1)

我也想说些什么。我还处理dicom /诊断图像,分析和ML。

要特别说明的关键点(我假设您知道这一点,而其他答复则暗含了该知识)是这些图像(您使用的是CT,但对MR和其他模态同样适用)是图像数据本身为16位。 (即值范围超过65,536个值集,而不是像8位数据一样为256个值)。

有两个重要的观点:

  • 对于任何机器学习/分析,您您必须使用16位数据,而不是任何8位表示形式。我说“必须”是因为 a)如果您不这样做,那么您将失去数据中的大多数信息b)(CT的)特定值具有临床意义,并且c)您将不会如果您不使用16位数据,则​​希望获得任何临床监管批准/使用/测试/验证
  • 如果要可视化数据,则需要将其转换为(通常)8位降采样的版本-即以某种方式将其表示为256个离散值而不是65k。

您在上面所做的就是试图可视化整个16位数据集(这意味着以某种方式下采样到256个灰度值)。

默认情况下,对于16位数据,matplotlib imshow会将灰度限制设置为数据的最小值和最大值。几乎可以肯定(见下文)不会为您提供想要的图像,或者对任何人都有用。

要获得所需的图像视图,您需要将vmin / vmax传递给imshow()来告诉matplotlib最小和最大灰度值(即,什么值是黑色,什么是白色):

vmin = -100
vmax = 200
plt.imshow(img_array, cmap='gray', vmin=vmin, vmax=vmax)

# or if you're using window/level:
window = 300
level = 100
vmin = level - window/2
vmax = level + window/2
plt.imshow(img_array, cmap='gray', vmin=vmin, vmax=vmax)

我几乎可以肯定地说,因为在CT图像中,图像中大多数扫描仪的最小值为-3000(或等效的非常低的值)。这是因为,虽然空气的HU值为-1000,但扫描仪的视场为圆形,因此可以获取图像数据。在该FOV之外,他们将数据设置为此“低”值,以指示它不是实际的实际扫描数据。您可以在图像here中看到这一点,那里有物体,身体外面的空气(中间灰度值--1000 HU附近),然后是该圆形区域之外的黑色值(可能是大约-3000 HU)。