简体   繁体   English

将 12 位 DICOM 图像转换为 8 位 jpeg

[英]converting 12 bit DICOM image to 8 bit jpeg

I am trying to load DICOM files into python using the dicom library.我正在尝试使用 dicom 库将 DICOM 文件加载到 python 中。 I have done the following我做了以下

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

This gives me values that appear to be 12 bit, since the highest value obtained was around 3047 and lowest value was 0. Then i made my own mapping function to bring it to the range 0-255.这给了我看起来是 12 位的值,因为获得的最高值大约是 3047,而最低值是 0。然后我制作了自己的映射函数,将它带到 0-255 的范围内。 I used the following code:我使用了以下代码:

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)

After doing this I realized that the array img_array was of type uint16.这样做之后,我意识到数组 img_array 的类型是 uint16。 I wanted it as uint8, so i used the following line to convert to uint8:我想要它作为 uint8,所以我使用以下行转换为 uint8:

cvuint8 = cv2.convertScaleAbs(correct_range_image)

Then I displayed the resulting image.然后我显示了结果图像。 But i received an image that didn't represent the original image very well.但是我收到的图像不能很好地代表原始图像。 I have posted pictures of the original image and the converted image.我已经发布了原始图像和转换图像的图片。 How can I make the conversion better so that I get a better representation of the original image??如何使转换更好,以便更好地表示原始图像? Code I used to display is here :我用来显示的代码在这里:

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

IMAGES图片

[1] Converted Image: https://i.stack.imgur.com/wdGCo.jpg [2] Original Image: https://i.stack.imgur.com/JyfYI.jpg [1] 转换图: https : //i.stack.imgur.com/wdGCo.jpg [2] 原图: https : //i.stack.imgur.com/JyfYI.jpg

I figured out the solution for my problem.As mentioned above by Ahmed, DICOM plays around rescale slope, intercept and window level/width for proper display.我找到了解决我的问题的方法。正如 Ahmed 上面提到的,DICOM 会围绕重新调整斜率、截距和窗口级别/宽度进行播放,以便正确显示。 After going through lot of documents, here is the way to render DICOM in Python using OpenCV,numpy and pydicom libraries which make all work easy在浏览了大量文档后,这里是使用 OpenCV、numpy 和 pydicom 库在 Python 中呈现 DICOM 的方法,这使所有工作变得容易

Code: 1.Read the image代码: 1.读取图像

ds=dicom.read_file("image_path")
# store the raw image data
img = ds.pixel_array
  1. Use rescale slope and intercept information from the image header and translate it.使用重新调整斜率并截取图像标题中的信息并进行翻译。

    rescale_slope=1 rescale_intercept=-1024 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.Use window level and width information from the image header to display in the proper range. 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.Finally, with final image as wanted 4.最后,根据需要使用最终图像

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

please refer to http://dicom.nema.org/DICOM/2013/output/chtml/part04/sect_N.2.html to see how the medical image pixel data is rendered before its displayed not all mentioned concepts is applied but i assume your missing the importance of Window level and window Center Values .请参阅http://dicom.nema.org/DICOM/2013/output/chtml/part04/sect_N.2.html以了解医学图像像素数据在显示之前是如何呈现的,并非所有提到的概念都适用,但我假设您错过了 Window level 和 window Center Values 的重要性。 read about Windowing equation here Window width and center calculation of DICOM image在此处阅读有关 Windowing equation 的 DICOM 图像的窗口宽度和中心计算

So if you are trying to downgrade the bitDepth of the Image before its correctly rendered (losing least important data) , for sure you will get a bad image .因此,如果您试图在图像正确呈现(丢失最不重要的数据)之前降级图像的 bitDepth,那么您肯定会得到一个糟糕的图像。 consider applying windowing on original data before conversion , you can play with imageJ tool to see image operations (WL , Downgrading Depth) in action before writing the code for it考虑在转换前对原始数据应用窗口化,您可以在为其编写代码之前使用imageJ工具查看图像操作(WL,降级深度)的实际效果

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

where in simple way they have mentioned DICOM rendering using window level/width, rescale slope/intercept他们以简单的方式提到了使用窗口级别/宽度、重新调整斜率/截距的 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)])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM