2010-12-07 13 views
1

編集:これは予期せぬ動作ではありませんが、まだ解決策が必要です。 findpeaks compares each element of data to its neighboring values.MATLABのSignal Processing Toolboxの関数findpeaksの予期しない動作

Signal Processing Toolboxから関数findpeaksで検出されたピークを含むデータがあります。時には、関数がピーク値を正しく検出しないように見えることがあります。これが私のデータでは非常にrarly発生しますが、ここでは私の問題を説明するためのサンプルです:

>> 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 

今findpeaks機能は唯一のピークを検出します。

>> [pks loc] = findpeaks(values) 

pks = 

    0.0116 


loc = 

    42 

私はデータをプロットした場合、それが明らかになりましたfindpeaksは両方とも値0.08579を持っているので、位置18/19のピークの1つを見逃しています。

alt text

それらの行方不明のピークを見つけるための最善の方法は何ですか?

+1

次のリソースを試してください:http://www.billauer.co.il/peakdet.html、http://terpconnect.umd.edu/~toh/spectrum/PeakFindingandMeasurement.htm – Amro

答えて

1

あなたは、画像処理ツールボックスを持っている場合(つまり、何が必要だ場合)、あなたは地域の中心を見つけるために、regionpropsを使用することができた後にピークを見つけるためにIMREGIONALMAXを使用することができ、すなわち

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

問題はそれではありませんでした。ただ1つのピークを検出しましたが、私は高いピークを全く検出しませんでした。 – Lucas

+0

@ルーカス:はい、それほど公式化されておらず、フィルタリングソリューションは問題の修正を保証していないので削除しました。とにかく、 'imregionalmax'はあなたが望むものを行いますが、2つ以上の等しい値があれば動作します。ノイズに起因するローカルな最大値を除去するために、最初にフィルタリングしたいかもしれません。 – Jonas

+0

imregionalmaxが実際に動作するように見えます。私はまだ自分自身の機能を使用しています。 – Lucas

0

私は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 

編集:明確にするために、私は丁度間の2つのサンプルポイントであったと、これら2つのサンプルポイントが偶然同じ値を持っていたピークを持っていたとき、問題は、発生しました。それは10.000件以上の場合に数回発生します。

+0

'X(idx + 1)> X(idx + 1)'がどのように真に評価されるかはわかりません。どこかのタイプミスがあるはずです。 – Jonas

+0

@ジョナス:うん、あなたが正しいと申し訳ありません。私は古いバージョンを使いました。なぜなら、私の問題に特有のものをいくつか追加したからです。それには間違いがありました。 – Lucas

1

これはおそらくいくつかは、まだこれを簡単に解決策を探している古い話題ですが、(私が行ったように、今日):

あなたはまた、単に高原にすべての値からいくつかの非常に小さな固定値をsubstractことができ、最初の値を除きます。これにより、プラトー上の各最初の値は、それぞれのプラトー上で常に最高になり、それらがピークとして含まれるようになります。

ちょうどあなたのコードのこの部分のようなものを作る:

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'); 

は、この情報がお役に立てば幸い!

関連する問題