1D多峰检测?

时间:2010-09-24 19:45:19

标签: actionscript-3 math matlab graph speech-recognition

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

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

我偶然发现some Matlab code看起来几乎太短了,不能成为现实,但我不能这么说,因为我无法将它转换成我所知道的任何语言。我试过AS3和C#。所以我想知道你们是否可以在正确的道路上开始我或者有任何用于峰值检测的伪代码?

3 个答案:

答案 0 :(得分: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 :(得分:1)

查找曲线的峰和谷是关于查看线的斜率。在这样的位置,斜率为0.因为我猜测声音曲线是非常不规则的,所以必须先对其进行平滑处理,直到只存在明显的峰值。

因此,我认为曲线应该被视为一组点。应对每组点进行平均以产生简单的平滑曲线。然后应该比较每个点的差异,并且找到彼此不同的点,并将那些区域标识为峰,谷或平台。

答案 2 :(得分: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;
        }
    }
}

}