Improved Wave Detection Algorithm

I am new to python and programming and working on a peak wave detection algorithm on my spline-interpolated graph. I used the code provided at this link: https://gist.github.com/endolith/250860. I have to get this algorithm to work with any type of waveform, that is, with low as well as high amplitude, baseline not aligned, etc. The goal is to calculate the number of waves on a graph. But my peak detection calculates the "invalid" peaks and gives incorrect answers. By "invalid" peaks, I mean if on the wave peak there are two grooves close to each other, the program detects 2 peaks, i.e. 2 waves, when in reality it is only 1 wave. I tried to change the "delta" parameter defined in the peak detection function specified in the link, but this does not solve the generalization goal I'm working on. Please suggest any improvement to the algorithm or any other approach that I should use with. Any help is appreciated. Thanks in advance.

PS I can’t upload an image of an irregular peak wave portion. Hope my explanation is enough ... The code is as follows

wave = f1(xnew)/(max(f1(xnew))) ##interpolated wave
maxtab1, mintab1 = peakdet(wave,.005) 
maxi = max(maxtab1[:,1])
for i in range(len(maxtab1)):
    if maxtab1[i,1] > (.55 * maxi) : ## Thresholding
        maxtab.append((maxtab1[i,0],maxtab1[i,1]))
arr_maxtab = np.array(maxtab)
dist = 1500 ## Threshold defined for minimum distance between two notches to be considered as two separate waves
mtdiff = diff(arr_maxtabrr[:,0])
final_maxtab = []
new_arr = []
for i in range(len(mtdiff)):
if mtdiff[i] < dist :
            new_arr.append((arr_maxtab[i+1,0],arr_maxtab[i+1,1])) 
for i in range(len(arr_maxtab)):
if  not arr_maxtab[i,0] in new_arr[:,0]:
    final_maxtab.append((arr_maxtab[i,0], arr_maxtab[i,1]))
else:
final_maxtab = maxtab
+4
source share
1 answer

The ability to distinguish labels from true peaks implies that you have a fundamental distance between the vertices. In other words, there is a minimum frequency resolution at which you want to run a peak detection search. If you are approaching a signal that is already drier than half the noise, you will see zigzag gags that appear “peaks” every few samples.

It looks like you want to do the following:

  • Smooth the signal.
  • Find the "real" peaks.

Or rather

  • Run the signal through the low pass filter.
  • /.

1:

1, , scipy.

, , FIR- scipy.

from numpy import cos, sin, pi, absolute, arange, arange
from scipy.signal import kaiserord, lfilter, firwin, freqz, find_peaks_cwt
from pylab import figure, clf, plot, xlabel, ylabel, xlim, ylim, title, grid, axes, show, scatter

#------------------------------------------------
# Create a signal. Using wave for the signal name.
#------------------------------------------------

sample_rate = 100.0
nsamples = 400
t = arange(nsamples) / sample_rate
wave = cos(2*pi*0.5*t) + 0.2*sin(2*pi*2.5*t+0.1) + \
        0.2*sin(2*pi*15.3*t) + 0.1*sin(2*pi*16.7*t + 0.1) + \
            0.1*sin(2*pi*23.45*t+.8)


#------------------------------------------------
# Create a FIR filter and apply it to wave.
#------------------------------------------------

# The Nyquist rate of the signal.
nyq_rate = sample_rate / 2.0

# The desired width of the transition from pass to stop,
# relative to the Nyquist rate.  We'll design the filter
# with a 5 Hz transition width.
width = 5.0/nyq_rate

# The desired attenuation in the stop band, in dB.
ripple_db = 60.0

# Compute the order and Kaiser parameter for the FIR filter.
N, beta = kaiserord(ripple_db, width)

# The cutoff frequency of the filter.
cutoff_hz = 10.0

# Use firwin with a Kaiser window to create a lowpass FIR filter.
taps = firwin(N, cutoff_hz/nyq_rate, window=('kaiser', beta))

# Use lfilter to filter x with the FIR filter.
filtered_x = lfilter(taps, 1.0, wave)

enter image description here

2:

2 , scipy. , . -.

#------------------------------------------------
# Step 2: Find the peaks
#------------------------------------------------

figure(4)
plot(t[N-1:]-delay, filtered_x[N-1:], 'g', linewidth=1)

peakind = find_peaks_cwt(filtered_x, arange(3,20))
scatter([t[i] - delay for i in peakind], [filtered_x[i] for i in peakind], color="red")
for i in peakind:
    print t[i] + delay

xlabel('t')
grid(True)

show()

enter image description here

+3

All Articles