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

How to adjust the viewing window of .mhd file to get a better look at medical images?

我为医学图像加载了一些 .mdh 和 .raw 文件,但有一件事困扰着我。我知道在 .dicom 文件中,您可以使用 rescale.slope 和 rescale.intercept 将像素强度转换为 HU,而 .mhd 文件无法包含。因此,我想知道如何从 .mdh 和 .raw 中更好地查看我的图像数据 file.This 是我想要完成的 image that I generate, this is the kind of image
在这里,我从数据中加载一个切片,并绘制每个 'pixel' 值的 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,因为我还没有被允许上传图片,所以请随时点击。

非常感谢!

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

我不建议重新调整文件本身的值,因为这会导致信息丢失。相反,我建议下载一个能够显示图像的程序,例如 ITK-Snap and/or MeVisLab,它允许您调整 window 和级别

前面的回答很好地解释了为什么您需要窗口化,而不是重新调整强度值。但是,@Czorio 提出的解决方案涉及您在第 3 方软件(ITK-Snap 或 MeVisLab)中可视化图像。

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

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 以实现非线性颜色映射,您可能希望再次根据您尝试可视化的解剖结构进行调整。

我也只是附和一下。我也用 dicom/diagnostic 图像、分析和机器学习做了很多工作。

要具体说明的一个关键点(我假设您知道这一点,而其他回复隐含地说明了这一点)是这些图像(您使用的是 CT,但同样适用于 MR 和其他模式)是 图像数据本身是 16 位 。 (即值范围超过 65,536 个值集,而不是像 8 位数据那样的 256 个)。

有两点很重要:

  • 对于任何机器learning/analysisy你必须使用16位数据,而不是它的任何8位表示。我说 'must' 因为 a) 如果你不这样做,你就会丢失数据中的大部分信息 b) 特定值(对于 CT)具有临床意义 c) 你不是如果您不使用 16 位数据
  • ,那么任何临床监管都会有希望 approval/use/testing/validation
  • 当您想可视化数据时,您需要将其转换为(通常)8 位下采样版本 - 即以某种方式将其表示为 256 个离散值而不是 65k .

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

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

要获得你想要的图像视图,你需要将 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 之外,他们将数据设置为这个 "low" 值以表明它不是实际的真实扫描数据。您可以在图像 here 中看到这一点,其中有 body,body 外部的空气(mid-grey 值 - 大约 -1000 HU),然后是黑色该圆形区域之外的值(可能约为 -3000 HU)。