How do I convert Pixel Data to a PNG image? #2126
Replies: 11 comments 3 replies
-
From a quick look at the dataset I would guess that you should apply the modality LUT and the VOI LUT before converting it to a PNG. |
Beta Was this translation helpful? Give feedback.
-
I tried the following code but got the same results, do i need to do something differently? Thanks! ds = dcmread(filepath) |
Beta Was this translation helpful? Give feedback.
-
Every time you're calling ds = dcmread(filepath)
arr = ds.pixel_array
arr = pydicom.pixels.processing.apply_modality_lut(arr, ds)
arr = pydicom.pixels.apply_voi_lut(arr, ds)
#save jpg
im = fromarray(arr)
im.save(folder + filename + '.png') |
Beta Was this translation helpful? Give feedback.
-
I tried this but I still only get a completely black png. This file can be opened with a dcm viewer and it displays a medical image. |
Beta Was this translation helpful? Give feedback.
-
Could you post a reproducible example, I don't know what |
Beta Was this translation helpful? Give feedback.
-
import pydicom ds = dcmread(filepath) |
Beta Was this translation helpful? Give feedback.
-
You can't save a float array as PNG, it needs to be converted to ints. Also, that isn't the example I posted, those functions return a new ndarray instance (as it says in the documentation). The other probable issue is you're just blinding converting some data to PNG without rescaling it. If you're using 16-bit PNGs then your actual image data range will be ~[0, 3542], so of course it will appear dark. |
Beta Was this translation helpful? Give feedback.
-
@scaramallion thank you so much. I tried with the correct code but i get the error OSError: cannot write mode F as JPEG |
Beta Was this translation helpful? Give feedback.
-
You can't write floats to JPEG either. Pretty much all image formats require ints in a specific range. |
Beta Was this translation helpful? Give feedback.
-
Simple example for 16-bit PNGs: from pydicom import dcmread
from PIL import Image
ds = dcmread("2122.dcm")
arr = ds.pixel_array
# Convert to floats
f_arr = arr.astype(float)
# Rescale to use full 16-bit range
f_arr /= arr.max()
f_arr *= (2**16 - 1)
print(f_arr.max()) # 65535.0
# Convert to uint16
u16_arr = f_arr.astype("u2")
print(u16_arr.max()) # 65535
im = Image.fromarray(u16_arr)
im.save("2122.png") |
Beta Was this translation helpful? Give feedback.
-
@scaramallion this is amazing but how do I know if this type of conversion is necessary or not from the ds data? I'm looking through but there are many properties |
Beta Was this translation helpful? Give feedback.
-
The attached file is converted to a black image rather than the actual image using the following code:
ds = dcmread(filepath)
im = fromarray(ds.pixel_array)
im.save(folder + filename + '.png')
https://drive.google.com/file/d/1DwJNQDChz3J79ylqgpSG7RUwvlhAIG5P/view?usp=sharing
Beta Was this translation helpful? Give feedback.
All reactions