简体   繁体   中英

How to convert a 3d RGB NumPy array to float without changing the image?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM