Adaptive subtraction of noise from signal in frequency domain - matlab

I have modeled noise in frequency domain(used matlab fft) and the the original signal also in frequency domain. I would like to adaptively subtract the model noise from the signal. I tried using wiener2, but it seems to work in pixels or i have no idea as it returns the input signal.Please inform which algorithm i used on matlab for adaptive subtraction in frequency domain?
Also a follow up question: the signal and noise is subband from 1 to 20 hz out of total of 250 hz. Although i have corrected for correct bin size. I need to confirm once i apply filter to 1 to 20 hz on the signal using noise model, do i need to replace these bins to the original full bins of the signal?
thanks

Related

Why getting same output from fir filter even after changing the cutoff frequency for acceleration time series data?

I have question about filtering.
Currently I am working on pedestrian step detection using an inertial measuring unit (accelerometer/acceleration data). I need to filter my signal at preprocessing level. Could anyone suggest which one will be the best filtration algorithm to get good accuracy?
For now I used digital lowpass fir filter with order=2, window size=1.2sec,sampling frequecy=200hz but seems not working. I want to use a lower cutoff frequency. I used 0.03hz and 3hz of cutoff frequecny but I am getting the same result for both cutoff frequencies. I need your guidance or help that how can I proceed. Below, I am attaching the images of filtration result as link at 3hz and 0.03hz respectively and also code that I tried.
Could some one suggest me or provide any good filter in matlab and/or how can I work on that?
fir result at 3hz cutoff fir result at 0.03hz cutoff
Fs = 200;
Hd = designfilt('lowpassfir','FilterOrder',2,'CutoffFrequency',0.03, ...
'DesignMethod','window','Window',{#kaiser,1.2},'SampleRate',Fs);
y1 = filter(Hd,norm);
plot(Time,norm,'b', Time, y1,'red')
xlabel('Time (s)')
ylabel('Amplitude')
legend('norm','Filtered Data')
I am adding another answer in reply to your followup questions. A rectangular window (or boxcar window) of width T, when used as moving average filter, is a lowpass filter with transfer function magnitude
|H(f)|=(sin(pifT))/(pifT) (1)
as you can verify by doing the Fourier transform. Therefore H(f)=0.707 when fco=0.44/T, and H(f)=0 when f=1/T. So a lowpass filter with cutoff fco can be implemented with a rectangular window with width on the order of 1/fco (specifically .44/fco). When fco=0.03 Hz, width is on the order of 30 s (specifically 15 s). See plot of transfer function of a 30 s-wide window.
How to find the necessary order:
>> Fs=200; Fc=.03;
>> Hd003=designfilt('lowpassfir','CutoffFrequency',Fc,'SampleRate',Fs);
Hd003 = designfilt('lowpassfir', 'PassbandFrequency', .03, 'StopbandFrequency', .1, 'PassbandRipple', 3, 'StopbandAttenuation', 20, 'SampleRate', 200, 'DesignMethod', 'kaiserwin');
>> disp(length(Hd003.Coefficients));
2400
The command Hd003=designfilt(...) above causes the Filter Design Assistant to launch, because designfilt() does not have enough info. In the FDA, specify Order mode = Minimum, Passband freq=0.03, Stopband freq=0.1, passband ripple=3 dB, stopband atten.=20 db, design method=Kaiser window. I chose those frequencies and dB values because a 2nd order Butterworth does equally well. (See figure.) Then click "OK", and control returns to the Matlab command window, which runs 'designfilt' with the specified parameters. Then check the length of the coefficient vector: it is 2400! I.e. the FIR filter order=2399, and the filter is 12 seconds long. This is not practical, and it is totally un-usable on signals as short as your 1.6 second long example.
This equation for |H(f)| is for continuous time. It is accurate for discrete time also, as long as the sampling rate Fs>=10/T.
You tried to make a 2nd order FIR filter. That order is far to low for your sampling rate (200 Hz) and desired cutoff frequency (3 or 0.03 Hz). The required order in a FIR filter is very different from the order of an IIR filter. An Nth order FIR filter does a moving average of N+1 data points. Hd=designfilt(...) computes the coefficients, or weights, for the moving average. I made the 3 Hz and 0.03 Hz cutoff filters, using your code fragment, and called them Hd300 and Hd003. Then I viewed the coefficients for the two filters:
>> disp(Hd003.Coefficients);
0.2947 0.4107 0.2947
>> disp(Hd300.Coefficients);
0.2945 0.4110 0.2945
As you can see, they are practically identical - which is why the output filtered signals look the same. The coefficients are very similar because order=2 is far, far too low to make an effective FIR filter of 3 or 0.03 Hz cutoff, when the sampling rate is 200 Hz.
The 0.03 cutoff frequency which you tried corresponds to a time constant of about 30 (=1/.03) seconds. It does not make sense to use such a low cutoff on data which is only 1.6 seconds long. Even if you had hundreds of seconds of data, it would not make sense, because you would be smoothing the data with about a 30 second wide window, which would make it very hard to detect each step.
A better approach: a simple 2nd order Butterworth lowpass, cutoff frequency=1 to 10 Hz. See code below and see figure. I used filtfilt() in my code rather than filter(), because filtfilt() handles the startup transient better. Replace filtfilt() with filter() and you will see what I mean.
%pedometerAccelFilter.m WCR 20210117
% Question on stack exchange
% The code provided on stack exchange assumes vector "norm"
% contains 1.6 seconds of acceleration data sampled at 200 Hz.
% I digitized the data from the figure on stack exchange and
% saved it in file pedometerInterpData.txt (2 columns, 329 rows).
%Load the data
data=load('pedometerInterpData.txt');
Time=data(:,1); norm=data(:,2);
%Compute the filter coefficients
Fs=200; %sampling frequency (Hz)
order=2;
Fc1=5; %filter 1 cutoff frequency (Hz)
Wn1=Fc1*2/Fs; %filter 1 normalized cutoff frequency
[b1,a1]=butter(order,Wn1); %filter 1 coefficients
Fc2=2; %filter 2 cutoff frequency (Hz)
Wn2=Fc2*2/Fs; %filter 2 normalized cutoff frequency
[b2,a2]=butter(order,Wn2); %filter 2 coefficients
%Filter the data
y1=filtfilt(b1,a1,norm); %filtfilt() could be replaced with filter()
y2=filtfilt(b2,a2,norm);
%Plot the data
plot(Time,norm,'r.-',Time,y1,'gx-',Time,y2,'bo-');
xlabel('Time (s)'); ylabel('Amplitude');
legend('Raw Data','Filter 1','Filter 2');
Figure created by code above.

How do i get all the numbers of fft bins in a defined frequency band?

I use the matlab software. To my question.
I have a audio signal, on which i am applying a STFT. I take a segment
(46 ms, specifially chosen) out of my signal y(audio signal) and use a FFT on it. Then i go to the next segment, until to end of my audio signal.
My WAV-File is 10.8526 seconds long. If I have a sample frequency of
44100Hz, this means my y is 10.8526*fs = 478599.66 which is
shown in the workspace as 478 6000 x2 double.
The length of my fft is 2048. My signal are differentiated under lower frequency band [0 300], mfb [301 5000] and hfb [5001 22050(fs/2)].
The bands are just an example and not the actual matlab code. Basicall what i want (or what I am trying to do), is to get the values of my bins in the defined frequency band and do a arithmetic mean on it.
I chose 46 ms because, I want it as long as the fft length, or nearly as long as the fft. (It is not exact).Afterwards, I want to try plotting it, but that is not important right now. Any help is appreciated.
Fourier transform of a signal in time domain in a vector of size n will return another vector of size n of same signal but in frequency domain.
Frequency domain will be from 0 (dc offset) to your sampling frequency. But you will only be able to use half of that. Second half would have same values but mirrored.
You can obtain the center frequency of each useful bin with:
f = Fs*(0:(n/2))/n;

Matlab white noise signal with a maximum frequency

I need to generate a white noise signal with Matlab that has a maximum frequency of 5, 10 and 20 Hz. I know one way is to create the signal, then do a fourier transform, adjust the signal frequency and then inverse transform the signal back to the time domain. I can't really figure out how to do that in Matlab. Any help at all would be great
I need to generate a white noise signal with Matlab that has a maximum frequency of 5, 10 and 20 Hz.
That's the same as saying "I need a perfect circle, but it has to have exactly three edges". White noise doesn't have maximum frequencies; it's white because it spans all your bandwidth with the same expected noise energy.
Now, I presume you want to say "I want to have noise that is shaped a bit like signals that center around 5, 10 and 20 Hz". You'd still have to define the spectral shape -- but for the sake of argument, I assume you want to have gaussian shaped frequency response around these frequencies with a bandwidth of 2 Hz, with a sampling frequency of 50 Hz (has to be twice the highest frequency your signal has[in the real signal case], or else you'll get aliasing).
You can simply do that by using matlabs filter design toolbox, and applying the resulting filter to your signal. Usually, you'd just design one filter and shift it in frequency, but that doesn't seem to be your level of expertise yet -- which indicates that experimenting is an extremely good approach to becoming accustomed to DSP. Go wild!

How can filter data to remove noise in matlab?

I have 2 arrays of 800000 input and output data samples of a system. The system in a kind of oven that works among 0 and 10 volts. The sample time is 0.001s.
I have to identify the model of this system, but first of all, given that the data are clearly dirty, I would like to filter the noise.
How can I do it with the System Identification Toolbox of Matlab?
Moreover, how can I estimate the cutoff frequency to remove the noise?
Thank you in advance.
PS: given that this is a bit out of topic, please, post your answer here thank you.
The cutoff frequency is directly given by you sampling time or sampling frequency.
you sampling frequency is 1/(sampling time) and must at least 2 the factor of the highest frequency of interest:
http://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem
f_s = 1/T_s >= 2*f_cutOff
You can then simply to same frequency domain processing in the case you sampling frequency is realy high enough. The easiest way would to have a look at the frequency domain (with function fft() ). And check first where you have high noise components. Then filter out these components (zeroing) and then transform it back into time domain ( with function ifft() ).
Noise is modeled as a white Gaussian distribution in the simplest case. If you estimate the noise energy, you can make a dummy noise by calling
noise = A*randn(1,N);
Here, A is the amplitude and N is the sample count. then just take the fft of this signal and subtract it from the fft of input signal and take the inverse fft (ifft)

How to get coefficients for sine/cosine function from complex FFT in Matlab?

I'm working on a control system that measures the movement of a vibrating robot arm. Because there is some deadtime, I need to look into the future of the somewhat noisy signal.
My idea was to use the frequencies in the sampled signal and produce a fourier function that could be used for extrapolation.
My question: I already have the FFT of the signal vector (containing 60-100 values e.g.) and can see the main frequencies in the amplitude spectrum. Now I want to have a function f(t) which fits to the signal, removes some noise, and can be used to predict the near future of the signal. How do I calculate the coefficients for the sine/cosine functions out of the complex FFT data?
Thank you so much!
AFAIR FFT essentially produces output as a sum of sine functions with different frequencies. The importance of each frequency is the height of each peak. So what you really want to do here is filter out some frequencies (ie. high frequencies for the arm to move gently) and then come back to the time domain.
In matlab this should be like going through the vector of what you got from fft, setting some values to 0 (or doing something more complex to it) and then use ifft to come back to time domain and make the prediction based on what you get.
There's also one thing you should consider while doing this - Nyquist frequency - this means that the highest frequency that you get on your fft is half of the sampling frequency.
If you use an FFT for data that isn't periodic within the FFT aperture length, then you may need to use a window to reduce spurious frequencies due to "spectral leakage". Frequency estimation techniques to better estimate "between bin" frequency content may also be appropriate. The phase of each cosine sinusoid, relative to the edge of the window, is usually atan2(imag[i], real[i]). The frequency depends on the sample rate and bin number versus the length of the FFT.
You might also want to look into using a Kalman filter instead of an FFT.
Added: If your signal isn't exactly integer periodic in the FFT length, then you may want to do an fftshift before the FFT to move the resulting phase measurement reference point to the center of your data vector, instead of a possibly discontinuous circular edge.