Reputation: 790
I want to add noise to an image in a way similar to this :
import numpy as np
import matplotlib.pyplot as plt
myImage = plt.imread('Pikachu.png')
noise = np.random.normal(0, 0.1, (myImage.shape[0], myImage.shape[1]))
noisyImage = myImage + noise
However, I would need the noise to be more intense in the center of the image, and less intense as we get farther from the center.
Ideally, I could regulate the spatial distribution parameter of the noise so that my noise
variable contains :
Does anyone know a way to do it? Any help is really appreciated!
Upvotes: 2
Views: 1505
Reputation: 5231
Something you could use as a starting point:
import numpy as np
import matplotlib.pyplot as plt
def gauss2D(shape,sx=1,sy=1):
"""
unnormalized 2D gauss centered on mean value,
given shape and standard dev (sx and sy).
"""
mx = shape[0]/2
my = shape[1]/2
return np.exp( -0.5*(
((np.arange(shape[0])[:,None]-mx)/sx)**2+
((np.arange(shape[0])[None,:]-my)/sy)**2
))#/(2*np.pi*sx*sy)
width,height = 64,64
my_img = np.zeros((width,height,3))+0.9
fig = plt.figure()
ax = fig.gca()
N=5
for i in range(N):
my_img[:,:,:]=0.5 #gray bg image
w = N*100/(4**(2*i))
A = (1-.1*(i+1))
noise =A*np.random.normal(0,w,(width,height))*gauss2D((width,height),10,10)
plt.imshow(my_img+noise[:,:,None]) #noise affects rgb equally
plt.title(i)
plt.show()
with output:
Here the noise was sampled from a gaussian distribution, but a uniform distribution should work fine.
The important part is to weight the noise by a gaussian to get the effect you desire.
You might want to tweak A
(amplitude), and w
(spread) to fit your needs(it could just be two lists). You want high amplitude and spread early, then first decrease spread possibly increasing the amplitude, then decreasing the amplitude to zero.
Upvotes: 2