4

Today, I came across a weird thing that I cannot explain and cannot find an answer to. Maybe I have some fundamental misunderstanding and I am not seeing the obvious, but I guess I am at the point where I will bite the bullet of being called out over now knowing what is going on.

I am loading some image data using PIL and converting it into a numpy array. Nothing fancy here. However, I am then changing the data type from integer to float so I can normalize the RGB channels in a later step.

I would expect that changing the datatype from int to float wouldn't really change the image in any way. However ...

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

im = Image.open("test.jpg")

before the dtype change:

plt.imshow(np.array(im))  

enter image description here

after the dtype change:

plt.imshow(np.array(im).astype(float))    

enter image description here

Is this what one would expect? If so ... why? What am I missing?

Cheers & thanks in advance!!

2 Answers 2

3

If you check the docs you'll see that imshow expects:

  • (M, N): an image with scalar data. The values are mapped to colors using normalization and a colormap. See parameters norm, cmap, vmin, vmax.

  • (M, N, 3): an image with RGB values (0-1 float or 0-255 int).

So when the are of dtype float, it expects them to be in the range 0-1, hence we have to divide it by 255 to get the expected result, otherwise you will see the negative of the image.

Here's an example using a sample image from sklearn.datasets:

from sklearn.datasets import load_sample_images
dataset = load_sample_images()     
first_img_data = dataset.images[0]
plt.imshow(first_img_data)

enter image description here

In order to limit the values in the range 0-1, we just have to divide by 255:

plt.imshow(first_img_data.astype(float)/255)

enter image description here

Sign up to request clarification or add additional context in comments.

5 Comments

Why do you see the negative of the image?
Thanks. It makes sense when you explain it like that.
Well @mad ... The question from the link asks exactly that. That is how i saw myself which is the reason by seing that post. I figured just directing you to it is the easiest way
I wasn't being sarcastic, but looking back I can see that there's no other way to read my comment. The effect of re-multiplying by 255 is indeed clearly the issue.
Thank you! Duh, in retrospect.
0

The following is written in the matplotlib.pyplot.imshow function:

Parameters:
        X : array-like or PIL image
            The image data. Supported array shapes are:
            - (M, N): an image with scalar data. The values are mapped to
              colors using normalization and a colormap. See parameters *norm*,
              *cmap*, *vmin*, *vmax*.
            - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
            - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
              i.e. including transparency.

this work for you:

plt.imshow(np.array(im).astype(float)/255)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.