コード例 #1
0
def qrs_detector(ecg_clean, ecg_noisy, ecg_res):
    qrs_inds_clean = processing.xqrs_detect(sig=ecg_clean, fs=360)
    qrs_inds_noisy = processing.xqrs_detect(sig=ecg_noisy, fs=360)
    qrs_inds_res = processing.xqrs_detect(sig=ecg_res, fs=360)

    print(f'QRS Clean: {len(qrs_inds_clean)}')
    print(f'QRS Noisy: {len(qrs_inds_noisy)}')
    print(f'QRS Res: {len(qrs_inds_res)}')
    pass
コード例 #2
0
ファイル: wfdb_xqrs_detector.py プロジェクト: ekrebs5/raccoon
 def detect(self, records):
     return [
         processing.xqrs_detect(
             sig = record.p_signal.T[0],
             fs = record.fs,
             verbose = False)
         for record in records]
コード例 #3
0
def qrs_detect(signals, fields, max_num=48):
    """
       qrs_indexes holds list of integer representing the location of QRS in the signals, the indices of the detected
       qrs complexes
       signals is ECG signal of recorded individuals
    """

    fs = fields["fs"]
    qrs_indexes = []
    all_signals = []
    for signal in signals[:max_num]:
        print("Signals: matrix form", signal)

        # Converting into array
        arr_signal = np.array(signal).ravel()
        print("Signals: array form", arr_signal)

        qrs_index = processing.xqrs_detect(sig=signal[:, 0], fs=fs)

        # Plot the detected complex on graph
        # plt.plot(arr_signal)
        # plt.scatter([qrs_index], [arr_signal[qrs_index]], c="r")
        # plt.show()

        qrs_indexes.append(qrs_index)
        all_signals.append(arr_signal)

        # xqrs = processing.XQRS(sig=signal[:, 0], fs=fs)
        # xqrs.detect()
        # wfdb.plot_items(
        #     signal=signal, ann_samp=[xqrs.qrs_inds], title="Using XQRS", figsize=(10, 4)
        # )
        print(len(all_signals))
    qrs_indexes = np.asarray(qrs_indexes)
    return qrs_indexes, all_signals
コード例 #4
0
def compute_rr_interval(record, channels=0):
    qrs_inds = processing.xqrs_detect(sig=record.p_signal[:, channels],
                                      fs=record.fs)
    rr_intervals = processing.calc_rr(qrs_inds,
                                      fs=record.fs,
                                      rr_units='seconds')
    return rr_intervals
コード例 #5
0
def detect_qrs_xqrs(ecg_data, fs):
    qrs_frames = []
    try:
        qrs_frames = processing.xqrs_detect(sig=ecg_data, fs=fs, verbose=False)
    except Exception:
        print("Exception in detect_qrs_xqrs")
    # return qrs_frames.tolist()
    return qrs_frames
コード例 #6
0
def xqrs_segment_beat(signal, fs, winL=180, winR=180, size_RR_max=5):
    r_poses = processing.xqrs_detect(sig=signal, fs=fs)

    beat = []
    for pos in r_poses:
        if pos > size_RR_max and pos < (len(signal) - size_RR_max):
            beat_poses = segment(signal, pos, winL, winR, size_RR_max)
            if (pos > winL and pos < (len(signal) - winR)):
                beat.append(beat_poses)
    return beat
