Issue
I have a 2D array of an image (slice). The array dimension is (224, 224) and when I read it as an image as shown below, the image mode is shown as "F", for some reason I need to save as "PNG" and display it. I'm gettig error message "ValueError: conversion from L to PNG not supported"
The real image is shown below. See the below code.
from matplotlib import pyplot as plt
from PIL import Image
from matplotlib import cm
# reproducible data
slice = np.ones([224, 224], dtype = float)
print(slice.shape)
img_m3= Image.fromarray(slice)#.convert('RGB')#.convert('PNG')
print("img .mode",img_m3 .mode)
if img_m3 .mode != 'PNG':
img_m3 = img_m3.convert('PNG')
img_m3.save("/tmp/myimageb.png", "PNG")
im = Image.open("/tmp/myimageb.png")
plt.imshow(im )#, vmin=0, vmax=255)
plt.show()
Update:
I also tried saving it as JPG, no errors, but I got blank image:
if img_m3 .mode != 'RGB':
img_m3 = img_m3.convert('RGB')
img_m3.save("/tmp/myimageb.jpg", 'JPEG')
#plt.imshow(img , cmap='gray', vmin=0, vmax=255)
im = Image.open("/tmp/myimageb.jpg")
plt.imshow(im )#, vmin=0, vmax=255)
plt.show()
Update2:
I tried the solution on the answer, now I can see the image. But the quality degraded. See below, on top is the original image and bottom is the result.
import cv2
from matplotlib import pyplot as plt
from PIL import Image
print(image[0].shape)
print("slice.max()",slice.max())
print("slice.min()",slice.min())
print("slice.mean()",slice.mean())
slice.min() and slice.mean()
#img = Image.fromarray((slice*255).astype(np.uint8)).convert('L')
img = Image.fromarray(slice.astype(np.uint8))
img.save("/tmp/myimageb.png", "PNG")
plt.imshow(img )#, cmap='gray', vmin=0, vmax=255)
plt.show()
(224, 224)
slice.max() 0.5193082
slice.min() -2.0836544
slice.mean() -0.37065452
Solution
Updated Answer
It transpires that the pixels are both float AND potentially negative, so you probably want an image format that can store such things which is TIFF.
import numpy as np
from PIL import Image
# Make single channel 224x244 image of floats in range -2...+2
slice = np.random.uniform(low=-2, high=2, size=(224,224))
# Convert to 224x224 to PIL 'F' Image
im = Image.fromarray(slice)
im.save('result.tiff')
Just a couple of notes:
TIFF files can get rather large because they are uncompressed by default, so you might want to try different compression options to see if anything suits your data
OpenCV also has a FileStorage format - but this is not readily viewable by other programs
OpenCV supports OpenEXR format for floats too and this is quite readily viewable by other software
Original Answer
The following should work fine for you:
import numpy as np
from PIL import Image
# Make single channel 224x244 image of floats in range 0..255
slice = np.random.rand(224,224) * 255
# Convert to 224x224 array of uint8 and then to PIL 'L' Image
im = Image.fromarray(slice.astype(np.uint8))
im.save('result.png')
print(im) # prints <PIL.Image.Image image mode=L size=224x224>
Answered By - Mark Setchell
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.