1

我为医学图像加载了一些 .mdh 和 .raw 文件,但有一件事困扰着我。我知道在 .dicom 文件中,您可以使用 rescale.slope 和 rescale.intercept 将像素强度转换为 HU,而 .mhd 文件无法包含这些。因此,我想知道如何从 .mdh 和 .raw 文件中更好地查看我的图像数据。这是我生成的图像,这是想要完成的图像。
在这里,我从数据中加载一个切片,并绘制每个“像素”值的直方图(不确定是否称它们为像素或体素)。
虽然我确实想到了简单地重置具有最小值的像素,但我真的很想听听有经验的同行是否有更复杂的方法来实现这一点。

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,因为我还没有上传图片的权限,所以请随意点击。

非常感谢!

4

3 回答 3

2

上一个答案很好地解释了为什么您想要开窗,而不是重新调整强度值。但是,@Czorio 提出的解决方案涉及您在 3rd 方软件(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 个百分位数。您将需要使用这些百分位数,直到获得您喜欢的图像(这将取决于您正在可视化的解剖结构等因素)。您也可以使用直方图来帮助您做出决定。

您可以修改cmap甚至clim进一步实现非线性颜色映射,您可能希望再次依赖于您尝试可视化的解剖结构。

于 2019-11-08T19:46:40.387 回答
1

存储在 .mhd/.mha 文件中的值已经是 HU 值。您正在考虑的是图像查看器的窗口和级别,它将 HU 值重新映射为可以在监视器上显示的像素值。

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

于 2019-05-25T23:21:48.077 回答
1

我也只是回应所说的话。我也用 dicom/diagnostic 图像做很多工作,包括分析和 ML。

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

有两个重要的点:

  • 对于任何机器学习/分析,您必须使用 16 位数据,而不是任何 8 位表示。我说“必须”是因为a)如果你不这样做,你会丢失数据中的大部分信息 b)特定值(对于 CT)具有临床意义 c)你不会有希望任何临床监管批准/使用/测试/验证,如果您不使用 16 位数据
  • 当您想要可视化数据时,您需要将其转换为(通常)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 之外,他们将数据设置为这个“低”值,以表明它不是实际的真实扫描数据。您可以在此处的图像中看到这一点,其中有身体,身体外部的空气(中灰色值 - 大约 -1000 HU),然后是该圆形区域之外的黑色值(可能大约 -3000 HU )。

于 2019-11-09T19:50:59.660 回答