如何提取和绘制一个数组的最小和最大峰,-graph分析 – 用Matlab或Excel

我正在做video分析。
我得到的最终结果数组是这样的:

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 

注意:我得到的实际数组通常是600+

所以当我绘制这个时,我得到了非常糟糕的graphics,所以我想过滤这个数组,只保留**最大和最小峰值**局部最大值和最小值,这样graphics会有更好的波

有没有办法,我可以用MATLAB来做到这一点?

如果没有,那我可以用Excel来做到吗? 因为我通常将这个数组保存到excel表单中就像这样

 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 

其中第一列是时间(y轴),第二列是振幅。(x轴)

我使用这个公式来计算本地最大值(感谢来自stackoverflow.com的brettdj

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

这个公式来计算当地的最低标准

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

但我需要的是过滤arrays只保留局部最大值和局部最小值,所以我可以得到很好的绘制曲线没有噪音。

如果你想要的最大值和最小值只是使用:

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

但我不能明白你想要什么…因为我的帐户是新的,我不能评论你的问题,试图更好地理解它。

– 编辑1:

好的,现在我明白你想要什么了。 我不知道为什么你有这个重复数字的数组,但是假设你不想要它们,或者至less,最好把它们移除以find局部最大值和最小值,你应该这样做:

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

其中signal_norep将是您的新数组只包含不同于最后一个的值:

左边是你的信号,右边是新信号

现在我们可以在这个数组上search出现局部最大值和最小值的索引,做到:

 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; 

而他们的价值观:

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

那就是它x)

这个VBA

  • 将列A和B中的数据读取到变体数组中
  • find局部最小值和最大值,并将其提取到第二个数组
  • 创build最小/最大值的全新图表(请参见图片)

在这里输入图像说明

  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 

我只是在Matlab中编写一个简单的循环来实现这一点。 我没有看到有什么根本性的问题?

如果你不想在Matlab中循环,你可以用一些数组操作来完成。 如果你有两个等长的数组a和b,你可以像c = a> b这样给你一个1和0的列表。 You1可以使用这个作为select最大值/最小值的一个string。 佐假设你有一个升级和降档arraysb,c。 这样(除了在端点上)b(n-1)= a(n)= c(n + 1)。 您可以通过q=a.*( (a>b).*(a>c) + (a<b).*(a<c) )获得仅包含极值和零点的数组q=a.*( (a>b).*(a>c) + (a<b).*(a<c) )

一个build议:如果你的信号有噪音,比这个select将是嘈杂。 为了使函数平滑,你应该使用你喜欢的内核来进行某种移动平均。