How to extract and draw only the minimum and maximum peaks of an array, graphical analysis. With matlab or excel

I am doing a video analysis.
The resulting array of final results looks something like this:

signal = Columns 1 through 7 73960 73960 73960 73960 68102 68102 68102 Columns 8 through 14 68102 19187 19187 19187 19187 14664 14664 Columns 15 through 21 14664 14664 13715 13715 13715 13715 30832 Columns 22 through 28 30832 30832 30832 53031 53031 53031 53031 Columns 29 through 35 56897 56897 56897 16104 16104 16104 16104 Columns 36 through 42 15188 15188 15188 15188 13973 13973 13973 

Note: the actual array I get is usually 600 +

Therefore, when I draw this, I get a very bad looking graph, so I want to filter this array and keep only the maximum and minimum peaks **, maximum and minimum maximums, so that the graph has more pleasant waves

Is there any way to do this with MATLAB?

If not, can I do this with excel? as i usually save this array in excel sheet like this

 0.1 68102 0.15 19187 0.2 14664 0.25 13715 0.3 30832 0.35 53031 0.4 56897 0.45 16104 0.5 15188 0.55 13973 0.6 21437 0.65 66950 0.7 65356 0.75 22562 0.8 14154 0.85 13938 0.9 20692 0.95 72823 1 69975 1.05 15328 1.1 14494 1.15 13681 1.2 14205 1.25 65278 1.3 63055 1.35 16999 1.4 14050 1.45 14245 

In which the 1st column is the time (y axis) and the second column is the amplitude (x axis)

I use this formula to calculate local maxima (thanks brettdj from stackoverflow.com)

 =SUMPRODUCT(--(B2:B149>B1:B148),--(B2:B149>B3:B150)) 

And this formula for calculating local minima

 =SUMPRODUCT(--(B2:B149<B1:B148),--(B2:B149<B3:B150)) 

But I need to filter the array only for local maxima and local minima so that I can get a nice curve without noise.

+6
source share
3 answers

If you want the maximum and minimum values โ€‹โ€‹to use only:

 [sig_min, idx_min] = min(signal); [sig_max, idx_max] = max(signal); 

But I could not understand exactly what you want ... since my account is new, I can not comment on your question in order to try to understand it better.

- edit 1:

Ok, now I understand what you want. I donโ€™t know why you have this array with duplicate numbers, but if you do not want them, or at least it is better to remove them to find local maximums and minimums, you should do:

 sinal_norep = signal(find(diff(sinal))); 

where signal_norep will be your new array containing only values โ€‹โ€‹that differ from the last:

On the left is your signal, on the right the new one

Now we can search for the index where local maximums and minimums occur on this array, doing:

 minimas_idx = find(signal_norep(2:end-1)<signal_norep(1:end-2) & signal_norep(2:end-1)<signal_norep(3:end))+1; maximas_idx = find(signal_norep(2:end-1)>signal_norep(1:end-2) & signal_norep(2:end-1)>signal_norep(3:end))+1; 

And their meanings:

 signal_maximas = signal_norep(maximas_idx); signal_minimas = signal_norep(minimas_idx); 

This is X)

+1
source

This vba

  • Reads data from columns A and B as arrays of options
  • Find local minima and maxima and extract them into the second array
  • Creates a new minimum / maximum chart (see image).

enter image description here

  Sub NewGraph() Dim X Dim Y Dim lngRow As Long Dim lngCnt As Long Dim Chr As ChartObject X = Range([a1], Cells(Rows.Count, "b").End(xlUp)) Y = Application.Transpose(X) For lngRow = 2 To UBound(X, 1) - 1 If X(lngRow, 2) > X(lngRow - 1, 2) Then If X(lngRow, 2) > X(lngRow + 1, 2) Then lngCnt = lngCnt + 1 Y(1, lngCnt) = X(lngRow, 1) Y(2, lngCnt) = X(lngRow, 2) End If Else If X(lngRow, 2) < X(lngRow + 1, 2) Then lngCnt = lngCnt + 1 Y(1, lngCnt) = X(lngRow, 1) Y(2, lngCnt) = X(lngRow, 2) End If End If Next lngRow ReDim Preserve Y(1 To 2, 1 To lngCnt) Set Chr = ActiveSheet.ChartObjects.Add(250, 175, 275, 200) With Chr.Chart With .SeriesCollection.NewSeries .XValues = Application.Index(Application.Transpose(Y), 0, 1) .Values = Application.Index(Application.Transpose(Y), 0, 2) End With .ChartType = xlXYScatter End With End Sub 
+3
source

I would just write a simple loop over an array in Matlab to achieve this. I do not see any fundamental problems here?

If you don't need loops in Matlab, you can do this with some array operations. If you have two uniformly long arrays a and b, you can do something like c = a> b, which gives you a list with ones and zeros. You1 can use this as an oneliner to select highs / lows. Zo, suppose you have a shifted up and down range b, c. Such that (except for the end points) b (n-1) = A (N) = C (n + 1). You can get an array containing only extrema and zeros q=a.*( (a>b).*(a>c) + (a<b).*(a<c) )

One tip: if your signal has noise, then this choice will be noisy. To smooth out the function, you have to apply some kind of moving averaging with the right kernel.

+1
source

All Articles