代码之家  ›  专栏  ›  技术社区  ›  Alex Turpin

1d多峰检测?

  •  5
  • Alex Turpin  · 技术社区  · 14 年前

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

    我现在能够为一个口语单词生成一个1d的声级数组,如果我以某种方式绘制它,我可以清楚地看到,在大多数情况下,音节都有明显的峰值。然而,我完全被困在如何找出那些峰的问题上。我真的只需要数数,但我想这是找到它们的结果。起初,我考虑获取一些最大值,并将它们与平均值进行比较,但我忘记了比其他值大的峰值,因此,我所有的“峰值”都位于一个实际峰值上。

    我偶然发现 some Matlab code 这看起来太短了,不可能是真的,但我不能这么做,因为我不能把它转换成我所知道的任何语言。我试过AS3和C。所以我想知道你们能不能让我从正确的路径开始,或者有任何用于峰值检测的伪代码?

    3 回复  |  直到 14 年前
        1
  •  4
  •   schnaader    14 年前

    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
    
        2
  •  1
  •   Andrey    14 年前

    寻找曲线的峰谷,就是要看曲线的坡度。在这样的位置,坡度为0。正如我猜测的,声音曲线是非常不规则的,必须首先平滑,直到只有显著的峰值存在。

    所以我认为曲线应该作为一组点。应平均点组以生成简单的平滑曲线。然后比较各点的差异,发现各点之间没有太大的差异,并将这些区域确定为峰、谷或高原。

        3
  •  1
  •   Alex Turpin    14 年前

    如果有人想要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;
            }
        }
    }
    

    }