4

I'm trying to convert an image from a numpy array format to a PIL one. This is my code:

img = numpy.array(image)
row,col,ch= np.array(img).shape
mean = 0
# var = 0.1
# sigma = var**0.5
gauss = np.random.normal(mean,1,(row,col,ch))
gauss = gauss.reshape(row,col,ch)
noisy = img + gauss
im = Image.fromarray(noisy)

The input to this method is a PIL image. This method should add Gaussian noise to the image and return it as a PIL image once more.

Any help is greatly appreciated!

AGN Gazer
  • 8,025
  • 2
  • 27
  • 45
Stefano Pozzi
  • 529
  • 2
  • 10
  • 26
  • 1
    Is there something wrong with your code? What is the question? – AGN Gazer Jun 12 '18 at 16:55
  • Re-added information now, don't know why it didn't show up once the question was posted – Stefano Pozzi Jun 12 '18 at 16:57
  • PIL is deprecated, use [skimage](http://scikit-image.org/) instead – zar3bski Jun 12 '18 at 16:57
  • No, the PIL-alternative is Pillow (while skimage is great, it has a different target-group). And the author really should read the close-vote and the first comment and react to those. The problem, whatever it is, is probably related to types (e.g. uint8 image; gaussian is obviously continuous/float_double resulting in a change of types). Hint: there are similar questions here! – sascha Jun 12 '18 at 16:59
  • I would suggest you follow the steps outlined in https://stackoverflow.com/a/10967471/8033585 except replace colormap step with "adding noise", e.g., add noise, rescale `(0-255)`, convert to `uint8`, etc. – AGN Gazer Jun 12 '18 at 17:01
  • @AGNGazer Like this you mean: im = Image.fromarray(np.uint8(noisy * 255)) – Stefano Pozzi Jun 12 '18 at 17:10
  • This is "kind of " what I mean, except your rescaling does not guarantee that `noisy*255` has all values in the range `[0, 255]`. It should be divided by maximum value (since a Gaussian is positive we don't need to worry about negative values): `noisy*255/np.amax(noisy)`. Then, of course perform conversion to `uint8`. – AGN Gazer Jun 12 '18 at 17:19
  • Oh, I just noticed that it is a normal distribution => negative values are allowed (for unknown reasons I had Poisson distribution in my head) => you need to compute also min and add it to `noisy` to make it positive. – AGN Gazer Jun 12 '18 at 17:31
  • @AGNGazer is it too much of a hustle asking how? As so? noisy*255/(np.amax(noisy)+ np.amin(noisy)) – Stefano Pozzi Jun 12 '18 at 17:33

1 Answers1

7

In my comments I meant that you do something like this:

import numpy as np
from PIL import Image

img = np.array(image)
mean = 0
# var = 0.1
# sigma = var**0.5
gauss = np.random.normal(mean, 1, img.shape)

# normalize image to range [0,255]
noisy = img + gauss
minv = np.amin(noisy)
maxv = np.amax(noisy)
noisy = (255 * (noisy - minv) / (maxv - minv)).astype(np.uint8)

im = Image.fromarray(noisy)
AGN Gazer
  • 8,025
  • 2
  • 27
  • 45