фильтрация сигнала устранения соседних пиков - PullRequest
0 голосов
/ 07 мая 2018

Я хочу отфильтровать действительно шумный сигнал, чтобы получить количество пиков, которые пересекают определенный порог. Это код Matlab, который я использовал:

thresh = 3;  % Specify threshold
x = VarName1; 
% Essentially need to pick out values which exceed threshold with the condition that the previous value  
% needs to be below the threshold
idxl = x>=thresh;
idxl(1) = 0;
idx = find(idxl);
yest = x(idx-1)<thresh; 
idx(yest)  % Final output

Но полученное мной значение слишком велико, и на самом деле, когда я нахожу на графике пик, он идентифицирует также соседние значения, которые пересекают порог, как вы можете видеть на прилагаемой картинке. Но я хочу посчитать один спайк за каждый раз, когда он переступил порог. У вас есть идеи, как я могу это сделать? image_matlab

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Matlab имеет функцию findpeaks(), которая должна работать в вашем случае. В частности, вы можете установить для параметра MinPeakDistance разумное значение, чтобы обнаруживать только те пики, которые вам нужны.

% Build some noisy signal
signal = peaks;  
signal = repmat(signal(18,:) , 1,3);
noisy_signal = signal + randn(1,3*49).*0.5;

% Find peaks and plot them
findpeaks(noisy_signal , 'MinPeakDistance' , 15);
hold on;
plot(signal)

Вот то, что я получаю, с желтой линией, являющейся исходным сигналом, синим цветом является шумный сигнал, а стрелки указывают на обнаруженные пики (в шумном сигнале, конечно). Вам просто нужно настроить параметр MinPeakDistance.

enter image description here

0 голосов
/ 07 мая 2018

Скажем, у вас есть индексы пиков, а затем для их подсчета вам придется их сегментировать. Это легче всего сделать, взяв разницу между индексами, а затем применив некоторый порог минимального расстояния между каждым пиком.

peaks = unique([randi([100,110],1,randi(10)),randi([150,160],1,randi(10)),randi([210,220],1,randi(10))]); %Create some peaks
thresh = 20; %Set a threshold
nextPeak = diff([-inf,peaks])>thresh; % Find peak seperators

Если вас интересует количество пиков, вы можете просто посчитать количество разделителей, например,

NumPeaks = sum(nextPeak);

Если вас интересует расположение пиков, вам нужно будет решить, как определить «пик», является ли он центральной точкой пика или максимальным значением, например, e.t.c.?

Во всех случаях вам придется пробежаться по количеству пиков

nextPeakIdx = [find(nextPeak),length(peaks)+1];
for i = 1:length(nextPeakIdx)-1
    peakIdx = peaks(nextPeakIdx(i):(nextPeakIdx(i+1)-1));
    %Decide which index to keep
end
...