test fixing thumbnails

This commit is contained in:
Ross
2025-04-14 10:38:35 +01:00
parent 5d37cf4284
commit edf4a992de
+84 -4
View File
@@ -25,7 +25,7 @@ have_PIL = True
try:
import PIL.Image, PIL.ImageOps
from pydicom.pixel_data_handlers.util import apply_voi_lut, apply_modality_lut
from pydicom.pixels import apply_voi_lut, apply_modality_lut, apply_windowing
except ImportError:
have_PIL = False
@@ -36,6 +36,32 @@ try:
except ImportError:
have_numpy = False
def lin_stretch_img(img, low_prc, high_prc, do_ignore_minmax=True):
"""
Apply linear "stretch" - low_prc percentile goes to 0,
and high_prc percentile goes to 255.
The result is clipped to [0, 255] and converted to np.uint8
Additional feature:
When computing high and low percentiles, ignore the minimum and maximum intensities (assumed to be outliers).
"""
# For ignoring the outliers, replace them with the median value
if do_ignore_minmax:
tmp_img = img.copy()
med = np.median(img) # Compute median
tmp_img[img == img.min()] = med
tmp_img[img == img.max()] = med
else:
tmp_img = img
lo, hi = np.percentile(tmp_img, (low_prc, high_prc)) # Example: 1% - Low percentile, 99% - High percentile
if lo == hi:
return np.full(img.shape, 128, np.uint8) # Protection: return gray image if lo = hi.
stretch_img = (img.astype(float) - lo) * (255/(hi-lo)) # Linear stretch: lo goes to 0, hi to 255.
stretch_img = stretch_img.clip(0, 255).astype(np.uint8) # Clip range to [0, 255] and convert to uint8
return stretch_img
def get_LUT_value(data, window, level):
"""Apply the RGB Look-Up Table for the given
@@ -65,7 +91,7 @@ def get_PIL_image(dataset):
# Apply modality lut
array = apply_modality_lut(dataset.pixel_array, dataset)
#array = apply_modality_lut(dataset.pixel_array, dataset)
# voi lut doesn't seem to help
#array = apply_voi_lut(array, dataset)
@@ -89,14 +115,21 @@ def get_PIL_image(dataset):
# PIL size = (width, height)
size = (dataset.Columns, dataset.Rows)
array = apply_modality_lut(dataset.pixel_array, dataset)
array = dataset.pixel_array
#array = apply_modality_lut(array, dataset)
array = apply_voi_lut(array, dataset, index=0)
#array = apply_windowing(array, dataset)
array = lin_stretch_img(array, 0.1, 99.9) # Apply "linear stretching" (lower percentile 0.1 goes to 0, and percentile 99.9 to 255).
array = apply_voi_lut(array, dataset)
if dataset["PhotometricInterpretation"].value == "MONOCHROME1":
# We need to invert
array = np.invert(array)
return PIL.Image.fromarray(array).convert('L')
pixel_data = array.tostring()
# Recommended to specify all details
# by http://www.pythonware.com/library/pil/handbook/image.htm
@@ -116,6 +149,53 @@ def get_PIL_image(dataset):
return im
def get_PIL_image2(dataset):
"""Get Image object from Python Imaging Library(PIL)"""
if not have_PIL:
raise ImportError("Python Imaging Library is not available. "
"See http://www.pythonware.com/products/pil/ "
"to download and install")
if ('PixelData' not in dataset):
raise TypeError("Cannot show image -- DICOM dataset does not have "
"pixel data")
# can only apply LUT if these window info exists
if ('WindowWidth' not in dataset) or ('WindowCenter' not in dataset):
bits = dataset.BitsAllocated
samples = dataset.SamplesPerPixel
if bits == 8 and samples == 1:
mode = "L"
elif bits == 8 and samples == 3:
mode = "RGB"
elif bits == 16:
# not sure about this -- PIL source says is 'experimental'
# and no documentation. Also, should bytes swap depending
# on endian of file and system??
mode = "I;16"
else:
raise TypeError("Don't know PIL mode for %d BitsAllocated "
"and %d SamplesPerPixel" % (bits, samples))
# PIL size = (width, height)
size = (dataset.Columns, dataset.Rows)
# Recommended to specify all details
# by http://www.pythonware.com/library/pil/handbook/image.htm
im = PIL.Image.frombuffer(mode, size, dataset.PixelData,
"raw", mode, 0, 1)
else:
ew = dataset['WindowWidth']
ec = dataset['WindowCenter']
ww = int(ew.value[0] if ew.VM > 1 else ew.value)
wc = int(ec.value[0] if ec.VM > 1 else ec.value)
image = get_LUT_value(dataset.pixel_array, ww, wc)
# Convert mode to L since LUT has only 256 values:
# http://www.pythonware.com/library/pil/handbook/image.htm
im = PIL.Image.fromarray(image).convert('L')
return im
def show_PIL(dataset):
"""Display an image using the Python Imaging Library (PIL)"""
im = get_PIL_image(dataset)