Simone
Simone

Reputation: 4940

Per channel normalization of RGB images

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

Answers (1)

Stef
Stef

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

Related Questions