Open SolarLiner opened 6 years ago
With regards to the floating point data, if I change if from 2**16-1
to 2**8-1
, it works fine.
import numpy
from PIL import Image
img = Image.open('/Users/andrewmurray/Desktop/16bit_image.png')
img_float = Image.fromarray(numpy.divide(numpy.array(img), 2**8-1))
print(numpy.array(img_float))
img_oct = img_float.convert('L')
print(numpy.array(img_oct))
[[202.19215 206.76863 199.50981 ... 119.58039 121.53333 117.28236 ]
[202.91373 204.64706 200.86667 ... 120.9451 117.333336 120.75687 ]
[201.09412 198.17255 200.50197 ... 123.6549 120.988235 120.2 ]
...
[110.933334 109.28628 109.92941 ... 134.77255 134.2549 134.55687 ]
[105.4902 108.10588 110.27451 ... 142.07451 135.71373 130.97647 ]
[109.670586 110.68235 109.6549 ... 142.05098 140.59216 135.20392 ]]
[[202 206 199 ... 119 121 117]
[202 204 200 ... 120 117 120]
[201 198 200 ... 123 120 120]
...
[110 109 109 ... 134 134 134]
[105 108 110 ... 142 135 130]
[109 110 109 ... 142 140 135]]
With regards to the first part, I've created PR #3838 to address this.
Thanks a lot for that. It'll help a lot for my terrain generation library!
It turns out that this situation is more complicated. See https://github.com/python-pillow/Pillow/pull/3838#discussion_r292114051
I don't understand is this happening or not?
fp = "/home/max/dev_projects/cuda_blob/data/S_000_1752450056/Tile_r1-c1_S_000_1752450056.tif"
img = Image.open(fp).convert('I').convert('F')
imarray = cp.array(img)
print(imarray.min(), imarray.max())
gives
0.0 254.0
Shouldn't the pixel values be scaled to [0,1]
?
using
pillow 8.0.1
python 3.8.5
This issue is more complex to resolve than I initially thought, and there is not even a consensus that it should be fixed.
I think this is related. I noticed that https://github.com/python-pillow/Pillow/blob/3f960d9a94e5f2cd789da8b9fd0d1d6db8a60cba/src/libImaging/Fill.c uses the same 0-255 range for every image type.
I am currently using this snippet to work around this issue:
def safe_image_loading(path: str) -> Image:
img = Image.open(path)
bit_size = re.findall(r"\d+", img.mode)
bit_size = int(bit_size[0]) if bit_size else 8
if bit_size not in [8, 16, 32]:
raise ValueError(f"Unsupported file type, supported bit size is {bit_size}")
if bit_size != 8:
max_value = 2**bit_size - 1
img_arr = (np.array(img) / max_value) * 255.0
img = Image.fromarray(img_arr.astype(np.uint8))
return img.convert("L")
would be great to have native support for bit sizes in PIL.
What did you do?
I tried to convert grayscale images of different modes together
What did you expect to happen?
Conversion should scale values; for example, converting from float to 8-bit should have the values scaled by 255, converting from 8-bit to 16-bit should have the values scaled by 65535/255, etc.
What actually happened?
Values are being clamped
Floating point data really doesn't go over well either
The input image is a 16 bit PNG made with GIMP, as attached below. terrain_input.png
What versions of Pillow and Python are you using?
Using Python 3.6.5 and Pillow 5.1.0