Вопрос по matlab – Как различить двойной пик и массив с одним пиком в MATLAB?

12

enter image description here

Как различить двойной пик и массив с одним пиком?

Также, если массив представляет двойной пик, как найти минимальную точку между двумя пиками? Минимальные точки за пределами пиков (слева от левого пика и справа от правого пика) не должны учитываться при поиске минимальной точки.

@Nzbuu: Это связано с обработкой сигналов. Не все сигнал является изображением. Jonas

Ваш Ответ

3   ответа
5

Вы можете найти местный минимум / максимум следующим образом:

x = 0:.1:4*pi;
y = sin(x);

plot(x,y)

diffy = diff(y);
localMin = find(diffy(1:end-1)<=0 & diffy(2:end) > 0)+1;
localMax = find(diffy(1:end-1)>=0 & diffy(2:end) < 0)+1;

hold on
plot(x(localMin),y(localMin),'dg')
plot(x(localMax),y(localMax),'*r')

В результате чего: enter image description here

В основном вы находите, где дельта между значениями y меняет знаки. Если ваши данные зашумлены, это вызовет множество локальных минимальных и максимальных значений, и вам может понадобиться отфильтровать данные.

Чтобы найти минимальное значение между двумя пиками, вы можете сделать что-то вроде этого:

if numel(localMax) == 1
    fprintf('The max value is: %f',y(localMax));
elseif numel(localMax > 1)
    betweenPeaksIndex = localMin(localMin > localMax(1) & localMin <localMax(2));
    fprintf('The min between the first 2 peaks is: %f',y(betweenPeaksIndex));
else
    fprintf('The was no local Max ..???');
end
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
8

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

Предполагая, что ваши исходные данные находятся в массивеA, Сначала найдите порог:

t = (max(A)+min(A))/2;

Далее найдите все точки, превышающие этот порогt:

P = A>t;

Подсчитать количество точек подключения, которые больше, чемt с помощьюbwlabel

L = bwlabel(P);
numberOfPeaks = max(L);

СейчасnumberOfPeaks должен сказать вам, сколько пиков (связанных точек больше, чем пороговое значение) у вас в ваших данных

Теперь, чтобы найти минимальную точку между двумя пиками, нам нужно определить те точки, которые разделяют два пика, используя матрицу меток.L.

firstPoint = find(L==1,1,'last')+1;
lastPoint  = find(L==2,1,'first')-1;

Таким образом, долина между первыми двумя вершинами - это точки с индексом междуfirsPoint а такжеlastPoint, Минимум тогда будет

minValue = min(A(firstPoint:lastPoint));

Solution that does not depend on the Image Processing Toolbox

Как отмечает @Nzbuu, aboth использует функцию набора инструментов для обработки изображений bwlabel. Таким образом, здесь далеко, чтобы избежать этого. Во-первых, я предполагаю, что массив P правильно идентифицирует точки, принадлежащие пику (P(i)=1) и те, которые принадлежат долинам (P(i)=-1). Если это так, то границу между пиками и долинами можно определить, когдаdP = P(i+1)-P(i) = 1 или же-1.

dP = diff(P);

Чтобы вычислить количество пиков, просто сложите число 1 вdP:

numberOfPeaks = sum(dP==1);

И точки, идентифицирующие первую долину, находятся между

firstPoint = find(dP==-1,1,'first')+1 %# the -1 represents the last point of the peak so add 1
lastPoint = find(dP==1,2,'first'); #% Find the start of the second peak
lastPoint = lastPoint(end); #% Keep the last value
Я думаю, что решение, которое не использует набор инструментов для обработки изображений, будет более полезным.
Error: User Rate Limit Exceeded
8

я нашелPEAKDET Функция должна быть достаточно надежной и быстрой, хотя она основана на цикле. Он не требует предварительного сглаживания зашумленных данных, но находит локальные максимальные и минимальные экстремумы с разницей, превышающей параметрdelta.

Поскольку PEAKDET запускается слева направо, иногда пропускаются пики на правом сайте. Чтобы избежать этого, я предпочитаю запускать его дважды:

%# some data
n = 100;
x = linspace(0,3*pi,n);
y = sin(x) + rand(1,n)/5;

%# run peakdet twice left-to-right and right-to-left
delta = 0.5;
[ymaxtab, ymintab] = peakdet(y, delta, x);
[ymaxtab2, ymintab2] = peakdet(y(end:-1:1), delta, x(end:-1:1));
ymaxtab = unique([ymaxtab; ymaxtab2],'rows');
ymintab = unique([ymintab; ymintab2],'rows');

%# plot the curve and show extreme points based on number of peaks
plot(x,y)
hold on
if size(ymaxtab,1) == 2 && size(ymintab,1) == 1 %# if double peak
    plot(ymintab(:,1),ymintab(:,2),'r.','markersize',30)
elseif size(ymaxtab,1) == 1 && size(ymintab,1) == 0 %# if single peak
    plot(ymaxtab(:,1),ymaxtab(:,2),'r.','markersize',30)
else %# if more (or less)
    plot(ymintab(:,1),ymintab(:,2),'r.','markersize',30)
    plot(ymaxtab(:,1),ymaxtab(:,2),'r.','markersize',30)
end
hold off

Two peaks example

В основном, дельта-параметр устанавливает, какую величину колебаний вы хотите игнорировать. Попробуйте изменить это и посмотреть, как это повлияет на результаты.
Спасибо, ПИКДЕТ - это хороший подход. Один недостаток - это начало поисков с выпуклого экстремума.
@yuk что делает параметр delta в peakdet

Похожие вопросы