【问题标题】:How to adjust the viewing window of .mhd file to get a better look at medical images?如何调整 .mhd 文件的查看窗口以更好地查看医学图像?
【发布时间】:2019-04-27 12:57:45
【问题描述】:

我为医学图像加载了一些 .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,因为我还没有上传图片的权限,所以请随意点击。

非常感谢!

【问题讨论】:

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


    【解决方案1】:

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

    虽然我也建议使用这些应用程序,但在您的帖子中,您正在尝试使用 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 以实现非线性颜色映射,您可能希望再次依赖于您尝试可视化的解剖结构。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 感谢您的建议。顺便说一句,我能以这种方式理解“信息丢失”吗?也就是说,当我将这些文件用作训练数据集时,直接在文件中重新调整值可能会破坏我的神经网络的性能。
      • 很可能,是的。作为HU values closely correlate with the tissue types,更改值可能会导致错误识别。
      【解决方案3】:

      我也只是回应所说的话。我还对 dicom/诊断图像、分析和机器学习做了很多工作。

      要特别说明的关键点(我假设您知道这一点,而其他回复隐含地表明了该知识)是这些图像(您使用的是 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 之外,他们将数据设置为这个“低”值,以表明它不是实际的真实扫描数据。您可以在您的图像here 中看到这一点,其中有身体,身体外部的空气(中灰色值 - 大约 -1000 HU),然后是该圆形区域之外的黑色值(可能在 - 3000 胡)。

      【讨论】:

        猜你喜欢
        • 2013-03-06
        • 2014-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多