【问题标题】:converting 12 bit DICOM image to 8 bit jpeg将 12 位 DICOM 图像转换为 8 位 jpeg
【发布时间】:2017-07-05 10:57:07
【问题描述】:

我正在尝试使用 dicom 库将 DICOM 文件加载到 python 中。我做了以下

ds=dicom.read_file(r"C:\Users\Z003SPFR.AD005\ML\GLCM AND SVM\data\NECT\1.IMA")
#    # store the raw image data
DicomImage = ds.pixel_array

这给了我看起来是 12 位的值,因为获得的最高值是 3047 左右,最低值是 0。然后我制作了自己的映射函数,将其带到 0-255 的范围内。我使用了以下代码:

leftMin = 0
leftMax = np.amax(DicomImage)

rightMin = 0
rightMax = 255



def translate(value, leftMin, leftMax, rightMin, rightMax):
    # Figure out how 'wide' each range is
    leftSpan = leftMax - leftMin
    rightSpan = rightMax - rightMin

    # Convert the left range into a 0-1 range (float)
    valueScaled = float(value - leftMin) / float(leftSpan)

    # Convert the 0-1 range into a value in the right range.
    return rightMin + (valueScaled * rightSpan)

#print(translate(value, leftMin, leftMax, rightMin, rightMax))



def int12_to_int8(img):
    img_array = []

    for eachRow in img:
        for eachPix in eachRow:
            img_array.append(translate(eachPix,leftMin, leftMax, rightMin, rightMax))
    img_array = np.array(img_array)
    img_array = img_array.reshape(512,512)  
    return img_array

correct_range_image = int12_to_int8(DicomImage)

这样做之后,我意识到数组 img_array 是 uint16 类型的。我想要它作为 uint8,所以我使用以下行转换为 uint8:

cvuint8 = cv2.convertScaleAbs(correct_range_image)

然后我显示了结果图像。但我收到的图像不能很好地代表原始图像。我已经发布了原始图像和转换图像的图片。如何使转换更好,以便更好地表示原始图像?我以前显示的代码在这里:

cv2.imwrite('1.jpeg', cvuint8 )
cv2.imshow('image',cvuint8 )[enter image description here][1]
cv2.waitKey(0)

图片

[1] 转换后的图像:https://i.stack.imgur.com/wdGCo.jpg [2] 原图:https://i.stack.imgur.com/JyfYI.jpg

【问题讨论】:

    标签: python dicom 8-bit cv2


    【解决方案1】:

    我找到了解决问题的方法。正如 Ahmed 上面提到的,DICOM 围绕重新调整斜率、截距和窗口级别/宽度进行正确显示。经过大量文档后,这里是使用 OpenCV、numpy 和 pydicom 库在 Python 中渲染 DICOM 的方法,这些库使所有工作变得简单

    代码: 1.阅读图片

    ds=dicom.read_file("image_path")
    # store the raw image data
    img = ds.pixel_array
    
    1. 使用重新缩放斜率并截取图像标题中的信息并进行翻译。

      rescale_slope=1 rescale_intercept=-1024

      def translate(value,rescale_slope,rescale_intercept):
      
      return (value*rescale_slope)+rescale_intercept 
      
      def int12_to_int8(DicomImage):
          img_array = []
      
      for eachRow in DicomImage:
          for eachPix in eachRow:
              img_array.append(translate(eachPix,rescale_slope,rescale_intercept))
      img_array = np.array(img_array)
      img_array = img_array.reshape(512,512)  
      return img_array
      
      img_1 = int12_to_int8(img)
      

    3.使用图像标题中的窗口级别和宽度信息在适当的范围内显示。

    def get_LUT_value(data, window, level)
    
        return np.piecewise(data, 
            [data <= (level - 0.5 - (window-1)/2),
                data > (level - 0.5 + (window-1)/2)],
                [0, 255, lambda data: ((data - (level - 0.5))/(window-1) + 0.5)*(255-0)])
    
    level=200
    window=800
    
    scaled_img=get_LUT_value(img, window, level)
    

    4.最后,得到想要的最终图像

    scaled_img = cv2.convertScaleAbs(scaled_img)
    cv2.imshow('image',scaled_img)
    cv2.imwrite("hem.jpg",scaled_img)
    cv2.waitKey(0)
    

    【讨论】:

      【解决方案2】:

      请参考http://dicom.nema.org/DICOM/2013/output/chtml/part04/sect_N.2.html,了解医学图像像素数据在显示之前是如何渲染的 并非所有提到的概念都适用,但我假设您缺少 Window level 和 window Center Values 的重要性。 在此处阅读有关窗口方程的信息 Window width and center calculation of DICOM image

      因此,如果您尝试在正确渲染之前降低图像的 bitDepth(丢失最不重要的数据),那么您肯定会得到一个坏图像。 考虑在转换之前对原始数据应用窗口,您可以在编写代码之前使用imageJ 工具查看实际的图像操作(WL,降级深度)

      【讨论】:

        【解决方案3】:

        可以按照这个: https://raw.githubusercontent.com/VolumeRC/AtlasConversionScripts/master/src/convertDICOM.py

        他们以简单的方式提到了使用窗口级别/宽度、重新调整斜率/截距的 DICOM 渲染

        def get_LUT_value(data, window, level,rescaleSlope,rescaleIntercept):
            return np.piecewise(data,
                                [((data * rescaleSlope) + rescaleIntercept) <= (level - 0.5 - (window - 1) / 2),
                                 ((data * rescaleSlope) + rescaleIntercept) > (level - 0.5 + (window - 1) / 2)],
                                [0, 255, lambda VAL: ((((VAL * rescaleSlope) + rescaleIntercept) - (level - 0.5)) / (
                                window - 1) + 0.5) * (255 - 0)])
        

        【讨论】:

          猜你喜欢
          • 2020-05-07
          • 1970-01-01
          • 2017-03-06
          • 2011-04-24
          • 2012-05-11
          • 1970-01-01
          • 2014-02-08
          • 1970-01-01
          • 2014-08-18
          相关资源
          最近更新 更多