converting 12 bit DICOM image to 8 bit jpeg

无人久伴 提交于 2019-12-06 09:29:32

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. 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

Code: 1.Read the image

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

    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.

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

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 . read about Windowing equation here Window width and center calculation of DICOM image

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 . 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

Can follow this: 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

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)])
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!