How to generate a pink noise image? - python

I am trying to replicate "Frequency Synthesis of Landscapes" by P. Bourke in Python. I thought it would be a simple
import numpy as np
from scipy.fft import fft2, ifft2
whitenoise = np.random.uniform(0,1,(256,256,3))
fouriertransformed = np.fft.fftshift(fft2(whitenoise))
pinktransformed = np.reciprocal(fouriertransformed)
pinknoise = ifft2(np.fft.ifftshift(pinktransformed)).real
but it seems to be way more complicated. How can I achieve this, and how can I check that the power really falls of by 1/f**2 in the resulting image?

The problem here is that by computing pinktransformed = np.reciprocal(fouriertransformed) you compute the reciprocal of the amplitudes, but what you actually want is scaling these amplitudes by 1/f**2, so you'd have to replace that line with
pinktransformed = fouriertransformed / f**2
where f is an array that contains the frequencies corresponding to each bin of the fourier transform.

Related

How to denoise an image using least square and regularization?

f = u+n: f is noisy image, u is an desired reconstruction and n is noise.
The reconstruction error is ||u-f||_2^2 + lambda * ||gradient(u)||_2^2
Solve ||Ax-b||_2^2 where x is a vector that is vectorised from f in column-wise.
the above is my problem and I can't understand what means "solve ||Ax-b||_2^2".
what is 'A'? what is 'b'? How can get 'the reconstruction'?
I know the simple way of find minimizing least square using pseudo inverse.
But I just adjusted the way on find θ in ||Aθ-b||^2.
I don't know what I have to do. So I did what can I do.
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
from skimage import io, color
from skimage import exposure
file_image = 'image.jpg'
im_color = io.imread(file_image)
im_gray = color.rgb2gray(im_color)
im = (im_gray - np.mean(im_gray)) / np.std(im_gray)
(row, col) = im.shape
noise_std = 0.2 # try with varying noise standard deviation
noise = np.random.normal(0, noise_std, (row, col))
im_noise = im + noise
I made a noisy image. and I don't know next step.
Is there anyone who can explain?
This very much looks like a poorly phrased homework question. I have a fair background in mathematical image processing and inverse problems so I rewrote it for you the only way it makes sense.
Let f be a noisy image described by the relationship f = u+n,
where u is a noise-free image and n is the noise. The goal is to
recover u from n. To do this, we introduce the following function
||u - f||²,
which is equal to the squared summed difference between all pixels in
u and f, to measure the similarity between u and f. Furthermore, we introduce the following function to measure the amount
of noise in the image
||Du||²,
where Du(x, y) represents the magnitude of the gradient of u at
position (x, y), as a measure of the noise in an image. By
||Du||², we therefore mean the squared sum of the gradient in all pixels.
A way to measure how well we have reconstructed the noise-free image can then be represented by the following function
||u - f||² + ||Du||²
Solve the regularised least squares problem above.

`fft` not returning what it should

I am trying to perform Fourier transform using numpy's fft as follows:
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0,1, 128)
x = np.cos(2*np.pi*t)
s_fft = np.fft.fft(x)
s_fft_freq = np.fft.fftshift(np.fft.fftfreq(t.shape[-1], t[1]-t[0]))
plt.plot(s_fft_freq, np.abs(s_fft))
The result I get is
which is wrong, as I know the FT should peak at f = 1, as the frequency of the cos is 1.
What am I doing wrong?
You are only applying fftshift to the x-axis labels, not the actual FFT magnitudes - you just need to apply s_fft = np.fft.fftshift(np.fft.fft(x)) too.
There are 2 or 3 things you have gotten wrong:
The FFT will peak at two positions for a pure real-valued frequency. This is the plus and minus frequencies. The only way to get a single peak in the Fourier domain is by having a complex valued signal (or having the trivial DC component).
(if with f, you mean frequency index) When using the DFT, the number of samples will determine how many frequency components you have. At the highest frequency index, you are always close to the per-sample oscilation: (-1)^t
(if with f, you mean amplitude) There are many definitions of the DFT, affecting both the forward and backward transform. This will affect how the values are interpreted when reading the spectrum.

How to represent a square wave in python and how to convolve it?

