Найдите пороговое пересечение в данных временных рядов Matlab, затем игнорируйте последующие пересечения в течение 60 секунд, прежде чем найти следующее пороговое пересечение.

Это немного сложно объяснить. У меня есть данные временного ряда в следующем формате: https://docs.google.com/spreadsheets/d/1B8mN0uD-t4kQr2U20gS713ZFHN6IgGB7OMR3-pqJjrw/edit?usp=sharing

Эти данные представляют собой записи напряжения с интервалом 0,01 с. При построении это выглядит так:

http://i.imgur.com/yatlBLt.jpg .

По сути, я хочу найти время, в которое возникает первый пик в каждой очень узкой паре (т. е. ~ 0,1, 0,75, 1,6 и т. д.).

Значения времени находятся в отдельном массиве, но значения индекса (номера строк) соответствуют между двумя наборами.

Есть идеи, как это сделать?

Моя первоначальная попытка была примерно такой из руководства по Matlab

function [edges2] = risingEdge2(time, data)
threshold = 0.4;
offsetData = [data(2:end); NaN];
edges2 = find(data < threshold & offsetData > threshold);
end

Я не мог найти хороший способ игнорировать в течение n секунд после первого пика... Я также получаю намного больше пиков, чем ожидалось... возможно, из-за зашумленных данных.


person user3746901    schedule 07.11.2014    source источник
comment
Есть ли что-то, что вы пробовали, но у вас возникли проблемы?   -  person AnonSubmitter85    schedule 07.11.2014
comment
Вы можете использовать набор инструментов для обработки сигналов?   -  person Benoit_11    schedule 07.11.2014
comment
@ AnonSubmitter85 только что обновил мою попытку   -  person user3746901    schedule 07.11.2014
comment
Что ж, в наборе инструментов sig proc есть команда findpeaks, но я не знаю, будет ли она работать здесь с характером вверх-вниз в верхней части последовательности прямоугольных импульсов. Насколько общим и надежным это должно быть? Если вас устраивает простое пороговое значение, вы можете просто установить пороговое значение и игнорировать области, которые превышают пороговое значение более чем на N секунд. Это своего рода хак, чтобы сделать это таким образом. Если узкие сигналы являются периодическими, можете ли вы выделить их в частотной области? Опять же, последовательность прямоугольных импульсов может затруднить это.   -  person AnonSubmitter85    schedule 07.11.2014
comment
@ AnonSubmitter85, так что данные довольно согласуются в том, что всегда будет 5 из этих узких пиков, которые я хочу захватить, и что они будут одинаковой величины. Это действительно специфическое приложение, поэтому оно просто должно работать с этими данными, которые, опять же, почти полностью идентичны. Единственное, что меняется между подходами, — это интервалы между 5 циклами.   -  person user3746901    schedule 07.11.2014
comment
Так что, если вы просто порог, вы получите вектор единиц и нулей. Найдите длины каждого непрерывного диапазона 1 и отбросьте те, которые слишком длинны. Остаются более узкие импульсы.   -  person AnonSubmitter85    schedule 07.11.2014


Ответы (2)


Следующий подход, кажется, работает для данных данных.

%// Define parameters
window_size = 200;
stepsize = 0.4; %// to be used for quantizing data into three levels - 0, 0.4, 0.8

%// Perform a sliding max to get rid of the dips within the spikes
slmax_data = nlfilter(data,[window_size 1],@max);

введите здесь описание изображения

%// Quantize sliding max data to three levels as the plot seem to suggest
quantized_slmax_data = round((slmax_data-min(slmax_data))./stepsize);

введите здесь описание изображения

Если вы увеличите рисунок выше, вы увидите уступы вокруг высоких пиков —

введите здесь описание изображения

%// Get sliding mode to get rid of the short ledges around the high peaks
slmax_mode_data = nlfilter(quantized_slmax_data,[window_size 1],@mode);

введите здесь описание изображения

%// Finally, find the indices where the mode data jump from 0 to 1 only, which
%// correspond to the start of spikes
index = find(diff(slmax_mode_data)==1)+window_size/2;

Выход -

index =
         682
        8048
       16487
       24164
       31797
person Divakar    schedule 07.11.2014
comment
О, мне нравится это решение. Я не могу заставить его работать. Я не знаком с nlfilter... Я продолжаю получать ошибку Undefined function 'nlfilter' для входных аргументов типа 'function_handle'. РЕДАКТИРОВАТЬ: я думаю, мне нужно установить набор инструментов для обработки изображений. - person user3746901; 08.11.2014
comment
@ user3746901 Да, процесс изображения. Для использования этих кодов потребуется набор инструментов! Дайте мне знать, как это происходит? - person Divakar; 08.11.2014

Здесь — найдите все нарастающие фронты, затем найдите те, которые расположены очень близко друг к другу, и выберите первый.

rising_edges = find(diff(data > .3) > 0);
first_of_paired_edges = find(diff(time(rising_edges)) < 500);

first_rising_edge_times = time(rising_edges(first_of_paired_edges));

Затем вы можете скользить по краю к пику.

first_peak_times = time(arrayfun( @(n) n+find(diff(data(n+[0:1000]) < 0, 1, 'first'), 
                        rising_edges(first_of_paired_edges));
person Ben Voigt    schedule 07.11.2014