语音识别-DTW算法

语音识别,声音的特征通过mfcc算出来了以后,我们进行进行跟模板对比,进行判断语音的内容了

先录制“目标词”语音,计算出MFCC保存,然后通过录音录入声音,进行计算MFCC,然后跟目标词进行对比,对比使用DTW算法

DTW参考:https://blog.csdn.net/zouxy09/article/details/9140207

算法实现 C语言,C++比较多


Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks


Class DTW


    Const DTWMAXNUM As Integer = 2000
    Const DTWVERYBIG As Double = 100000000.0
    Private distance As Double(,) = New Double(DTWMAXNUM - 1, DTWMAXNUM - 1) {}
    '保存距离
    Private dtwpath As Double(,) = New Double(DTWMAXNUM - 1, DTWMAXNUM - 1) {}
    '保存路径


    '***************************************************************************


    ' DTWDistance,求两个数组之间的匹配距离
    '        /* A,B分别为第一第二个数组,Alen,Blen为其数组长度,r为匹配窗口的大小
    '
    '        /* r的大小一般取为数组长度的1/10到1/30
    '        /* 返回两个数组之间的匹配距离,如果返回-1.0,表明数组长度太大了
    '        /****************************************************************************


    Public Function DTWDistanceFun(A As Double(), Alen As Integer, B As Double(), Blen As Integer, r As Integer) As Double
        Dim i As Integer, j As Integer
        Dim dist As Double
        Dim istart As Integer, imax As Integer
        Dim r2 As Integer = r + Math.Abs(Alen - Blen)
        '匹配距离
        Dim g1 As Double, g2 As Double, g3 As Double
        Dim pathsig As Integer = 1
        '路径的标志


        '检查参数的有效性


        If Alen > DTWMAXNUM OrElse Blen > DTWMAXNUM Then
            'printf("Too big number\n");
            Return -1.0
        End If


        '进行一些必要的初始化


        For i = 0 To Alen - 1
            For j = 0 To Blen - 1
                dtwpath(i, j) = 0
                distance(i, j) = DTWVERYBIG
            Next
        Next


        '动态规划求最小距离


        '这里我采用的路径是 -------
        '                                      . |
        '                                    .   |
        '                                  .     |
        '                                .       |
        '             


        distance(0, 0) = CDbl(2) * Math.Abs(A(0) - B(0))
        For i = 1 To r2
            distance(i, 0) = distance(i - 1, 0) + Math.Abs(A(i) - B(0))
        Next
        For j = 1 To r2
            distance(0, j) = distance(0, j - 1) + Math.Abs(A(0) - B(j))
        Next


        For j = 1 To Blen - 1
            istart = j - r2
            If j <= r2 Then
                istart = 1
            End If
            imax = j + r2
            If imax >= Alen Then
                imax = Alen - 1
            End If


            For i = istart To imax
                g1 = distance(i - 1, j) + Math.Abs(A(i) - B(j))
                g2 = distance(i - 1, j - 1) + 2 * Math.Abs(A(i) - B(j))
                g3 = distance(i, j - 1) + Math.Abs(A(i) - B(j))
                g2 = Math.Min(g1, g2)
                g3 = Math.Min(g2, g3)
                distance(i, j) = g3
            Next
        Next


        dist = distance(Alen - 1, Blen - 1) / CDbl(Alen + Blen)
        Return dist
    End Function
    'end DTWDistance




    '***************************************************************************


    ' DTWTemplate,进行建立模板的工作
    '        /* 其中A为已经建立好的模板,我们在以后加入训练样本的时候,
    '        /* 以已建立好的模板作为第一个参数,Alen为模板的长度,在这个模板中不再改变
    '        /* B为新加入的训练样本,Blen为B的长度,turn为训练的次数,在第一次
    '        /* 用两个数组建立模板时,r为1,这是出于权值的考虑
    '        /* temp保存匹配最新训练后的模板,建议temp[DTWMAXNUM],函数返回最新训练后模板的长度
    '        /* 如果函数返回-1,表明训练样本之间距离过大,需要重新选择训练样本,
    '        /* tt为样本之间距离的阀值,自行定义
    '        /* rltdistance保存距离,第一次两个数组建立模板时可以随意赋予一个值,
    '        /* 后面用前一次返回的值赋予该参数
    '        /****************************************************************************


    Public Function DTWTemplate(A As Double(), Alen As Integer, B As Double(), Blen As Integer, temp As Double(), turn As Integer,
            tt As Double, rltdistance As Double()) As Integer
        Dim dist As Double
        Dim i As Integer, j As Integer
        Dim pathsig As Integer = 1
        dist = DTWDistanceFun(A, Alen, B, Blen, CInt(Alen / 30))
        If dist > tt Then
            Console.WriteLine(vbLf & "Sample doesn't match!" & vbLf)
            Return -1
        End If




        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        'If turn = 1 Then
        '    rltdistance.Target = dist
        'Else
        '    rltdistance.Target = ((rltdistance.Target) * (turn - 1) + dist) / turn
        'End If




        If turn = 1 Then
            rltdistance(0) = dist
        Else
            rltdistance(0) = ((rltdistance(0)) * (turn - 1) + dist) / turn
        End If


        '----------------------------------------------------------------------------
        '寻找路径,这里我采用了逆向搜索法


        i = Alen - 1
        j = Blen - 1
        While j >= 1 OrElse i >= 1
            Dim m As Double
            If i > 0 AndAlso j > 0 Then
                m = Math.Min(Math.Min(distance(i - 1, j), distance(i - 1, j - 1)), distance(i, j - 1))
                If m = distance(i - 1, j) Then
                    dtwpath(i - 1, j) = pathsig
                    i -= 1
                ElseIf m = distance(i - 1, j - 1) Then
                    dtwpath(i - 1, j - 1) = pathsig
                    i -= 1
                    j -= 1
                Else
                    dtwpath(i, j - 1) = pathsig
                    j -= 1
                End If
            ElseIf i = 0 Then
                dtwpath(0, j - 1) = pathsig
                j -= 1
            Else
                'j==0
                dtwpath(i - 1, 0) = pathsig
                i -= 1
            End If
        End While
        dtwpath(0, 0) = pathsig
        dtwpath(Alen - 1, Blen - 1) = pathsig


        '建立模板


        For i = 0 To Alen - 1
            Dim ftemp As Double = 0.0
            Dim ntemp As Integer = 0
            For j = 0 To Blen - 1
                If dtwpath(i, j) = pathsig Then
                    ftemp += B(j)
                    ntemp += 1
                End If
            Next
            ftemp /= CDbl(ntemp)
            '注意这里的权值
            temp(i) = (A(i) * turn + ftemp) / CDbl(turn + 1)
        Next


        Return Alen
        '返回模板的长度
    End Function
    'end DTWTemplate
  

End Class

你可能感兴趣的:(语音识别)