DICOM文件中的医学图像质量问题

3
我正在尝试使用Python对DICOM格式的CT图像进行分割任务。
主要问题是,当我尝试使用pydicom库读取DICOM文件(https://www.dicomlibrary.com/meddream/md5/index.html?study=1.2.826.0.1.3680043.8.1055.1.20111102150758591.92402465.76095170)并使用属性显示图像时,得到的图像比原始图像质量差得多(请参见下面的代码和截图)。
dicom_file = pydicom.read_file('Anonymized20191102.dcm')
plt.imshow(dicom_file.pixel_array, cmap='gray')
plt.show()

The original image

The image displayed with matplotlib

我的问题是为了更好地理解问题:
1.像素数组属性代表什么?我看到它的取值范围在[0,2250]之间。
观察结果:
我也尝试通过乘以斜率并加上偏差来获取Hounsfield单位(HU)值,如下所示:
def convert_to_hu(dicom_file):
    bias = dicom_file.RescaleIntercept
    slope = dicom_file.RescaleSlope
    pixel_values = dicom_file.pixel_array
    new_pixel_values = (pixel_values * slope) + bias
    return new_pixel_values

hu_pixels = convert_to_hu(dicom_file)
plt.imshow(hu_pixels, cmap='gray')
plt.show()

可视化方面的结果与从pixel_array中获取原始值的结果几乎相同。此外,数值范围在[-1000, 1250]之间(考虑到HU通常在-1000和1000之间,我认为这是不错的)。

尝试使用ImageMagick将图像转换为JPEG格式,看看它能在其中找到什么内容convert input.dcm output.jpg - Mark Setchell
我刚刚尝试了一下,但是输出结果和最初的帖子一样。 - robertg
2个回答

4
第二张图看起来像是使用了适合所有提供的HU值的灰度范围来绘制像素,而不仅仅是显示与所显示解剖结构相对应的HU值范围。虽然我不确定pydicom如何处理这个问题,但你需要对图像进行“窗口和水平”操作,以获得第一张图像的结果。通常通过线性 VOI LUT来应用窗口/水平,用于CT图像,将限制显示的像素范围并将其缩放到可显示的范围,通常为8位,除非使用灰度显示器。 CT图像最有可能具有窗口中心(0028,1050)标记以设置级别和窗口宽度(0028,1051)以设置窗口。生成图像的模态提供了图像中的中心和宽度值,并对应于在图像中显示腹部区域的良好范围。下面的链接提供了一些基于被查看身体部位的常见窗口/水平设置,并提供有关这些设置如何影响显示图像的其他信息。

https://radiopaedia.org/articles/windowing-ct

应用窗位/窗宽虽然有助于显示图像,但是将每个像素存储的10或12位(CT图像常见)转换为每个像素显示的8位会导致丢失位深度。您需要确定是否需要这些额外的位深度来进行分割任务。


2

就像Colby所说的,看起来不对的原因几乎肯定是窗位的问题。

对于这样的CT图像,您可能需要一个窗位在w=400,level=50左右,这是一个min=-150,max=250。请参阅Colby链接的文章。

您可以选择适合的窗位级别(即最小/最大)值,或者如Colby所提到的,从dicom文件中提取可能保存的WL值,并从中计算出最小/最大值(min = level - window/2,max = level + window/2)。

在您的代码中,请更改为以下内容:

level = dicom_file.WindowCenter
window = dicom_file.WindowWidth
# ...or set window/level manually to values you want
vmin = level - window/2
vmax = level + window/2
plt.imshow(hu_pixels, cmap='gray', vmin=vmin, vmax=vmax)
plt.show()

此外,你在一开始说:“我正在尝试进行一些分割任务。”
如果是这种情况,你需要直接使用16位数据,而不是8位版本,因为:
1. 它具有更高的数据范围,因此更适合用于分割。 2. 对于CT来说,实际值具有临床意义,因此对于分割至关重要。
所以,如果你的总体目标是分割,而不仅仅是如何显示图像,则使用正确的窗口/级别进行显示并不是太大的问题。对于分割,你需要意识到数据是完整的16位,并在完整的16位数据范围内使用它。
只需了解窗口/级别的工作原理,并使用imshow()按自己的需求进行显示,你就可以开始工作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接