Reputation: 4940
I would like to know how I can manually normalize an RGB
image.
I tried:
img_name = 'example/abc/myfile.png'
img = np.asarray(Image.open(img_name))
img = np.transpose(img, (2,0,1))
(img/255.0 - mean)/std
mean
and std
has shape (3,)
When I run the code above I get this error:
ValueError: operands could not be broadcast together with shapes (3,512,512) (3,)
How can we normalize each channel individually?
Upvotes: 2
Views: 2258
Reputation: 30579
Normalization means to transform to zero mean and unit variance. This is done by subtracting the mean and dividing the result by the standard deviation.
You can do it per channel by specifying the axes as x.mean((1,2))
instead of just x.mean()
. In order to be able to broadcast you need to transpose the image first and then transpose back.
import numpy as np
np.random.seed(0)
c = 3 # number of channels
h = 2 # height
w = 4 # width
img = np.random.randint(0, 255, (c, h, w))
img_n = ((img.T - img.mean((1,2))) / img.std((1,2))).T
Original image:
array([[[172, 47, 117, 192],
[ 67, 251, 195, 103]],
[[ 9, 211, 21, 242],
[ 36, 87, 70, 216]],
[[ 88, 140, 58, 193],
[230, 39, 87, 174]]])
Normalized image:
array([[[ 0.43920493, -1.45391976, -0.39376994, 0.74210488],
[-1.15101981, 1.63565973, 0.78753987, -0.6057999 ]],
[[-1.14091546, 1.10752281, -1.00734487, 1.45258017],
[-0.84038163, -0.27270662, -0.46193163, 1.16317723]],
[[-0.59393963, 0.21615508, -1.06130196, 1.04182853],
[ 1.61824207, -1.35729811, -0.60951837, 0.74583239]]])
Verify zero mean and unit standard deviation per channel print(img_n.mean((1,2)), img_n.std((1,2)))
:
[-1.38777878e-17 0.00000000e+00 0.00000000e+00]
[1. 1. 1.]
Upvotes: 3