Git Product home page Git Product logo

Comments (1)

JanCBrammer avatar JanCBrammer commented on September 27, 2024

Hi @skywalkerzhang, thanks for your question. Have a look at https://joss.theoj.org/papers/10.21105/joss.02621. In the paper there's a validation of the R-peak detector that was originally implemented for biopeaks and is now also used as default method for R-peak detection in NeuroKit2. Note that the paper doesn't include details on the internals of the algorithm, only a validation, but maybe it can still be useful as a reference.

You can have a look at the implementation here:

biopeaks/biopeaks/heart.py

Lines 14 to 104 in 9d11af4

def ecg_peaks(signal, sfreq, smoothwindow=.1, avgwindow=.75,
gradthreshweight=1.5, minlenweight=.4, mindelay=.3,
enable_plot=False):
"""Detect R-peaks in an electrocardiogram (ECG).
QRS complexes are detected based on the steepness of the absolute gradient
of the ECG signal. Subsequently, R-peaks are detected as local maxima in
the QRS complexes.
Parameters
----------
signal : ndarray
The ECG signal.
sfreq : int
The sampling frequency of `signal`.
smoothwindow : float, optional
Size of the kernel used for smoothing the absolute gradient of `signal`.
In seconds. Default is .1.
avgwindow : float, optional
Size of the kernel used for computing the local average of the smoothed
absolute gradient of `signal`. In seconds. Default is .75.
gradthreshweight : float, optional
Factor used to offset the averaged absolute gradient of `signal`. The
resulting time series is then used as a threshold for QRS detection.
Default is 1.5.
minlenweight : float, optional
The average QRS duration is multiplied by `minlenweight` in order to
obtain a threshold for the minimal duration of QRS complexes (QRS
complexes shorted than the minimal duration will be discared). Default
is .4.
mindelay : float, optional
Minimal delay between R-peaks. R-peaks that follow other R-peaks by less
than `mindelay` will be discarded. In seconds. Default is .3.
enable_plot : bool, optional
Visualize `signal` along with the detection thresholds, as well as the
detected QRS complexes and R-peaks. Default is False.
Returns
-------
peaks : ndarray
The samples within `signal` that mark the occurrences of R-peaks.
"""
if enable_plot:
plt.figure()
ax1 = plt.subplot(211)
ax2 = plt.subplot(212, sharex=ax1)
filt = butter_highpass_filter(signal, .5, sfreq)
filt = powerline_filter(filt, sfreq)
grad = np.gradient(filt)
absgrad = np.abs(grad)
smoothgrad = moving_average(absgrad, int(np.rint(smoothwindow * sfreq)))
avggrad = moving_average(smoothgrad, int(np.rint(avgwindow * sfreq)))
gradthreshold = gradthreshweight * avggrad
mindelay = int(np.rint(sfreq * mindelay))
if enable_plot:
ax1.plot(filt)
ax2.plot(smoothgrad)
ax2.plot(gradthreshold)
qrs = smoothgrad > gradthreshold
beg_qrs, end_qrs, durations_qrs = find_segments(qrs)
# Identify R-peaks within QRS (ignore QRS that are too short).
min_len = np.mean(durations_qrs) * minlenweight
peaks = [0]
for beg, end, duration in zip(beg_qrs, end_qrs, durations_qrs):
if duration < min_len:
continue
if enable_plot:
ax2.axvspan(beg, end, facecolor="m", alpha=0.5) # visualize QRS
data = signal[beg:end]
locmax, props = find_peaks(data, prominence=(None, None)) # find local maxima and their prominence within QRS
if locmax.size > 0:
peak = beg + locmax[np.argmax(props["prominences"])] # identify most prominent local maximum
if peak - peaks[-1] > mindelay: # enforce minimum delay between R-peaks
peaks.append(peak)
peaks.pop(0)
if enable_plot:
ax1.scatter(peaks, filt[peaks], c="r")
return np.asarray(peaks).astype(int)

Maybe visualizing the R-peak detection by calling the function with enable_plot=True can give you some more insight in how the detection works.

from biopeaks.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.