我正在尝试使用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)并使用 pixel_array 属性显示图像时, ,我得到的图像质量比原始图像差很多(请从下面查看代码和屏幕截图)。
dicom_file = pydicom.read_file('Anonymized20191102.dcm')
plt.imshow(dicom_file.pixel_array, cmap='gray')
plt.show()
为了更好地理解问题,我的问题是:
观察:
我还尝试通过乘以斜率并加上偏差来获得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之间,我认为这很好)。
答案 0 :(得分:3)
第二张图像看起来已使用适合所有提供的HU值的灰度范围绘制了像素,而不仅仅是显示与所显示的解剖结构相对应的HU值范围。
虽然我不确定pydicom如何处理此问题,但您需要“缩放和缩放”图像以从第一张图像中获得结果。通常通过线性VOI LUT为CT图像应用窗口/级别将限制显示像素的范围,并将其缩放到可显示范围,通常为8位,除非使用灰度监视器。
CT图像很可能具有用于窗口中心(0028,1050)来设置级别和用于窗口宽度(0028,1051)来设置窗口的标签。图像中的中心和宽度值由生成图像的模态提供,并对应于显示图像中腹部区域的良好范围。下面的链接提供了一些基于正在查看的身体部位的CT图像的常见窗口/级别设置,还提供了有关设置如何影响显示图像的更多信息。
https://radiopaedia.org/articles/windowing-ct
虽然应用窗口/级别对显示图像很有用,但您却失去了位深,因为它是将每个像素存储的10或12位(CT图像常见)转换为每个像素显示的8位。您需要确定分段任务是否需要此额外的位深度。
答案 1 :(得分:0)
像Colby said一样,看起来错误的原因几乎可以肯定是窗口级别。
对于这样的CT图像,您可能希望窗口水平大约在w = 400,水平= 50,这是最小值= -150,最大值= 250。参见链接到Colby的文章。
您可以选择适合的窗口级别值(即最小/最大值),或者如Colby所述,将其从dicom文件中可能保存的WL值中拉出,然后从中计算出最小/最大值(最小=级别-窗口/ 2,最大值=级别+窗口/ 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位版本。...因此,如果您的总体目标是分割,而不仅仅是简单地显示图像,那么以正确的窗口/级别显示并不是什么大问题。对于分段,您需要意识到数据是完整的16位,并在完整的16位数据范围内使用它。
只需弄清楚WL的工作原理,以及如何使用imshow()根据需要/需要/想要显示它,就可以了。