I have a signal which I'm trying to extract information from (specifically, features to recognize using DTW). Parts of it have very clear and unique features which are unfortunately only sometimes superimposed with a higher frequency low power interference. Below is an example of a square wave feature.
In this picture,
- Black line represents the original signal.
- Blue line is a lowpass Butterworth filter (I have added 3 to the value so that the graph looks more legible).
- Red line is the signal minus the result of a highpass filter (again offset by +5). And the
- green line is a simple box smoothing filter (specifically [1,3,5,7,9,11,9,7,5,3,1]) on the original signal.
The blue line in the second graph is the high pass filter's result.
My questions are: is there any way to disentangle what appears to be a very crisp square wave from a very periodic hum? This hum isn't mains hum, by the way, and it isn't always the same strength or frequency. When it comes on, it'll remain constant all along, but the next time it comes on, it might be a different frequency.
I'm a bit disappointed that I can't get a result that's better than my box filter without severely distorting the resulting signal into something that barely resembles a square signal. Already the low pass filter result (blue graph) is starting to move well past square.
I've gone so far as to thinking of picking the dominant high end frequency, and creating an artificial sine wave to try and "manually remove" the hum. Is this completely misguided? And what hope do I have of getting a clear signal if I won't have the luxury of fine tuning my filters at design time?
I appreciate any general recommendations.
Here's a functional equivalent to my problem in python. Any comments as to why I'm not obtaining a clean output signal? I've played around with the cutoff values but I'm not very familiar with signal processing so I'm not sure if I'm approaching it right.
length = 1200 frequency = .00259 interference = 0.0237 interference_amplitude = 0.2 def iirfilter_filter(data): nyq = 1/2 bottom = interference/nyq top = interference*10/nyq b, a = iirfilter(10, [bottom,top], rs=60, btype="bandstop" , analog=False , ftype="cheby2" ) return lfilter(b,a, data) time_series = np.linspace(1, length, length ) sine_wave = np.sin(2 * np.pi * frequency * time_series ) square_wave = (sine_wave / abs(sine_wave)) sine_wave = sine_wave + (interference_amplitude * np.sin( 2 * np.pi * interference * time_series ) ) - 1 square_wave = square_wave + (interference_amplitude * np.sin( 2 * np.pi * interference * time_series ) ) + 1 noisy_sine_wave = sine_wave + ( numpy.random.rand(length) * interference_amplitude) noisy_square_wave = square_wave + ( numpy.random.rand(length) * interference_amplitude) a = plt.subplot(2,2,1) b = plt.subplot(2,2,2) c = plt.subplot(2,2,3) d = plt.subplot(2,2,4) a.plot( sine_wave ) a.plot( square_wave ) b.plot( iirfilter_filter( sine_wave ) ) b.plot( iirfilter_filter( square_wave ) ) c.plot( noisy_sine_wave ) c.plot( noisy_square_wave ) d.plot( iirfilter_filter( noisy_sine_wave ) ) d.plot( iirfilter_filter( noisy_square_wave ) ) plt.show()