I am trying to convolve a square wave with itself more than once and see the resulting graph. I know how to do convolution by my hands but I am not experienced in signal processing with Python. So my questions are:
How can I represent a signal in Python? For example:
x(t) = 1 , 0 ≤ t ≤ 1
x(t) = 0, otherwise
How can I convolve this square wave with itself?
What I have come so far is that I must use numpy's built-in convolve method; but the problem is I am stuck representing this square wave.
One way to create a suitable 0-1 array is np.fromfunction, passing it a function that returns True within the wave. Converting to float results in a 0-1 array.
For this illustration it's better to position the wave in the middle of the array, avoiding boundary effects associated with convolution. Using mode='same' allows for all curves to be plotted together. Also, don't forget to divide the output of convolve by sample_rate, otherwise it will grow proportionally to it with each convolution.
import numpy as np
import matplotlib.pyplot as plt
sample_rate = 100
num_samples = 500
wave = np.fromfunction(lambda i: (2*sample_rate < i) & (i < 3*sample_rate), (num_samples,)).astype(np.float)
wave1 = np.convolve(wave, wave, mode='same')/sample_rate
wave2 = np.convolve(wave1, wave, mode='same')/sample_rate
wave3 = np.convolve(wave2, wave, mode='same')/sample_rate
plt.plot(np.stack((wave, wave1, wave2, wave3), axis=1))
plt.show()
Mathematically, these are known as cardinal B-splines and as the density of Irwin–Hall distribution.

Python - modelling noise in electrical systems

This may open a can of worms or will be very easily answered:
I'm building a model of a system within Python: how do I quantitatively add noise? So far I have this (below code) -
i. Can I do this by broadcasting, even for unique noise added to each sample?
and
ii. Should noise be Gaussian or Uniform for electrical signal modelling?
(Gaussian I think though I'm unsure)
import random
import numpy as np
import matplotlib.pyplot as plt
f = 1e6
T = 1/f
pi = np.pi
t = np.arange(0,20e-6,10e-9)
# create signal and normalise
y = np.sin(2*pi*f*t)
y /= max(y)
# add noise
for i in range(0, len(y)):
noise = random.uniform(-1, 1) / 10 **#10% noise added**
y[i] += noise
plt.figure(1)
plt.plot(t*1e6,y,'r-')
plt.grid()
plt.show()
Judging by the signal you've generated it looks like your going for volts vs time. In which case you're wanting to add Gaussian noise.
You can generate Gaussian noise by exploiting the central limits theorem. Simply generate a bunch of random numbers (the distribution doesn't matter), add them together, store the result. Repeat that len(y) times and the list of results will be randomish but Gaussian distributed. Then just add that list to your y signal. But there's probably a predefined routine to give you Gaussian noise in the first place.
As for doing it in a more pythonic way, I expect numpy has a vector add routine.

FFT filter vs lfilter in python

I have some troubles when applying bandpass filter to signal in Python. Have tried the following to things:
Do the box window "by hand", i.e. do the FFT on the signal, apply the
filter with a box window and the do the IFFT to get back to the time
domain.
Use the scipy.signal module where I use firwin2 to construct the
filter and then lfilter to to the filtering.
Futhermore I have done the same filtering in the audio program Cool Edit and compared the result from the above two tests.
As can be seen (I am a new user so I can not post my png fig), the results from the FFT and scipy.signal are very different. When compare to the result from Cool edit, the FFT is close, however not identical. Code as below:
# imports
from pylab import *
import os
import scipy.signal as signal
# load data
tr=loadtxt('tr6516.txt',skiprows=1)
sr = 500 # [samples/s]
nf = sr/2.0 # Nyquist frequence
W = 512 # Window widht for filtering
N=float(8192) # Fourier settings
Ns = len(tr[:,0]) # Total number of samples
# Create inpulse responce from the filter
fv=12.25
w =0.5
r =0.5*w
Hz=[0, fv-w-r, fv-w, fv+w, fv+w+r, nf]
ff=[0, 0, 1, 1, 0, 0]
b = signal.firwin2(W,Hz,ff,nfreqs=N+1,nyq=nf)
SigFilter = signal.lfilter(b, 1, tr[:,1])
# Fourier transform
X1 = fft(tr[:,1],n=int(N))
X1 = fftshift(X1)
F1 = arange(-N/2.0,N/2.0)/N*sr
# Filter data
ff=[0,1,1,0]
fv=12.25
w =0.5
r =0.5*w
Hz=[fv-w-r,fv-w,fv+w,fv+w+r]
k1=interp(-F1,Hz,ff)+interp(F1,Hz,ff)
X1_f=X1*k1
X1_f=ifftshift(X1_f)
x1_f=ifft(X1_f,n=int(N))
Can anyone explain to me why this difference? The filtering in Cool edit has been done using the same settings as in scipy.signal (hanning window, window width 512). Or have I got this all totaly wrong.
Best regards,
Anders
Above code:
Compared with Cool Edit:
Small differences can be explained by the libraries using different algorithms that accumulate error slightly differently.
For example, if you compute the DFT using a radix-2 FFT, a split-radix FFT and an ordinary DFT, the results will all be slightly different. In fact the ordinary DFT has worse accuracy than all decent implementations of an FFT because it uses many more floating point operations, and thus it accumulates more error.
Could this explain the close (but not identical) results you are seeing?

Categories

Resources