How can I approximate a certain section of a vector to remove noise?

3 visualizzazioni (ultimi 30 giorni)
I have some plots of S-parameters from a network analyzer, and they have a large amount of noise around 2.4 GHz. I am relatively certain that this noise is due to the Wi-Fi signal in the lab where I am working, so I would like to remove this section of the vector entirely and replace it with an approximation of what the line should look like. These vectors are complex, which complicates the issue because if I use local linear approximation, the real and imaginary components turn out alright, but the magnitude still looks pretty bad. I've tried using some sort of interpolation function (like spline or pchip) but I can't seem to get it to do what I want, which is to entirely remove one section of the vector and replace it with values that fit with the curve before and after. I've attached a few plots to show the issue. The [Raw] plots are straight from the network analyzer, and the [Corrected] plots have simply been "fixed" with local linear approximation on both the real and imaginary components. Thanks!

Risposta accettata

Image Analyst
Image Analyst il 29 Lug 2014
I wouldn't use polyfit - I'd use a Savitzky-Golay filter. It's like polyfit, but does polyfit in a window of limited width as it slides along the entire signal. You can use function sgolayfilt() in the Signal Processing Toolbox. Since a sine wave or cosine wave is pretty well fit from a 4th or 5th order polynomial (as we know from the Taylor series representation of it), you could try 4 or 5 for the order of the Savitzky-Golay filter. Fitting a 5th order polynomial to a small sliding window will be better than fitting the entire signal with polyfit.
  5 Commenti
Image Analyst
Image Analyst il 29 Lug 2014
You can use conv() if you want to do a sliding window to give a mean. Just use linear weights in the kernel. No toolbox is required:
windowWidth = 5; % Some odd number.
outputSignal = conv(inputSignal, ones(1, windowWidth)/windowWidth);
It will "blur" out the signal and smooth the spikes, though it will change the shape of the signal slightly. You can do a modified one where you do a first pass to get a smooth signal then subtract the original signal and threshold to find the outliers. Then get a logical vector of the outliers and replace only those:
originalSignal(outlierLocations) = smoothSignal(outlierLocations);
That will keep the original values in all locations except near the outliers. Also see this: http://www.mathworks.com/matlabcentral/fileexchange/3961-deleteoutliers
Adam Horton
Adam Horton il 30 Lug 2014
Thanks for all your help! I ended up using polyfit in the region, but I'll definitely keep the sgolayfilt() function in mind for later cases, as well as the sliding window with conv(). Thanks again.

Accedi per commentare.

Più risposte (1)

Andrew Reibold
Andrew Reibold il 29 Lug 2014
Modificato: Andrew Reibold il 29 Lug 2014
A easy solution is to either use polyfit or take a moving line average of your data, but you lose some resolution.
Try
data = smooth(yourdata)
Smoothing twice dramatically reduces noise:
data = smooth(smooth(yourdata))
By default, its is a 5 point moving line average.
I wouldn't recommend doing it too many times, especially if you have very few data points. Once or twice should be fine in most situations.
(Taking the moving line average 100 times would results in a flat line)
  1 Commento
Adam Horton
Adam Horton il 30 Lug 2014
I ended up using polyfit only in the region of the 2.4 GHz noise, which worked pretty well. Thanks for your response! smooth() doesn't work very well for this case because I know that the data around 2.4 GHz are pretty much garbage, so I don't want them affecting the "fixed" data too much.

Accedi per commentare.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by