I am trying to save an image that is in RGB pixel form. For whatever reason, when I call matplotlib.pyplot.imshow
, the image is displayed properly.
However, when I call matplotlib.pyplot.imsave
, I get an error that the array has to be in float
. When I decided to change all the values to float
, the image is completely modified. It makes no sense to me.
def display_image(pixels, name=""):
if name:
plt.imsave(name, array)
plt.imshow(array)
pixels = im.getdata()
pixelMap = im.load()
npImage = np.array(pixels).reshape(671, 450, 3)
display_image(npImage) ## great!
# things that I tried
display_image(npImage, "image.jpg") ## error, must be floats.
# changes the images
pixels = list(pixels) ## pixels var originally imagecore class
for index in range(len(pixels)):
pixels[index] = (float(pixels[index][0]), float(pixels[index][1]), float(pixels[index][2]))
display_image(npImage, "monaLisa.jpg") ## works but incorrect image
Before I'll give an answer to your actual question, a few words regarding your comment, and why you might got a downvote on your question. Your code is no minimal, reproducible example , and also not working as is.
You're missing all the necessary imports:
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image
One of your method parameters is wrong:
def display_image(pixels, name=""): # <-- I assume, pixels should be array here.
if name:
plt.imsave(name, array)
plt.imshow(array)
plt.show() # <-- Without, there's no actual output.
What's im
? Most likely, that's some PIL image. Also, you hard-coded some values, without providing the corresponding image.
im = Image.open('someImage.jpg') # <-- Need to load some image at all.
pixels = im.getdata()
pixelMap = im.load()
npImage = np.array(pixels).reshape(671, 450, 3) # <-- That only works for images with the specific size
display_image(npImage) ## great!
In the last test case, you're not updating npImage
:
pixels = list(pixels) ## pixels var originally imagecore class
for index in range(len(pixels)):
pixels[index] = (float(pixels[index][0]), float(pixels[index][1]), float(pixels[index][2]))
# <-- You updated pixels, but not npImage
display_image(npImage, "monaLisa.jpg")
Only after fixing all these issues, one comes to the actual error, you're talking about in your question!
Now, to your error:
Traceback (most recent call last):
File "[...].py", line 18, in <module>
display_image(npImage, "image.jpg") ## error, must be floats.
[...]
ValueError: Image RGB array must be uint8 or floating point; found int32
Your npImage
is of type int32
, but plt.imsave
expects uint8
(values 0 ... 255)
or float
(values 0.0 ... 1.0
) for writing.
So, let's enforce uint8
:
npImage = np.array(pixels, dtype=np.uint8).reshape(..., 3)
After adding the necessary update of npImage
as mentioned above
pixels = list(pixels) ## pixels var originally imagecore class
for index in range(len(pixels)):
pixels[index] = (float(pixels[index][0]), float(pixels[index][1]), float(pixels[index][2]))
npImage = np.array(pixels).reshape(..., 3) # <-- This line
display_image(npImage, "monaLisa.jpg") ## works but incorrect image
the following error occurs:
Traceback (most recent call last):
File "[...].py", line 25, in <module>
display_image(npImage, "monaLisa.jpg") ## works but incorrect image
[...]
ValueError: Floating point image RGB values must be in the 0..1 range.
You haven't scaled your float
values to 0.0 ... 1.0
. So, we just divide by 255
:
npImage = np.array(pixels).reshape(..., 3) / 255
I couldn't reproduce your "completely modified image" (due to possibly missing code fragments), but most likely this was also due to the unscaled float
values, and you possibly saw clipping. (Was the image almost white?)
Hope that helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.