2010-12-07 4 views
1

편집 : 실제로 이것은 예기치 않은 동작이 아니지만 여전히 솔루션이 필요합니다. findpeaks compares each element of data to its neighboring values.MATLAB의 Signal Processing Toolbox에서 함수 findpeaks의 예기치 않은 동작

신호 처리 도구 상자에서 findpeaks 기능으로 탐지 한 피크가있는 데이터가 있습니다. 때로는 함수가 피크 값을 제대로 감지하지 못하는 것처럼 보입니다. 동일한 값을 두 번 옆에 두었을 때가 있습니다. 내가 데이터를 플롯 경우

>> [pks loc] = findpeaks(values) 

pks = 

    0.0116 


loc = 

    42 

, 그것은 분명하게 : 지금 findpeaks는 하나 개의 피크가 발견 기능

>> values 

values = 

    -0.0324 
    -0.0371 
    -0.0393 
    -0.0387 
    -0.0331 
    -0.0280 
    -0.0216 
    -0.0134 
    -0.0011 
    0.0098 
    0.0217 
    0.0352 
    0.0467 
    0.0548 
    0.0639 
    0.0740 
    0.0813 
    0.0858     <-- here should be another peak 
    0.0858     <-- 
    0.0812 
    0.0719 
    0.0600 
    0.0473 
    0.0353 
    0.0239 
    0.0151 
    0.0083 
    0.0034 
    -0.0001 
    -0.0025 
    -0.0043 
    -0.0057 
    -0.0048 
    -0.0038 
    -0.0026 
    0.0007 
    0.0043 
    0.0062 
    0.0083 
    0.0106 
    0.0111 
    0.0116 
    0.0102 
    0.0089 
    0.0057 
    0.0025 
    -0.0025 
    -0.0056 

: 이것은 내 문제를 설명하기 위해 샘플을 내 데이터에 매우 rarly 발생하지만 여기 findpeaks는 모두 0.08579 값을 가지고 있기 때문에 위치가 18/19 인 봉우리 중 하나를 놓치게됩니다.

alt text

그 실종 피크를 찾을 수있는 가장 좋은 방법은 무엇입니까?

+1

다음 리소스를 사용해보십시오. http://www.billauer.co.il/peakdet.html, http://terpconnect.umd.edu/~toh/spectrum/PeakFindingandMeasurement.htm – Amro

답변

0

second derivative test을 대신 사용 하시겠습니까? 당신은 이미지 처리 도구 상자가있는 경우

1

, 당신은 그 후에 당신은 즉,

bw = imregionalmax(signal); 
peakLocations = find(bw); %# returns n peaks for an n-tuple of max-values 

stats = regionprops(bw,'Centroid'); 
peakLocations = cat(1,stats.Centroid); %# returns the center of the n-tuple of max-values 
+0

문제는 아닙니다. 단지 하나의 피크를 감지했지만, 나는 높은 피크를 전혀 감지하지 못했습니다. – Lucas

+0

@ 루카스 : 그렇습니다. 공식화되지 않았기 때문에 필터링 솔루션이 문제를 해결할 수 있다고 보장 할 수 없으므로 제거했습니다. 어쨌든,'imregionalmax'는 당신이 원하는 것을 수행합니다. 단, 2 이상의 값이 동일하다면 작동합니다. 노이즈로 인한 로컬 최대 값을 제거하기 위해 먼저 필터링 할 수도 있습니다. – Jonas

+0

imregionalmax가 실제로 작동하는 것 같습니다. 나는 여전히 내 자신의 기능을 사용하고있을 것이다. – Lucas

0

(즉, 당신이 필요하다면) 지역의 중심을 찾기 위해 regionprops를 사용하여, 피크를 찾기 위해 IMREGIONALMAX을 사용할 수 있습니다 나는 나의 목적을 위해 작동하는 findpeaks의 나 자신의 더 간단한 버전을 쓰는 것을 끝내었다.

function [pks,locs] = my_findpeaks(X)  
    M = numel(X); 
    pks = []; 
    locs = []; 
    if (M < 4) 
     datamsgid = generatemsgid('emptyDataSet'); 
     error(datamsgid,'Data set must contain at least 4 samples.'); 
    else 
     for idx=1:M-3 
      if X(idx)< X(idx+1) && X(idx+1)>=X(idx+2) && X(idx+2)> X(idx+3) 
       pks = [pks X(idx)]; 
       locs = [locs idx]; 
      end 

     end 

    end 
end 

편집 : 나는 정확히 두 개의 샘플 점 두 샘플 점 사이였다 우연히 같은 값을 가진 피크를했을 때 문제가 발생 명확합니다. 10,000 건이 넘는 경우에만 2 번 발생합니다.

+0

'X (idx + 1)> X (idx + 1)'이 어떻게 평가되는지를 알 수 없습니다. 어딘가에 오타가 있어야합니다. – Jonas

+0

@Jonas : 네, 네가 옳다는 것을 유감스럽게 생각한다.내 문제에 특정한 부분을 추가했기 때문에 이전 버전을 사용했습니다. 그리고 그것은 실수를 포함했습니다. – Lucas

1

이 어쩌면 일부는 여전히에 쉽게 솔루션을 찾고 오래된 주제이지만, (I했던 것처럼 오늘) :

또한 단지 고원에 모든 값에서 아주 작은 고정 된 값을 빼줄 수있는, 첫 번째 값을 제외하고 이로 인해 고원의 각 첫 번째 값이 항상 각 고원에서 가장 높아지므로 해당 요소가 정점으로 포함됩니다.

그냥 코드의이 부분 같은 것을합니다

peaks = yourdata; 
verysmallvalue = .001; 
plateauvalue = peaks(1); 

for i = 2:size(peaks,1) 
    if peaks(i) == plateauvalue 
     peaks(i) = peaks(i) - verysmallvalue; 
    else 
     plateauvalue = peaks(i); 
    end 
end 

[PKS,LOCS] = findpeaks(peaks); 
plot(yourdata); 
hold on; 
plot(LOCS, yourdata(LOCS), 'Color', 'Red', 'Line', 'None', 'Marker', 'o'); 

희망이 도움이!

관련 문제