Automate Signal Labeling with Custom Functions
This example shows how to use custom autolabeling functions in Signal Labeler to label QRS complexes and R peaks of electrocardiogram (ECG) signals. One custom function uses a previously trained recurrent deep learning network to identify and locate the QRS complexes. Another custom function uses a simple peak finder to locate the R peaks. In this example, the network labels the QRS complexes of two signals that are completely independent of the network training and testing process.
The QRS complex, which consists of three deflections in the ECG waveform, reflects the depolarization of the right and left ventricles of the heart. The QRS is also the highest-amplitude segment of the human heartbeat. Study of the QRS complex can help assess the overall health of a person's heart and the presence of abnormalities [1]. In particular, by locating R peaks within the QRS complexes and looking at the time intervals between consecutive peaks, a diagnostician can compute the heart-rate variability of a patient and detect cardiac arrhythmia.
The deep learning network in this example was introduced in Waveform Segmentation Using Deep Learning, where it was trained using ECG signals from the publicly available QT Database [2] [3]. The data consists of roughly 15 minutes of ECG recordings from a total of 105 patients, sampled at 250 Hz. To obtain each recording, the examiners placed two electrodes on different locations on a patient's chest, which resulted in a two-channel signal. The database provides signal region labels generated by an automated expert system [1]. The added labels make it possible to use the data to train a deep learning network.
Load, Resample, and Import Data into Signal Labeler
The signals labeled in this example are from the MIT-BIH Arrhythmia Database [4]. Each signal in the database was irregularly sampled at a mean rate of 360 Hz and was annotated by two cardiologists, allowing for verification of the results.
Load two MIT database signals, corresponding to records 200 and 203. Resample the signals to a uniform grid with a sample time of 1/250 second, which corresponds to the nominal sample rate of the QT Database data.
load mit200 y200 = resample(ecgsig,tm,250); load mit203 y203 = resample(ecgsig,tm,250);
Open Signal Labeler. On the Labeler tab, click Import and select From Workspace
in the Members list. In the dialog box, select the signals y200
and y203
. Add time information: Select Time
from the drop-down list and specify a sample rate of 250
Hz. Click Import and Close. The signals appear in the Labeled Signal Set Members browser. Plot the signals by selecting the check boxes next to their names.
Define Labels
Define labels to attach to the signals.
Define a categorical region-of-interest (ROI) label for the QRS complexes. Click Add Definition on the Labeler tab. Specify the Label Name as
QRSregions
, select a Label Type ofROI
, enter the Data Type ascategorical
, and add two Categories,QRS
andn/a
, each on its own line.Define a sublabel of
QRSregions
as a numerical point label for the R peaks. ClickQRSregions
in the Label Definitions browser to select it. Click Add Definition and selectAdd sublabel definition
. Specify the Label Name asRpeaks
, select a LabelType ofPoint
, and enter the Data Type asnumeric
.
Create Custom Autolabeling Functions
Create two Custom Labeling Functions, one to locate and label the QRS complexes and another to locate and label the R peak within each QRS complex. (Code for the findQRS
and findRpeaks
functions appears later in the example.) To create each function, in the Labeler tab, expand the Automate Value gallery and select Add Custom Function. Signal Labeler shows a dialog box asking for the name, description, and label type of the function.
For the function that locates the QRS complexes, enter
findQRS
in the Name field and selectROI
as the Label Type. You can leave the Description field empty or you can enter your own description.For the function that locates the R peaks, enter
findRpeaks
in the Name field and selectPoint
as the Label Type. You can leave the Description field empty or you can enter your own description.
If you already have written the functions, and the functions are in the current folder or in the MATLAB® path, Signal Labeler adds the functions to the gallery. If you have not written the functions, Signal Labeler opens blank templates in the Editor for you to type or paste the code. Save the files. Once you save the files, the functions appear in the gallery.
Label QRS Complexes and R Peaks
Find and label the QRS complexes of the input signals.
In the Labeled Signal Set Members browser, select the check box next to
y200
.Select
QRSregions
in the Label Definitions browser.In the Automate Value gallery, select
findQRS
.Click Auto-Label and select
Auto-Label All Signals
. In the dialog box that appears, enter the250
Hz sample rate in the Arguments field and click OK.
Signal Labeler locates and labels the QRS complexes for all signals, but displays labels only for the signals whose check boxes are selected. The QRS complexes appear as shaded regions in the plot and in the label viewer axes. Activate the panner by clicking Panner on the Display tab and zoom in on a region of the labeled signal.
Find and label the R peaks corresponding to the QRS complexes.
Select
Rpeaks
in the Label Definitions browser.Go back to the Labeler tab. In the Automate Value gallery, select
findRpeaks
.Click Auto-Label and select
Auto-Label All Signals
. Click OK in the dialog box that appears.
The labels and their numeric values appear in the plot and in the label viewer axes.
Export Labeled Signals and Compute Heart-Rate Variability
Export the labeled signals to compare the heart-rate variability for each patient. On the Labeler tab, click Export and select To File
in the Labeled Signal Set list. In the dialog box that appears, give the name HeartRates.mat
to the labeled signal set and add an optional short description. Click Export.
Go back to the MATLAB® Command Window. Load the labeled signal set. For each signal in the set, compute the heart-rate variability as the standard deviation of the time differences between consecutive heartbeats. Plot a histogram of the differences and display the heart-rate variability.
load HeartRates nms = getMemberNames(heartrates); for k = 1:heartrates.NumMembers v = getLabelValues(heartrates,k,["QRSregions" "Rpeaks"]); hr = diff(cellfun(@(x) x.Location,v)); subplot(2,1,k) histogram(hr,0.5:0.025:1.5) legend("hrv = " + std(hr)) ylabel(nms(k)) ylim([0 6]) end
findQRS
Function: Find QRS Complexes
The findQRS
function finds and labels the QRS complexes of the input signals.
The function uses an auxiliary function, computeFSST
, to reshape the input data and compute the Fourier synchrosqueezed transform (FSST). You can either store computeFSST
in a separate file in the same directory or nest it inside findQRS
by inserting it before the final end
statement.
findQRS
uses the classify
(Deep Learning Toolbox) function and the trained deep learning network net
to identify the QRS regions. The deep learning network outputs a categorical array that labels every point of the input signal as belonging to a P region, a QRS complex, a T region, or to none of these. This function converts the point labels corresponding to a QRS complex to QRS region-of-interest labels using signalMask
and discards the rest. The df
parameter selects as regions of interest only those QRS complexes whose duration is greater than 20 samples. If you do not specify a sample rate, the function uses a default value of 250 Hz.
function [labelVals,labelLocs] = findQRS(x,t,parentLabelVal,parentLabelLoc,varargin) % This is a template for creating a custom function for automated labeling % % x is a matrix where each column contains data corresponding to a % channel. If the channels have different lengths, then x is a cell array % of column vectors. % % t is a matrix where each column contains time corresponding to a % channel. If the channels have different lengths, then t is a cell array % of column vectors. % % parentLabelVal is the parent label value associated with the output % sublabel or empty when output is not a sublabel. % parentLabelLoc contains an empty vector when the parent label is an % attribute, a vector of ROI limits when parent label is an ROI or a point % location when parent label is a point. % % labelVals must be a column vector with numeric, logical or string output % values. % labelLocs must be an empty vector when output labels are attributes, a % two column matrix of ROI limits when output labels are ROIs, or a column % vector of point locations when output labels are points. labelVals = cell(2,1); labelLocs = cell(2,1); if nargin<5 Fs = 250; else Fs = varargin{1}; end df = 20; load("trainedQTSegmentationNetwork","net") for kj = 1:size(x,2) sig = x(:,kj); % Reshape input and compute Fourier synchrosqueezed transforms mitFSST = computeFSST(sig,Fs); % Use trained network to predict which points belong to QRS regions netPreds = classify(net,mitFSST,MiniBatchSize=50); % Create a signal mask for QRS regions and specify minimum sequence length QRS = categorical([netPreds{1} netPreds{2}]',"QRS"); msk = signalMask(QRS,MinLength=df,SampleRate=Fs); r = roimask(msk); % Label QRS complexes as regions of interest labelVals{kj} = r.Value; labelLocs{kj} = r.ROILimits; end labelVals = vertcat(labelVals{:}); labelLocs = cell2mat(labelLocs); % Insert computeFSST here if you want to nest it inside findQRS. end
computeFSST
Function: Reshape Input and Compute Fourier Synchrosqueezed Transforms
This function uses the fsst
function to compute the Fourier synchrosqueezed transform (FSST) of the input. As discussed in Waveform Segmentation Using Deep Learning, the network performs best when given as input a time-frequency map of each training or testing signal. The FSST results in a set of features particularly useful for recurrent networks because the transform has the same time resolution as the original input. The function:
Pads the input data with random numbers and reshapes it into the 2-by-5000 cell array stack expected by
net
.Specifies a Kaiser window of length 128 and default shape factor to provide adequate frequency resolution.
Extracts data over the frequency range from 0.5 Hz to 40 Hz.
Treats the real and imaginary parts of the FSST as separate features.
Normalizes the data by subtracting the mean and dividing by the standard deviation.
function signalsFsst = computeFSST(xd,Fs) xd = reshape([xd;randn(10000-length(xd),1)/100],5000,2); signalsFsst = cell(1,2); for k = 1:2 [ss,ff] = fsst(xd(:,k),Fs,kaiser(128)); sp = ss(ff>0.5 & ff<40,:); signalsFsst{k} = normalize([real(sp);imag(sp)],2); end end
findRpeaks
Function: Find R Peaks
This function locates the most prominent peak of the QRS regions of interest found by findQRS
. The function applies the MATLAB® islocalmax
function to the absolute value of the signal in the intervals located by findQRS
.
function [labelVals,labelLocs] = findRpeaks(x,t,parentLabelVal,parentLabelLoc,varargin) labelVals = zeros(size(parentLabelLoc,1),1); labelLocs = zeros(size(parentLabelLoc,1),1); for kj = 1:size(parentLabelLoc,1) tvals = t>=parentLabelLoc(kj,1) & t<=parentLabelLoc(kj,2); ti = t(tvals); xi = x(tvals); lc = islocalmax(abs(xi),MaxNumExtrema=1); labelVals(kj) = xi(lc); labelLocs(kj) = ti(lc); end end
References
[1] Laguna, Pablo, Raimon Jané, and Pere Caminal. "Automatic Detection of Wave Boundaries in Multilead ECG Signals: Validation with the CSE Database." Computers and Biomedical Research. Vol. 27, No. 1, 1994, pp. 45–60.
[2] Goldberger, Ary L., Luis A. N. Amaral, Leon Glass, Jeffery M. Hausdorff, Plamen Ch. Ivanov, Roger G. Mark, Joseph E. Mietus, George B. Moody, Chung-Kang Peng, and H. Eugene Stanley. "PhysioBank, PhysioToolkit, and PhysioNet: Components of a New Research Resource for Complex Physiologic Signals." Circulation. Vol. 101, No. 23, 2000, pp. e215–e220. [Circulation Electronic Pages: http://circ.ahajournals.org/content/101/23/e215.full].
[3] Laguna, Pablo, Roger G. Mark, Ary L. Goldberger, and George B. Moody. "A Database for Evaluation of Algorithms for Measurement of QT and Other Waveform Intervals in the ECG." Computers in Cardiology. Vol. 24, 1997, pp. 673–676.
[4] Moody, George B., and Roger G. Mark. "The impact of the MIT-BIH Arrhythmia Database." IEEE Engineering in Medicine and Biology Magazine. Vol. 20, No. 3, May–June 2001, pp. 45–50.
See Also
Apps
Objects
Related Examples
- Label Signal Attributes, Regions of Interest, and Points
- Label ECG Signals and Track Progress
- Examine Labeled Signal Set
- Label Spoken Words in Audio Signals
More About
- Use Signal Labeler App
- Import Data into Signal Labeler
- Import and Play Audio File Data in Signal Labeler
- Create or Import Signal Label Definitions
- Label Signals Interactively or Automatically
- Custom Labeling Functions
- Customize Labeling View
- Feature Extraction Using Signal Labeler
- Dashboard
- Export Labeled Signal Sets and Signal Label Definitions
- Signal Labeler Usage Tips