コード例 #7
0
    def get_qrs_inds(self, signals, fs):
        qrs_inds = processing.correct_peaks(
            signals[:, 0],
            processing.xqrs_detect(signals[:, 0],
                                   fs,
                                   conf=processing.XQRS.Conf(hr_min=20,
                                                             hr_max=230,
                                                             qrs_width=0.5)),
            fs * 60 // 230, fs // 2, 'compare')

        return qrs_inds
コード例 #8
0
 def __compute_R_points(self):
     if self.R_points is None:
         self.R_points = processing.xqrs_detect(self.signal[:,0],self.fs,verbose=False).tolist()
         self.indexes = [i for i in range(len(self.R_points))]
         if self.filteredSignal==None:
             self.filteredSignal = self.__butter_lowpass_filter(10)
         if self.derivativeSignal==None:
             self.__compute_signal_derivative()
         for i in range(len(self.R_points)):
             while abs(self.derivativeSignal[self.R_points[i]]<=eps):
                 self.R_points[i]-=1
コード例 #9
0
def signal_heart_rate(signal):
    lead_mean_rates = []
    for sig in signal:
        r_locs = processing.xqrs_detect(sig=sig,
                                        fs=conf.sample_rate,
                                        verbose=False)
        lead_mean_rate = 60 / (np.nanmean(np.diff(r_locs)) / conf.sample_rate)
        lead_mean_rates.append(lead_mean_rate)
    lead_mean_rates = np.array([x for x in lead_mean_rates if str(x) != 'nan'])
    lead_mean_rates = reject_outliers(lead_mean_rates, m=2.)
    signal_mean_rate = np.mean(lead_mean_rates)
    return signal_mean_rate
コード例 #10
0
def get_beat_bank(start_sec=275, stop_sec=300):
    """
    Make a beat bank of ecgs by extracting all beats from
    the same time section of channels 0 and 1 of all true
    alarm training records
    """
    fs = 250
    beat_bank = dict([(sig_name, []) for c in ecg_channels])
    # No cheating! We should only have access to training data
    records_train, records_test = train_test_split(record_names)

    for record_name in records_train:
        # Skip false alarm records
        if not alarm_data.loc['v131l', 'result']:
            continue
        # Read record
        signal, fields = wfdb.rdsamp(os.path.join(data_dir, record_name),
                                     sampfrom=start_sec * fs,
                                     sampto=stop_sec * fs,
                                     channels=[0, 1])

        # Clean the signals, removing nans
        signal = get_clean_signal(sig=signal, nan_thresh=0.5)
        # Filter the signal
        signal = bandpass(signal, fs=fs, f_low=0.5, f_high=40, order=2)

        # Get beats from each channel
        for ch in range(2):
            sig_ch = signal[:, ch]
            sig_name = fields['sig_name'][ch]
            # Skip flatline signals
            if is_flatline(sig_ch):
                continue
            # Get beat locations
            qrs_inds = processing.xqrs_detect(sig_ch, fs=fs, verbose=False)
            # Skip if too few beats
            if len(qrs_inds) < 2:
                continue
            # Normalize the signal
            sig_ch = normalize(sig_ch)
            # Get the beats
            beats, _ = get_beats(sig_ch, qrs_inds)
            beat_bank[sig_name] = beat_bank[sig_name] + beats
    print('Finished obtaining beat bank')

    # Remove signals without beats from the dictionary
    for sig_name in beat_bank:
        if len(beat_bank[sig_name]) == 0:
            print('Obtained no beats for signal %s. Removing.' % sig_name)
            del (beat_bank[sig_name])
    return beat_bank
コード例 #11
0
def PreProcessing(signal, fs=360, datasetinds=None):

    filteredSig = butter_bandpass_filter(signal, 0.5, 40, 300, 2)
    filteredSig = normalized(filteredSig)

    if datasetinds == None:
        qrs_inds = processing.xqrs_detect(sig=filteredSig[:, 0], fs=fs)

        beats = DynamicSegmentation(qrs_inds, filteredSig)
    else:
        beats = DynamicSegmentation(datasetinds, filteredSig)
    beats = resampling(beats, 300)

    return beats
コード例 #12
0
def get_avg_beat(seg, window=200, fs=300):
    out = []
    left_offset = window//2
    right_offset = window - left_offset
    len_seg = len(seg)
    qrs_inds = processing.xqrs_detect(sig=seg, fs=fs, verbose=False)
    if len(qrs_inds) == 0:
        return np.zeros(window)
    for ind in qrs_inds:
        if ind >= left_offset and ind <= (len_seg-right_offset):
            out.append(seg[(ind-left_offset):(ind+right_offset)])
    out = np.array(out)
    if len(out.shape) == 1:
        avg_beat = out
    else:
        avg_beat = np.mean(out, axis=0)
    return avg_beat
コード例 #13
0
ファイル: stats_utils.py プロジェクト: eladwass/Dynamic-Deep
def calc_ECG_annotation(annotation_GT, reconstructed, fs=360):
    qrs_inds = processing.xqrs_detect(sig=reconstructed, fs=fs, verbose=True)
    # Compare detected qrs complexes to reference annotation.
    # Note, first sample in 100.atr is not a qrs.ֶ
    comparitor = processing.compare_annotations(ref_sample=annotation_GT,
                                                test_sample=qrs_inds,
                                                window_width=int(0.1 * fs),
                                                signal=reconstructed)

    F_mesure = 2 * (comparitor.positive_predictivity *
                    comparitor.sensitivity) / (comparitor.positive_predictivity
                                               + comparitor.sensitivity)
    return [
        len(annotation_GT), comparitor.n_test, comparitor.tp, comparitor.fp,
        comparitor.fn, comparitor.positive_predictivity,
        comparitor.sensitivity, F_mesure
    ]
コード例 #14
0
def xqrs_algorithm(filename,
                   sampfrom=None,
                   sampto=None,
                   channel=0,
                   r_peak_inds=None,
                   fig=None,
                   pic_index=1,
                   pic_size=1,
                   skip_flag=False):
    sig, fields = wfdb.rdsamp(filename,
                              channels=[channel],
                              sampfrom=sampfrom,
                              sampto=sampto)

    qrs_inds = processing.xqrs_detect(sig=sig[:, 0],
                                      fs=fields['fs'])  #numpy.array
    print(qrs_inds)
    #标记位置减去采样点开始位置得到相对位置
    r_peak_inds -= sampfrom
    if len(qrs_inds) < 1:
        qrs_inds = np.array([-100])
    if skip_flag:
        return draw_graph(r_peak_inds,
                          sig,
                          fields,
                          'XQRS',
                          qrs_inds,
                          fig=fig,
                          pic_index=pic_index,
                          pic_size=pic_size,
                          skip_flag=skip_flag)
    summary, fig = draw_graph(r_peak_inds,
                              sig,
                              fields,
                              'XQRS',
                              qrs_inds,
                              fig=fig,
                              pic_index=pic_index,
                              pic_size=pic_size)

    return summary, fig
コード例 #15
0
def detect_qrs(ecg_measurements, fs, win_len_min=10, win_overlap_min=1):

    win_len = int(fs * 60 * win_len_min)
    win_overlap = int(fs * 60 * win_overlap_min)
    indices = set()
    win_skip = win_len - win_overlap
    wins = int((len(ecg_measurements) - win_len) / win_skip) + 2
    min_bpm = 20
    max_bpm = 230
    search_radius = int(fs * 60 / max_bpm)
    start_time_all = time.time()
    for i, w_start in enumerate([x * win_skip for x in range(wins)]):
        w_end = w_start + win_len
        start_time = time.time()
        calc_data = ecg_measurements[w_start:w_end]
        qrs_inds = processing.xqrs_detect(sig=calc_data,
                                          fs=fs,
                                          learn=True,
                                          verbose=False)
        corrected_peak_inds = processing.correct_peaks(
            calc_data,
            peak_inds=qrs_inds,
            search_radius=search_radius,
            smooth_window_size=150)
        start_upd_dict_time = time.time()
        corrected_peak_inds = corrected_peak_inds + w_start
        indices.update(corrected_peak_inds)
        end_time = time.time()
        print(
            "{:5} {:10} - {:10} czas wykonania: {:10.2} całkowity czas wykonania: {:10.2}  liczba probek: {} liczba qrs: {} liczba probek w zbiorze {}"
            .format(i, w_start, w_end, end_time - start_time,
                    end_time - start_time_all, len(calc_data),
                    len(corrected_peak_inds), len(indices)),
            flush=True)
    result = np.array(list(indices))
    np.ndarray.sort(result)
    return result
コード例 #16
0
ファイル: xqrs.py プロジェクト: Jeilef/qrs_compare
import wfdb
from wfdb import processing

DATA_PATH = "/data/"
SAVE_PATH = "/pred/"

with open(DATA_PATH + "RECORDS", 'r') as f:
    records = f.readlines()
    records = list(map(lambda r: r.strip("\n"), records))

for record in records:
    sig, fields = wfdb.rdsamp(DATA_PATH + record, channels=[0])
    res = processing.xqrs_detect(sig[:, 0], fs=fields['fs'])
    if len(res) > 0:
        wfdb.wrann(record,
                   'atr',
                   res,
                   write_dir=SAVE_PATH,
                   symbol=(['N'] * len(res)))
コード例 #17
0
ファイル: test_comit.py プロジェクト: 06fsantos/ECG_Analysis
    
    print(len(predict_beat_dict['Abnormal Beats']))
    print(len(predict_beat_dict['Normal Beats']))
    
    model = load_model('my_model.h5')

    columns = ['Distance to Previous Beat', 'Distance to Next Beat', 'Beat']
    signal_df = pd.DataFrame(columns = columns)
    
    sample_rate = 360
    
    record, fields = wfdb.rdsamp(record_name='uploads/101', sampfrom = 0, channels = [0])
    #annotations = wfdb.rdann(record_name='Data/101', extension = 'atr', sampfrom = 0)
    
    #locate R peaks
    qrs_inds = xqrs_detect(record[:,0], fs=sample_rate)
    print(fields['fs'])
    print('-----------------------------')
    for i, peak in enumerate(qrs_inds):
        if i > 1 and i != len(qrs_inds)-1:
            beat_peak = qrs_inds[i]
            next_peak = qrs_inds[i+1]
            prev_peak = qrs_inds[i-1]
            
            beat_indices.append(beat_peak)
            
            low_diff = beat_peak - prev_peak
            high_diff = next_peak - beat_peak
            
            beat = record[int(beat_peak - 180) : int(beat_peak + 180)]
            
コード例 #18
0
def run_algo(algorithm: str, sig: numpy.ndarray,
             freq_sampling: int) -> List[int]:
    """
    run a qrs detector on a signal

    :param algorithm: name of the qrs detector to use
    :type algorithm: str
    :param sig: values of the sampled signal to study
    :type sig: ndarray
    :param freq_sampling: value of sampling frequency of the signal
    :type freq_sampling: int
    :return: localisations of qrs detections
    :rtype: list(int)
    """
    detectors = Detectors(freq_sampling)
    if algorithm == 'Pan-Tompkins-ecg-detector':
        qrs_detections = detectors.pan_tompkins_detector(sig)
    elif algorithm == 'Hamilton-ecg-detector':
        qrs_detections = detectors.hamilton_detector(sig)
    elif algorithm == 'Christov-ecg-detector':
        qrs_detections = detectors.christov_detector(sig)
    elif algorithm == 'Engelse-Zeelenberg-ecg-detector':
        qrs_detections = detectors.engzee_detector(sig)
    elif algorithm == 'SWT-ecg-detector':
        qrs_detections = detectors.swt_detector(sig)
    elif algorithm == 'Matched-filter-ecg-detector' and freq_sampling == 360:
        qrs_detections = detectors.matched_filter_detector(
            sig, 'templates/template_360hz.csv')
    elif algorithm == 'Matched-filter-ecg-detector' and freq_sampling == 250:
        qrs_detections = detectors.matched_filter_detector(
            sig, 'templates/template_250hz.csv')
    elif algorithm == 'Two-average-ecg-detector':
        qrs_detections = detectors.two_average_detector(sig)
    elif algorithm == 'Hamilton-biosppy':
        qrs_detections = bsp_ecg.ecg(signal=sig,
                                     sampling_rate=freq_sampling,
                                     show=False)[2]
    elif algorithm == 'Christov-biosppy':
        order = int(0.3 * freq_sampling)
        filtered, _, _ = bsp_tools.filter_signal(signal=sig,
                                                 ftype='FIR',
                                                 band='bandpass',
                                                 order=order,
                                                 frequency=[3, 45],
                                                 sampling_rate=freq_sampling)
        rpeaks, = bsp_ecg.christov_segmenter(signal=filtered,
                                             sampling_rate=freq_sampling)
        rpeaks, = bsp_ecg.correct_rpeaks(signal=filtered,
                                         rpeaks=rpeaks,
                                         sampling_rate=freq_sampling,
                                         tol=0.05)
        _, qrs_detections = bsp_ecg.extract_heartbeats(
            signal=filtered,
            rpeaks=rpeaks,
            sampling_rate=freq_sampling,
            before=0.2,
            after=0.4)
    elif algorithm == 'Engelse-Zeelenberg-biosppy':
        order = int(0.3 * freq_sampling)
        filtered, _, _ = bsp_tools.filter_signal(signal=sig,
                                                 ftype='FIR',
                                                 band='bandpass',
                                                 order=order,
                                                 frequency=[3, 45],
                                                 sampling_rate=freq_sampling)
        rpeaks, = bsp_ecg.engzee_segmenter(signal=filtered,
                                           sampling_rate=freq_sampling)
        rpeaks, = bsp_ecg.correct_rpeaks(signal=filtered,
                                         rpeaks=rpeaks,
                                         sampling_rate=freq_sampling,
                                         tol=0.05)
        _, qrs_detections = bsp_ecg.extract_heartbeats(
            signal=filtered,
            rpeaks=rpeaks,
            sampling_rate=freq_sampling,
            before=0.2,
            after=0.4)
    elif algorithm == 'Gamboa-biosppy':
        order = int(0.3 * freq_sampling)
        filtered, _, _ = bsp_tools.filter_signal(signal=sig,
                                                 ftype='FIR',
                                                 band='bandpass',
                                                 order=order,
                                                 frequency=[3, 45],
                                                 sampling_rate=freq_sampling)
        rpeaks, = bsp_ecg.gamboa_segmenter(signal=filtered,
                                           sampling_rate=freq_sampling)
        rpeaks, = bsp_ecg.correct_rpeaks(signal=filtered,
                                         rpeaks=rpeaks,
                                         sampling_rate=freq_sampling,
                                         tol=0.05)
        _, qrs_detections = bsp_ecg.extract_heartbeats(
            signal=filtered,
            rpeaks=rpeaks,
            sampling_rate=freq_sampling,
            before=0.2,
            after=0.4)
    elif algorithm == 'mne-ecg':
        qrs_detections = mne_ecg.qrs_detector(freq_sampling, sig)
    elif algorithm == 'heartpy':
        rol_mean = rolling_mean(sig, windowsize=0.75, sample_rate=100.0)
        qrs_detections = hp_pkdetection.detect_peaks(
            sig, rol_mean, ma_perc=20, sample_rate=100.0)['peaklist']
    elif algorithm == 'gqrs-wfdb':
        qrs_detections = processing.qrs.gqrs_detect(sig=sig, fs=freq_sampling)
    elif algorithm == 'xqrs-wfdb':
        qrs_detections = processing.xqrs_detect(sig=sig, fs=freq_sampling)
    else:
        raise ValueError(
            f'Sorry... unknown algorithm. Please check the list {algorithms_list}'
        )
    cast_qrs_detections = [int(element) for element in qrs_detections]
    return cast_qrs_detections
コード例 #19
0
ファイル: app.py プロジェクト: 06fsantos/ECG_Analysis
def classify_beats(signal_file, model, sampling_rate):
    '''
    method predicts the classes of all beats in an ECG signal 
    
    --------------------
    Input:
        signal --> the input data in the form of an ECG signal from physionet
        
        model --> the trained and saved neural network used for classification 
        
        sampling rate --> the sampling frequency of the ECG signal
    -------------------
    Output:
        predict_beat_dict --> a dictionary containing the locations of each beat classified as normal or abnormal 
    '''

    normal = []
    abnormal = []
    beat_indices = []

    predict_beat_dict = {'Normal Beats': normal, 'Abnormal Beats': abnormal}

    columns = ['Distance to Previous Beat', 'Distance to Next Beat', 'Beat']
    signal_df = pd.DataFrame(columns=columns)

    record, fields = wfdb.rdsamp(record_name=signal_file,
                                 sampfrom=0,
                                 channels=[0])

    #locate R peaks
    qrs_inds = xqrs_detect(record[:, 0], fs=sampling_rate)

    for i, peak in enumerate(qrs_inds):
        if i > 1 and i != len(qrs_inds) - 1:
            beat_peak = qrs_inds[i]
            next_peak = qrs_inds[i + 1]
            prev_peak = qrs_inds[i - 1]

            beat_indices.append(beat_peak)

            low_diff = beat_peak - prev_peak
            high_diff = next_peak - beat_peak

            beat = record[int(beat_peak -
                              (sampling_rate / 2)):int(beat_peak +
                                                       (sampling_rate / 2))]

            denoised_beat = denoise_wave.denoise(beat)
            denoised_beat = denoised_beat.flatten()

            signal_df = signal_df.append(
                {
                    'Distance to Previous Beat': low_diff,
                    'Distance to Next Beat': high_diff,
                    'Beat': denoised_beat
                },
                ignore_index=True)

    for i in range(len(signal_df['Beat'][0])):
        col_name = 'amp{}'.format(i)
        columns.append(col_name)
        signal_df[col_name] = np.nan

    row_count = 0
    for beat in signal_df['Beat']:
        amp_count = 0
        for amp in beat:
            col = 'amp{}'.format(amp_count)
            signal_df[col][row_count] = amp
            amp_count += 1
        row_count += 1

    signal_df = signal_df[signal_df.Beat != '[]']
    signal_df["Distance to Previous Beat"] = pd.to_numeric(
        signal_df["Distance to Previous Beat"])
    signal_df["Distance to Next Beat"] = pd.to_numeric(
        signal_df["Distance to Next Beat"])
    signal_df = signal_df.drop('Beat', axis=1)
    signal_df = signal_df.dropna(axis=0)

    signal_array = signal_df.to_numpy()
    signal_array = np.expand_dims(signal_array, axis=2)

    pred_classes = model.predict_classes(signal_array,
                                         batch_size=24,
                                         verbose=0)

    count = 0
    for pred in pred_classes:
        if pred == 0:
            normal.append(beat_indices[count])
            count += 1
        elif pred == 1:
            abnormal.append(beat_indices[count])
            count += 1
        else:
            print('unidentified class for Beat index {}'.format(i))

    return predict_beat_dict
コード例 #20
0
 def trigger(self, record):
     return processing.xqrs_detect(
         sig = record.p_signal.T[0],
         fs = record.fs,
         verbose = False)
コード例 #21
0
def xqrs_single(fields, record, save_path, sig, save=True):
    r_peaks = processing.xqrs_detect(sig[:, 0], fs=fields['fs'], verbose=False)
    if save:
        save_prediction(r_peaks, record, save_path)
    else:
        return r_peaks