2012-01-05 4 views
12

enter image description hereMATLABでダブルピークとシングルピークアレイを区別する方法は?

ダブルピークとシングルピークアレイを区別する方法はありますか?

また、配列がダブルピークを表す場合、2つのピーク間の最小ポイントを見つける方法は?ピークの外側の最小点(左ピークの左および右ピークの右)は、最小点を見出すために考慮されるべきではない。

+0

@Nzbuu::私はそれを2回実行することを好む、それを避けるためにこれは、信号処理に関係しています。すべてが画像ではありません。 – Jonas

答えて

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

+0

ありがとうございます、PEAKDETは良いアプローチです。 1つの欠点 - それは凸極値からの検索を開始する。 – 23W

+0

@yukパラメータdeltaはpeakdetで何をするのですか – kkk

+0

deltaパラメータは、無視したい変動の大きさを基本的に設定します。それを変えて、それが結果にどのように影響するかを見てください。 – yuk

8

ここでは、信号の騒音の程度に応じて動作するアルゴリズムがあります。ここでは、ピークを、所定の閾値より大きい接続点の集合として定義する。

元のデータが配列Aであると仮定します。より大きいトンbwlabel

を使用している接続されたエントリポイントの

P = A>t; 

カウント数:

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

次に、このしきい値を超えるすべての点を見つけるトン:まず、閾値を見つけます

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

今すぐnumberOfPeaksは、データ中にいくつのピーク(接続点がしきい値より大きい)があるかを教えてください

ここで、2つのピークを分離するポイントを特定するために、 L

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

したがって、最初の2つのピークの間の谷はLASTPOINT firsPoint インデックスを持つ点です。最小はその後@Nzbuuがabothは、画像処理ツールボックスの関数bwlabelに依存しているノートのような画像処理ツールボックス

に依存しない

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

解決策になります。だから、これを避けるためにここにいる。最初に、配列Pはピーク(P(i)= 1)に属する点と谷に属する点(P(i)= - 1)を正しく特定していると仮定します。この場合、dP = P(i+1)-P(i) = 1または-1とすると、山と谷の境界が特定できます。あなたは地元を見つけることができます

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

私は、画像処理ツールボックスを使用しないソリューションがより有用になると思います。 – Nzbuu

+0

@ Nzbuu私は同意し、2番目の方法を追加しました。 – Azim

5

の間にある:単にdPに1つの数を合計したピークの数を計算するに

dP = diff(P); 

は、最小/最大は次のようになります。

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

に結果として得られる:yの値の間のデルタはサインを変更ところ基本的にあなたが探している enter image description here

。データにノイズが多い場合は、ローカルの最小値/最大値が大きくなり、データをフィルタリングする必要があります。

あなたはこのような何かを行うことができる2つのピーク間の最小値を見つけるには:

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

一般的に、私はこれに似ていますが、結果に影響を与えるノイズを避けたい場合は、データを使用する前にデータを滑らかにする必要があります。 – Nzbuu

+0

@ Nzbuuだからこそ私はノイズに関する注意点を持っている。ソリューションは、データセットの特性に依存します。騒がしい場合は、最初にフィルタを適用する必要があり、信号/ノイズの特性によってどのような種類のフィルタが必要かが決まります。 –

+1

@Aero Engy、私はそれを逃したと思う:/まだ、ポイントを強調する役目をする。 – Nzbuu