将灰色pixel_array从DICOM转换为RGB图像

时间:2019-11-11 12:04:39

标签: python pydicom

我正在读取DICOM灰色图像文件

gray = dicom.dcmread(file).pixel_array

我有(x,y)形状,但我需要RGB(x,y,3)形状

我正在尝试使用CV进行转换

img = cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB)

为了进行测试,我将其写入文件cv2.imwrite('dcm.png', img)

我的输出图像非常暗,这是错误的,将pydicom图像转换为RGB的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

有关读取DICOM文件的完整教程,请参见:https://www.kaggle.com/gzuidhof/full-preprocessing-tutorial

基本上,您必须从DICOM文件中提取参数slopeinterception并为每个像素做数学运算:hu = pixel_value * slope + intercept-所有这些都在本教程中使用代码示例进行了说明。和图片。

答案 1 :(得分:1)

要回答您的问题,您需要提供更多信息,并且要更加清楚。

首先,您想做什么?您是否正在尝试仅在内存中获得(x,y,3)数组?还是您正在尝试将dicom文件转换为.png文件? ...它们是完全不同的东西。

第二,您的dicom图像是什么形式?

这可能是16位灰度图像(除非是超声检查或可能是nuc med),这意味着数据是16位,这意味着上面的var returnitem = await graphserviceClient.Sites["Site-ID"].Drives["Dive-ID"].Root.Children.Request().GetAsync();//gets all Children in the drive var returnitemfiles = await graphserviceClient.Sites["Site-ID"].Drives["Drive-ID"].Items["File-ID"].Children.Request().GetAsync();//gets one Child and returns all the Children of that file var returnitemfile = await graphserviceClient.Sites["Site-ID"].Drives["Dive-ID"].Items["File-ID"].ItemWithPath(fileBase.FileName).Content.Request().PutAsync<DriveItem>(fileBase.InputStream);//upload a file to the drive in a folder by id only usable for small files under 4 MB 数组是16位数据。

因此,首先要了解的是窗口调整以及如何以8位显示16位图像。在这里看看:http://www.upstate.edu/radiology/education/rsna/intro/display.php

如果它是16位图像,如果要以rgb格式将其查看为灰度图像,则需要知道正在使用或需要的窗口级别,并在保存之前进行适当的调整。

第三,就像lenik提到above一样,您需要在使用之前将dicom斜率/截距值应用于像素数据。


如果您的问题只是为rgb制作一个具有额外维度的新数组(大小为(r,c)至(r,c,3)),那么这很容易

gray

这将为您提供第三维。但是,如果您希望将其设为RGB,则这些值仍将全部为16位,而不是所需的8位。 (假设您使用dcmread读取的图像是CT,MR或等效的16位dicom-那么dtype可能是uint16)。

如果要使其为RGB,则需要将值从16位转换为8位。为此,您需要确定一个窗口/级别,并将其应用于从整个16位数据范围中选择8位值。


同样,您上面的问题-# orig is your read in dcmread 2D array: r, c = orig.shape new = np.empty((w, h, 3), dtype=orig.dtype) new[:,:,2] = new[:,:,1] = new[:,:,0] = orig # or with broadcasting new[:,:,:] = orig[:,:, np.newaxis] -实际上是正确的,但它很暗,因为默认情况下使用的窗口/级别cv使其“看起来”很暗,或者是正确的,但您没有应用斜率/拦截。


如果您想要将dicom转换为png(或jpg),那么您可能应该使用I've got extremely dark image on output which is wrongPIL而不是matplotlib。两者都提供了保存16位2D数组的简便方法(上面的代码中就是'cv'),这两种方法都允许您在保存为png或jpg时指定窗口和级别。 CV是完全矫kill过正(意味着更大/更慢的加载,以及更高的学习曲线)。

使用matplotlib的一些伪代码。您需要调整的vmin / vmax值-对于CT图像,这里的值大约可以确定。

gray

将保存png版本,但也会绘制轴。要将图像另存为无轴且无空格的图像,请使用以下方法:


    import matplotlib.pyplot as plt

    df = dcmread(file)
    slope = float(df.RescaleSlope)
    intercept = float(df.RescaleIntercept)
    df_data = intercept + df.pixel_array * slope

    # tell matplotlib to 'plot' the image, with 'gray' colormap and set the
    # min/max values (ie 'black' and 'white') to correspond to 
    # values of -100 and 300 in your array
    plt.imshow(df_data, cmap='gray', vmin=-100, vmax=300)

    # save as a png file
    plt.savefig('png-copy.png')