.--- .... --. ..- .----. ... /.--. . .-. ... --- -. .- .-.. /... .. - .

Generating Gaussian Random Image from a Given PSD

# Generate a Gaussian Random 2D Image that has a certain power spectral density
import numpy as np
from numpy.fft import fft2, fftfreq, ifft2
import matplotlib.pylab as plt
from numpy.random import normal
### The PSD that we use to generate the image
def smooth_step(x, w):
    return (np.pi/2+np.arctan(x/w))/np.pi


def ps_model(f, a, f0, alpha, w, e):
    f=np.abs(f)
    a2=a**2
    y=((e + f**2)/(e + f0**2))**(alpha/2)
    s=smooth_step(f-f0, w)
    return a2*y*s+a2*(1-s)
### Image size
nt=32
nf=32
### Frequency value of each pixel
ft=fftfreq(nt)
ff=fftfreq(nf)
### set some parameter of the PSD
fmin_t=ft[1]
a1=3
f01=fmin_t*1
alpha1=-1
fmin_f=ff[1]
a2=1
f02=fmin_f*1
alpha2=-1
### Generate the 2D PSD
ps1=ps_model(ft, a1, f01, alpha1, 1e-9, 1e-9)
ps2=ps_model(ff, a2, f02, alpha2, 1e-9, 1e-9)
#plt.plot(f, ps1)
ps=np.atleast_2d(ps1).T.dot(np.atleast_2d(ps2))
plt.imshow(ps)
<matplotlib.image.AxesImage at 0x7f79621cfcc0>
### Generate the random image
noise_image=ifft2(fft2(normal(size=ps.shape))*ps)
### Check the result, note that the image part is not exactly zero, because the numerical accuracy
plt.figure(figsize=(15,6))
plt.subplot(121)
plt.imshow(noise_image.real, aspect='auto')
plt.colorbar()
plt.subplot(122)
plt.imshow(noise_image.imag, aspect='auto')
plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x7f7961d44160>