Jagadeesh Jagadeesh - 2 months ago 14
Python Question

Matplotlib - how to rescale pixel intensities for RGB image

I am confused regarding how matplotlib handles fp32 pixel intensities. To my understanding, it rescales the values between max and min values of the image. However, when I try to view images originally in [0,1] by rescaling their pixel intensites to [-1,1] (by im*2-1) using imshow(), the image appears differently colored. How do I rescale so that images don't differ ?

EDIT : Please look at the image -

PS: I need to do this as part of a program that outputs those values in [-1,1]

Following is the code used for this:

img = np.float32(misc.face(gray=False))
fig,ax = plt.subplots(1,2)
img = img/255 # Convert to 0,1 range
print (np.max(img), np.min(img))
img0 = ax[0].imshow(img)
plt.colorbar(img0,ax=ax[0])
print (np.max(2*img-1), np.min(2*img-1))
img1 = ax[1].imshow(2*img-1) # Convert to -1,1 range
plt.colorbar(img1,ax=ax[1])
plt.show()


The max,min output is :

(1.0, 0.0)
(1.0, -1.0)

Answer

You are probably using matplotlib wrong here.

The normalization-step should work correctly, if it's active. The docs tell us, that is only active by default, if the input-image is of type float!

Code

import numpy as np
import matplotlib.pyplot as plt
from scipy import misc

fig, ax = plt.subplots(2,2)

# This usage shows different colors because there is no normalization
# FIRST ROW
f = misc.face(gray=True)
print(f.dtype)
g = f*2  # just some operation to show the difference between usages
ax[0,0].imshow(f)
ax[0,1].imshow(g)

# This usage makes sure that the input-image is of type float
# -> automatic normalization is used!
# SECOND ROW
f = np.asarray(misc.face(gray=True), dtype=float)  # TYPE!
print(f.dtype)
g = f*2  # just some operation to show the difference between usages
ax[1,0].imshow(f)
ax[1,1].imshow(g)

plt.show()

Output

uint8
float64

enter image description here

Analysis

The first row shows the wrong usage, because the input is of type int and therefore no normalization will be used.

The second row shows the correct usage!

EDIT:

sascha has correctly pointed out in the comments that rescaling is not applied for RGB images and inputs must be ensured to be in [0,1] range.

Comments