0

I am trying to identify the R peak of an ECG. I have used the following line of code to do this:

peaks=signal.find_peaks_cwt(signal_slice, widths=np.arange(1,80))
fig, ax = plt.subplots()
ax.set_title('Detect R peak')
ax.plot(signal_slice)
for peak in peaks:
ax.axvline(x=peak, color='r')

And I get the following output: enter image description here

However, with the following signal it inaccurately detects the smaller peak also.

enter image description here

Is there any extra parameter I could add to the scipy.signal.find_peaks_cwt to make this more accurate? Or any way of using peakutils to do so?

Now it has stopped wrongly detecting the small peaks, but still seems to randomly miss the large peak, does anyone know why? enter image description here

Niam45
  • 552
  • 2
  • 16

1 Answers1

0

You should specify the widths to the expected width of the peak. From the Scipy documentation:

1-D array of widths to use for calculating the CWT matrix. In general, this range should cover the expected width of peaks of interest.

Here is an example to illustrate the effect of width.

from scipy import signal
xs = np.arange(0, 20*np.pi, 0.05)
xs2 = np.arange(0, 20*np.pi, 0.025)
data = np.sin(xs)
data2 = np.sin(xs2)
data= data + data2[:1257]
peakind = signal.find_peaks_cwt(data, np.arange(1,200))
peakind, xs[peakind], data[peakind]
fig, ax = plt.subplots()
ax.set_title('Detect R peak')
ax.plot(data)
for peak in peakind:
    ax.axvline(x=peak, color='r')

This results in only the global peaks. One peak

But if you change the width to np.arange(1,100), you will also see the other local peak.

peakind = signal.find_peaks_cwt(data, np.arange(1,100))

Here the methods detects more peaks due to the difference in width. Two peaks in the same data

KarateKid
  • 3,138
  • 4
  • 20
  • 39
  • Now it is working correctly, but it still randomly misses some peaks, do you know why that might be? – Niam45 Apr 30 '19 at 15:32
  • signal_slice = np.ndarray.flatten(smoothed_signal) / peaks=signal.find_peaks_cwt(signal_slice, / widths=np.arange(1,200)) / fig, ax = plt.subplots() / ax.set_title('Detect R peak') / ax.plot(signal_slice) / for peak in peaks: / ax.axvline(x=peak, color='r') / – Niam45 Apr 30 '19 at 15:37
  • Try something around 180. – KarateKid Apr 30 '19 at 15:41
  • It still gives the same result – Niam45 Apr 30 '19 at 15:42