1D多峰检测?

5

我目前正在尝试在AS3中实现基本的语音识别。由于需要完全在客户端进行,因此我无法访问强大的服务器端语音识别工具。我的想法是检测单词中的音节,并使用它来确定所说的单词。我知道这将大大限制识别能力,但我只需要识别几个关键词,并且我可以确保它们都有不同数量的音节。

我目前能够生成一个单词的声音级别的一维数组,并且如果我以某种方式绘制它,我可以清楚地看到,在大多数情况下,音节之间存在明显的峰值。然而,我完全不知道如何找到这些峰值。我只需要计数,但我认为这需要先找到它们。起初,我想抓住一些最大值,并将它们与值的平均值进行比较,但我忘记了那个比其他峰值更高的峰值,因此,我的“峰值”都位于一个实际峰值上。

我偶然发现了一些Matlab代码,看起来几乎太简短了,以至于我无法将其转换为我所知道的任何语言。我尝试了AS3和C#。因此,我想知道您是否能够帮助我找到正确的路径或提供任何有关峰值检测的伪代码?

3个回答

4

这段Matlab代码非常简单。我会尝试将其翻译成更像伪代码的形式。

将其翻译成ActionScript/C#应该很容易,如果你遇到困难,可以尝试并在发布后跟进问题,这样你将获得最佳的学习效果。

Param: delta (defines kind of a tolerance and depends on your data, try out different values)
min = Inf (or some very high value)
max = -Inf (or some very low value)
lookformax = 1
for every datapoint d [0..maxdata] in array arr do
  this =  arr[d]
  if this > max
    max = this
    maxpos = d
  endif
  if this < min
    min = this
    minpos = d
  endif

  if lookformax == 1
    if this < max-delta
      there's a maximum at position maxpos
      min = this
      minpos = d
      lookformax = 0
    endif
  else
    if this > min+delta
      there's a minimum at position minpos
      max = this
      maxpos = d
      lookformax = 1
    endif
  endif

1
如果有人想要AS3的最终代码,这里是:
function detectPeaks(values:Array, tolerance:int):void
{


var min:int = int.MIN_VALUE;
var max:int = int.MAX_VALUE;
var lookformax:int = 1;
var maxpos:int = 0;
var minpos:int = 0;

for(var i:int = 0; i < values.length; i++)
{
    var v:int = values[i];
    if (v > max)
    {
        max = v;
        maxpos = i;
    }
    if (v < min)
    {
        min = v;
        minpos = i;
    }

    if (lookformax == 1)
    {
        if (v < max - tolerance)
        {
            canvas.graphics.beginFill(0x00FF00);
            canvas.graphics.drawCircle(maxpos % stage.stageWidth, (1 - (values[maxpos] / 100)) * stage.stageHeight, 5);
            canvas.graphics.endFill();

            min = v;
            minpos = i;
            lookformax = 0;
        }
    }
    else
    {
        if (v > min + tolerance)
        {
            canvas.graphics.beginFill(0xFF0000);
            canvas.graphics.drawCircle(minpos % stage.stageWidth, (1 - (values[minpos] / 100)) * stage.stageHeight, 5);
            canvas.graphics.endFill();

            max = v;
            maxpos = i;
            lookformax = 1;
        }
    }
}

}


1
这个函数并不返回任何东西,但如果它返回的话,它只会返回最高峰的索引 - 而不是所有的峰值? - Matt

1

寻找曲线的峰值和谷底就是要观察线的斜率。在这样的位置上,斜率为0。由于我猜测语音曲线非常不规则,因此必须先进行平滑处理,直到只剩下显著的峰值。

因此,我认为应该将曲线视为一组点。对点进行平均处理以产生简单平滑的曲线。然后比较每个点的差异,并找到彼此相似的点,将这些区域识别为峰值、谷底或高原。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接