1

I am trying to centralize an image globally using

# example of global centering (subtract mean)
from numpy import asarray
from PIL import Image

# load image
image = Image.open('13.jpg')
pixels = asarray(image)

# convert from integers to floats
pixels = pixels.astype('float32')

# calculate global mean
mean = pixels.mean()
print('Mean: %.3f' % mean)
print('Min: %.3f, Max: %.3f' % (pixels.min(), pixels.max()))

# global centering of pixels
global_pixels = pixels - mean

# confirm it had the desired effect
mean = global_pixels.mean()
print('Mean: %.3f' % mean)
print('Min: %.3f, Max: %.3f' % (global_pixels.min(), global_pixels.max()))

Then centralize using

# normalize to the range 0-1
pixels_new = global_pixels/ 255.0

# confirm the normalization
print('Min: %.3f, Max: %.3f' % (pixels_new.min(), pixels_new.max()))

plt.imshow(np.array(pixels_new))

plt.imsave('test1.png', pixels_new)

I get a warning and then an error

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

and then on the plt.imsave function

ValueError: Floating point image RGB values must be in the 0..1 range.

Can anyone kindly explain what is wrong ?

PolarBear10
  • 2,065
  • 7
  • 24
  • 55

2 Answers2

0

i prefere opencv because the fanbase is bigger and its easier to use it in combiantion with numpy. I wrote you an short example how to deal with the red channel, because i assumed you want to average all three layers seperately, and apply the mean for every channel individually:

from numpy import asarray
import cv2
import numpy as np
import matplotlib.pyplot as plt

path="/content/111.jpg"

# load image
img=cv2.imread(path,1)

# mean Pixel of Red layer
mean_R=np.sum(img[:,:,0])/(img.shape[0]*img.shape[1])
# Subtract calculated Mean_Red from all pixels
img_red_new=img[:,:,0]-mean_R
#eliminate all negative values
img_red_new=(img_red_new>=0)*img_red_new


# Validate Images and values
plt.imshow(img_red_new)
plt.figure()
plt.imshow(img[:,:,0])
print("Red_New:",np.max(img_red_new))
print("Red_old:",np.max(img[:,:,0]))
print("Mean:",mean_R)

# Safe as Image
cv2.imwrite("test.jpg",img_red_new)

Your Error in the end, is because you have to define a value range, in which one your colors are represented. Between 0-1 or 0-255, its your choice but you have to choose one. So just normalize your image by:

max=np.max(image)
image=image/max --> values 0-1

Additionally you can convert it back to unsigned integers (0-255) by:

image=image*255
image=image.astype(np.uint8)
Paul Higazi
  • 197
  • 13
0

By changing

plt.imshow(np.array(pixels_new))

to

plt.imshow(np.array(pixels* 255).astype(np.uint8))

That fixed both issues

Seems to be related to this https://github.com/matplotlib/matplotlib/issues/9391/

Orginally from here

PolarBear10
  • 2,065
  • 7
  • 24
  • 55