I have a real vector time series x of length T and a filter h of length t << T. h is a filter in fourier space, real and symmetric. It is approximately 1/f.
I would like to filter x with h to get y.
Suppose t == T and FFT's of length T could fit into memory (neither of which are true). To get my filtered x in python, I would do:
import numpy as np
from scipy.signal import fft, ifft
y = np.real( np.ifft( np.fft(x) * h ) ) )
Since the conditions don't hold, I tried the following hack:
Is this a good strategy? How do I select the padding P in a good way? What is the proper way to do this? I don't know much signal processing. This is a good chance to learn.
I am using cuFFT to speed things up so it would be great if the bulk of the operations are FFTs. The actual problem is 3D. Also, I am not concerned about artifacts from an acausal filter.
Thanks, Paul.
Once a two-dimensional Fourier transform has been performed, regions of k -space are attenuated (removed) or phase-shifted. Attenuation in the case of digital processing means zeroing the amplitude function in those regions, and in the case of optical filtering it means blocking the light's path in the transform plane.
A Fourier space filter is just one type (although a fundamentally important type) of transform space filter where the transform is chosen according to the properties of the input data and the desired result of the output. Examples of such transforms are given in Chapter 5.
The Fast Fourier Transform (FFT) is an implementation of the DFT which produces almost the same results as the DFT, but it is incredibly more efficient and much faster which often reduces the computation time significantly. It is just a computational algorithm used for fast and efficient computation of the DFT.
Noise in an image means there are many rapid transitions (over a short distance) in intensity from high to low and back again or vice versa, as faulty pixels are encountered.
You're on the right track. The technique is called overlap-save processing. Is t
short enough that FFTs of that length fit in memory? If so, you can pick your block size B
such that B > 2*min(length(x),length(h))
and makes for a fast transform. Then when you process, you drop the first half of y_b
, rather than dropping from both ends.
To see why you drop the first half, remember that the spectral multiplication is the same as circular convolution in the time domain. Convolving with the zero-padded h
creates weird glitchy transients in the first half of the result, but by the second half all the transients are gone because the circular wrap point in x
is aligned with the zero part of h
. There's a good explanation of this, with pictures, in "Theory and Application of Digital Signal Processing" by Lawrence Rabiner and Bernard Gold.
It's important that your time domain filter taper to 0 at least on one end so that you don't get ringing artifacts. You mention that h
is real in the frequency domain, which implies that it has all 0 phase. Usually, such a signal will be continuous only in a circular fashion, and when used as a filter will create distortion all through the frequency band. One easy way to create a reasonable filter is to design it in the frequency domain with 0 phase, inverse transform, and rotate. For instance:
def OneOverF(N):
import numpy as np
N2 = N/2; #N has to be even!
x = np.hstack((1, np.arange(1, N2+1), np.arange(N2-1, 0, -1)))
hf = 1/(2*np.pi*x/N2)
ht = np.real(np.fft.ifft(hf)) # discard tiny imag part from numerical error
htrot = np.roll(ht, N2)
htwin = htrot * np.hamming(N)
return ht, htrot, htwin
(I'm pretty new to Python, please let me know if there's a better way to code this).
If you compare the frequency responses of ht
, htrot
, and htwin
, you see the following (x-axis is normalized frequency up to pi
):
ht
, at the top, has lots of ripple. This is due to the discontinuity at the edge. htrot
, in the middle, is better, but still has ripple. htwin
is nice and smooth, at the expense of flattening out at a slightly higher frequency. Note that you can extend the length of the straight-line section by using a bigger value for N.
I wrote about the discontinuity issue, and also wrote a Matlab/Octave example in another SO question if you want to see more detail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With