Isra
Isra

Reputation: 155

Removing spikes from a signal Matlab

I have the following signal which contains some distorted data

Raw signal

I'm trying to remove those spikes without damaging my signal, I've tried the medfilt1 function but it smoothed out the correct signal as well which is not wanted. Filtering cannot be used because of the frequency overlap between the wanted and unwanted signal. I also tried a moving window which will compare the value with the median of this window and if the point is much higher than it it will set it to the median as shown bellow:

%moving cleaning window
y1_1= y1(1:100);%first window
 x=1;
 %cleaning loop
while  x<= length(y1)
    if(y1(x)> 1.01*(median(y1_1))||y1(x) < 0.95*(median(y1_1)))
        y1(x)= median(y1_1);
    end
    if(x>= length(y1)-100)
        y1_1= y1(length(y1)-100:length(y1));
    else
     y1_1 = y1(x:x+100);
    end
     x=x+1;
end

I've gotten rid of the spikes but also some of the signal's distinct peaks were gone as shown in the figure bellow

Output of actual program

How do I achieve the best denoising in a simple way?

Thanks

Upvotes: 1

Views: 9480

Answers (3)

You could try to use a MUCH smaller window. As both neighboring values of the spike seem to be good representation of the true signal, a window of length 3 could solve your problem. In general, a longer window will distort more your signal.

Also, the computational cost will be greatly reduced with a smaller window.

Upvotes: 0

CKT
CKT

Reputation: 781

If you can upgrade to R2017a, you may want to check out the filloutliers function. There are various methods you can use to detect the spikes, and similarly a variety of choices as to how to fill them.

If you want to basically get a median filter but only on the spikes, then you can specify 'movmedian' as the find method and 'center' as the fill method.

Upvotes: 1

Ozcan
Ozcan

Reputation: 726

You can use median filter or moving average filter. Whatever filter it is, you need to use some kind of threshold. Threshold the spikes and replace them with your filter result.

s=rand(500,1)*5; 
s(ceil(rand(1,20)*500))=rand(1,20)*100; 
maxs=max(s);

figure
subplot(211); plot(s);

thr=10;
med_s=medfilt2(s,[10,1]); 
s(s>med_s+thr)=med_s(s>med_s+thr);
subplot(212); plot(s); ylim([0 maxs])

enter image description here

Upvotes: 1

Related Questions