Этот пример показывает, как выполнить базовый пиковый анализ. Это поможет вам ответить на такие вопросы, как: Как я могу найти peaks в своем сигнале? Как измерить расстояние между peaks? Как измерить амплитуду peaks сигнала, на который влияет тренд? Как найти peaks в сигнале с шумом? Как найти местные минимумы?
Относительное число солнечных пятен в Цюрихе измеряет как количество, так и размер солнечных пятен. Используйте findpeaks
функция для поиска местоположений и значения peaks.
load sunspot.dat year = sunspot(:,1); relNums = sunspot(:,2); findpeaks(relNums,year) xlabel('Year') ylabel('Sunspot Number') title('Find All Peaks')
На приведенном выше графике показаны номера пятен, сведенные в таблицу за 300 лет, и отмечены обнаруженный peaks. В следующем разделе показано, как измерить расстояние между этими пиками.
Peaks в сигнале появляются, по-видимому, с регулярными интервалами. Однако некоторые из peaks очень близки друг к другу. The MinPeakProminence
свойство может использоваться, чтобы отсеять эти пики. Рассмотрим peaks, которые падают с обеих сторон как минимум на 40 относительных чисел солнечных пятен, прежде чем встретить большее значение.
findpeaks(relNums,year,'MinPeakProminence',40) xlabel('Year') ylabel('Sunspot Number') title('Find Prominent Peaks')
Следующая гистограмма показывает распределение пиковых интервалов в годах:
figure [pks, locs] = findpeaks(relNums,year,'MinPeakProminence',40); peakInterval = diff(locs); histogram(peakInterval) grid on xlabel('Year Intervals') ylabel('Frequency of Occurrence') title('Histogram of Peak Intervals (years)')
AverageDistance_Peaks = mean(diff(locs))
AverageDistance_Peaks = 10.9600
Распределение показывает, что большинство пиковых интервалов лежат между 10 и 12 годами, что указывает на циклическую природу сигнала. Также средний интервал в 10,96 лет между peaks соответствует известной циклической активности пятна 11 лет.
Можно хотеть рассматривать плоские достигать максимума как peaks или исключить их. В последнем случае минимальное отклонение, которое определяется как амплитудное различие между пиком и его ближайшими соседями, задается с помощью threshold
свойство.
load clippedpeaks.mat figure % Show all peaks in the first plot ax(1) = subplot(2,1,1); findpeaks(saturatedData) xlabel('Samples') ylabel('Amplitude') title('Detecting Saturated Peaks') % Specify a minimum excursion in the second plot ax(2) = subplot(2,1,2); findpeaks(saturatedData,'threshold',5) xlabel('Samples') ylabel('Amplitude') title('Filtering Out Saturated Peaks') % link and zoom in to show the changes linkaxes(ax(1:2),'xy') axis(ax,[50 70 0 250])
Первый подграфик показывает, что в случае плоского пика, восходящее ребро обнаруживается как пик. Второй подграфик показывает, что установка порога может помочь отклонить плоский peaks.
Этот пример показывает пиковый анализ в сигнале ЭКГ (электро-кардиограмма). ЭКГ является мерой электрической активности сердца с течением времени. Сигнал измеряется электродами, прикрепленными к коже, и чувствителен к нарушениям порядка, как интерференция источника степени и шум от программных продуктов движения.
load noisyecg.mat t = 1:length(noisyECG_withTrend); figure plot(t,noisyECG_withTrend) title('Signal with a Trend') xlabel('Samples'); ylabel('Voltage(mV)') legend('Noisy ECG Signal') grid on
Вычитание тренда из данных
Вышеописанный сигнал показывает базовый сдвиг и, следовательно, не представляет истинную амплитуду. Чтобы удалить тренд, подбирайте полином низкого порядка к сигналу и используйте полином, чтобы уменьшить его.
[p,s,mu] = polyfit((1:numel(noisyECG_withTrend))',noisyECG_withTrend,6); f_y = polyval(p,(1:numel(noisyECG_withTrend))',[],mu); ECG_data = noisyECG_withTrend - f_y; % Detrend data figure plot(t,ECG_data) grid on ax = axis; axis([ax(1:2) -1.2 1.2]) title('Detrended ECG Signal') xlabel('Samples') ylabel('Voltage(mV)') legend('Detrended ECG Signal')
После удаления тренда, найдите комплекс QRS, который является самым заметным повторяющимся пиком в сигнале ECG. Комплекс QRS соответствует деполяризации правого и левого желудочков человеческого сердца. Его можно использовать, чтобы определить частоту сердечных сокращений пациента или предсказать нарушения в работе сердца. Следующий рисунок показывает форму комплекса QRS в сигнале ECG.
Комплекс QRS состоит из трех основных компонентов: Q-волна, R-волна, S-волна. Волны R могут быть обнаружены с помощью пороговых достигать максимума выше 0,5 мВ. Заметьте, что волны R разделены более чем 200 выборками. Используйте эту информацию для удаления нежелательного peaks путем определения значения 'MinPeakDistance'.
[~,locs_Rwave] = findpeaks(ECG_data,'MinPeakHeight',0.5,... 'MinPeakDistance',200);
Для обнаружения S-волн найдите локальные минимумы в сигнале и примените пороги соответственно.
Нахождение локальных минимумов в сигнале
Локальные минимумы могут быть обнаружены путем нахождения peaks в инвертированной версии исходного сигнала.
ECG_inverted = -ECG_data; [~,locs_Swave] = findpeaks(ECG_inverted,'MinPeakHeight',0.5,... 'MinPeakDistance',200);
Следующий график показывает волны R и волны S, обнаруженные в сигнале.
figure hold on plot(t,ECG_data) plot(locs_Rwave,ECG_data(locs_Rwave),'rv','MarkerFaceColor','r') plot(locs_Swave,ECG_data(locs_Swave),'rs','MarkerFaceColor','b') axis([0 1850 -1.1 1.1]) grid on legend('ECG Signal','R waves','S waves') xlabel('Samples') ylabel('Voltage(mV)') title('R wave and S wave in Noisy ECG Signal')
Затем мы попытаемся определить местоположение Q-волн. Установка порогового peaks для определения местоположения Q-волн приводит к обнаружению нежелательного peaks, когда Q-волны зарыты в шум. Сначала фильтруем сигнал, а затем находим peaks. Фильтрация Савицкого-Голея используется для удаления шума в сигнале.
smoothECG = sgolayfilt(ECG_data,7,21); figure plot(t,ECG_data,'b',t,smoothECG,'r') grid on axis tight xlabel('Samples') ylabel('Voltage(mV)') legend('Noisy ECG Signal','Filtered Signal') title('Filtering Noisy ECG Signal')
Мы выполняем пиковое обнаружение сглаженного сигнала и используем логическое индексирование, чтобы найти местоположения Q-волн.
[~,min_locs] = findpeaks(-smoothECG,'MinPeakDistance',40); % Peaks between -0.2mV and -0.5mV locs_Qwave = min_locs(smoothECG(min_locs)>-0.5 & smoothECG(min_locs)<-0.2); figure hold on plot(t,smoothECG); plot(locs_Qwave,smoothECG(locs_Qwave),'rs','MarkerFaceColor','g') plot(locs_Rwave,smoothECG(locs_Rwave),'rv','MarkerFaceColor','r') plot(locs_Swave,smoothECG(locs_Swave),'rs','MarkerFaceColor','b') grid on title('Thresholding Peaks in Signal') xlabel('Samples') ylabel('Voltage(mV)') ax = axis; axis([0 1850 -1.1 1.1]) legend('Smooth ECG signal','Q wave','R wave','S wave')
Приведенный выше рисунок показывает, что комплекс QRS успешно обнаружен в шумном сигнале ECG.
Ошибка между шумным и сглаженным сигналом
Заметьте среднее различие между комплексом QRS в необработанном и детрендированном фильтрованном сигнале.
% Values of the Extrema
[val_Qwave, val_Rwave, val_Swave] = deal(smoothECG(locs_Qwave), smoothECG(locs_Rwave), smoothECG(locs_Swave));
meanError_Qwave = mean((noisyECG_withTrend(locs_Qwave) - val_Qwave))
meanError_Qwave = 0.2771
meanError_Rwave = mean((noisyECG_withTrend(locs_Rwave) - val_Rwave))
meanError_Rwave = 0.3476
meanError_Swave = mean((noisyECG_withTrend(locs_Swave) - val_Swave))
meanError_Swave = 0.1844
Это демонстрирует, что важно уменьшить сигнал с шумом для эффективного пикового анализа.
Пиковые свойства
Некоторые важные пиковые свойства включают время нарастания, время спада, уровень подъема и уровень падения. Эти свойства вычисляются для каждого из комплексов QRS в сигнале ECG. Средние значения для этих свойств показаны на рисунке ниже.
avg_riseTime = mean(locs_Rwave-locs_Qwave); % Average Rise time avg_fallTime = mean(locs_Swave-locs_Rwave); % Average Fall time avg_riseLevel = mean(val_Rwave-val_Qwave); % Average Rise Level avg_fallLevel = mean(val_Rwave-val_Swave); % Average Fall Level helperPeakAnalysisPlot(t,smoothECG,... locs_Qwave,locs_Rwave,locs_Swave,... val_Qwave,val_Rwave,val_Swave,... avg_riseTime,avg_fallTime,... avg_riseLevel,avg_fallLevel)