1

So I'm experiencing a weird visual glitch when creating an empty numpy array and loading an image in it as follows:

import numpy as np
from imageio import imread
import matplotlib.pyplot as plt

dir_path = os.path.join('path/to/image', 'a.jpg')
# Pre-indexing numpy array
X = np.empty((1, *(111, 455), 4))

# Loading image in the traditional way:
img_0 = imread(dir_path)
# Loading image and saving it in the pre-indexed array:
X[0] = imread(dir_path)

# Check whether image contents are the same
print((img_0 == X[0]).all())

# Display images
imgplot = plt.imshow(X[0])
plt.show()
imgplot = plt.imshow(img_0)
plt.show()

So in this code I'm importing an image a.jpg either through the traditional imread or by saving it in a numpy array. Theoretically the two methods should be equivalent, in fact print((img_0 == X[0]).all()) returns True.

However, this are the plt.show() results:

numpy image: numpy image

traditional image: traditional image

If the contents of the two arrays are exactly the same, how is it possible that the two images are displayed differently when imported by the same imread function?

sacuL
  • 49,704
  • 8
  • 81
  • 106
universvm
  • 353
  • 2
  • 11

1 Answers1

5

The problem is that when you put the image into your array X, it went from int to float, and the scaling methods differ with plt.imshow between ints and floats. This is described in the warning message you probably got:

Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).

What you can do is either instantiate X as an int array, or force X[0] to dtype int, or normalize the image to be between 0 and 1 by dividing by 255:

# Method 1:
X = np.empty((1, *(111, 455), 3), dtype=int)
X[0] = imread(dir_path)

imgplot = plt.imshow(X[0])
plt.show()

# Method 2:
X = np.empty((1, *(111, 455), 3))
X[0] = imread(dir_path)

imgplot = plt.imshow(X[0].astype(int))
plt.show()

# method 3:
imgplot = plt.imshow(X[0]/255)
plt.show()

Following either of those methods, you will get:

enter image description here

sacuL
  • 49,704
  • 8
  • 81
  • 106
  • Thanks! That's clear. I didn't know that for example float(1.0) == int(1) would return True in Python. I was very confused by this. It's weird, I didn't get any warning when running that code, but now everything works :) thanks! – universvm Nov 07 '18 at 07:49