На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: RaD, nsh
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Распознавание отдельных слов , wav,mfcc,dtw
    Цитата
    Поднимите взгляд к шапке сайта, там есть ссылка "Алгоритмы"


    Спасибо за совет, этот вариант я попробовал в первую очередь, из этой библиотеки я использовал БПФ, но вскоре нашел библиотеку в которой было все в одном. Но к сожалению, товарищ nsh обнаружил в этой библиотеке недоработки.

    Цитата
    уважаемый автор и форумчане ) у кого есть наработки? или готовое решение. ищу именно такое по чтоб натренировать и понимало меня.


    К сожалению, я пока не добился нужного результата. Думаю для вашей задачи будет достаточно готового продукта CMU Sphinx.
      nsh Пожалуйста помогите мне никак не могу получить MFCC коэфиценты. Хочу написать программу распознование речи на c++, но мне нужен сначала получить MFcc коэфиценты а потом пуду использовать нейронные сети.Очень важно для меня.
        Конечно. Покажите свой код, опишите, что не работает. Разберемся. Какая-нибудь реализация у вас есть? Под какую платформу Вы программируете, под какую ОС.
          Цитата nsh @
          Конечно. Покажите свой код, опишите, что не работает. Разберемся. Какая-нибудь реализация у вас есть? Под какую платформу Вы программируете, под какую ОС.

          У меня есть код, в этом разделе у кого-то тоже был такой же вопрос вы помогли ему, я смотрел код который он написал но у меня есть вопросы.
          Я не понимаю почему wav фаил разбиваем по окном и почему для 16кГц выбираем int Window = 500, для чего надо разбивать а не взять весь wav фаил. И второй вопрос не могу понять с каким алгоритмом напсан функция MatrixFromFile, почему NoPairCount Начинается с Window/2? Буду очень блогодарень если поможете.

          Это более хороший код.

          ExpandedWrap disabled
            #include "aquila/global.h"
            #include "aquila/source/WaveFile.h"
            #include "aquila/source/SignalSource.h"
            #include "aquila/transform/Mfcc.h"
            #include "aquila/ml/Dtw.h"
            #include "aquila/ml/DtwPoint.h"
            #include "aquila/transform/FftFactory.h"
             
            #include <iostream>
            #include <vector>
            #include <math.h>
             
            #ifdef NAN
            /* NAN is supported */
            #endif
            #ifdef INFINITY
            /* INFINITY is supported */
            #endif
            using namespace std;
             
            /* Rounding  number of samples */
            unsigned int RoundSize (Aquila::WaveFile& wav, int& Sample)
            {
                int SIZE = 0;
                if (wav.getSamplesCount()%Sample == 0)
                {
                    SIZE = wav.getSamplesCount();
                }
                else
                {
                    SIZE = wav.getSamplesCount()-(wav.getSamplesCount()%Sample);
                }
                return SIZE;
            }
             
            /* Transform wavfile to frame matrix with double overlap */
            vector< vector<double> > MatrixFromFile (Aquila::WaveFile& wav, int Row, int Col,int Window)
             {
                vector< vector<double> > WindowMatrix(Row);
                int PairCount = 0;
                for(int i = 0; i < Row; i=i+2)
                {
                    WindowMatrix[i].resize(Col);
                    for(int j = 0; j < Col; ++j)
                    {
                        WindowMatrix[i][j] = wav.sample(PairCount++);
                    }
                }
                int NoPairCount = Window/2;
                for(int i = 1; i < Row; i=i+2)
                {
                    WindowMatrix[i].resize(Col);
                    for(int j = 0; j < Col; j++)
                    {
                        cout << NoPairCount << endl;
                        WindowMatrix[i][j] = wav.sample(NoPairCount);
                        NoPairCount ++;
                    }
                }
                return WindowMatrix;
             }
             
             /* Calculation of Mel Frequency Cepstral Coefficients for FrameMatrix with subtracting the average */
            vector< vector<double> > CalcMFCCforMatrix (vector< vector<double> >& WindowMatrix, int FFTSize, int Row)
            {
                vector< vector<double> > result (Row);
                for(int i = 0; i < Row; ++i)
                {
                   result[i].resize(FFTSize);
                   Aquila::SignalSource WavFromArr(WindowMatrix.at(i),16000);
                   Aquila::Mfcc fftMFCC (FFTSize);
                   result.at(i) = fftMFCC.calculate(WavFromArr);
                }
             
                /* Searching the average */
                 vector<double> AverangeMFCC;
                 for(int i = 0; i < 12; ++i)
                 {
                     double TempSum = 0.0;
                     for(int j = 0; j < Row; ++j)
                     {
                         TempSum+= result[j][i];
                     }
                     AverangeMFCC.push_back(TempSum/Row);
                 }
             
                 /* Subtracting the average */
                 for(int i = 0; i < 12; ++i)
                 {
                     for(int j = 0; j < Row; ++j)
                     {
                         result[j][i] = (result[j][i]) - AverangeMFCC.at(i);
                     }
                 }
                 return result;
            }
             
            int main()
            {
             
                Aquila::WaveFile wav("one.wav");
             
                /* firs file */
                int Window = 500; /*16kHz = 62.5uS per sample*/
             
                unsigned int Wav1Size = RoundSize (wav,Window);
                /* Matrix vector< vector<double> > size:
                 * Row - number of windows (one sample = 62.5uS, one WindowSize = sample*window, double overlap)
                 * Column - Window*/
                const int RowWav1 = 2*(Wav1Size/Window);
                const int ColWav1 = Window;
             
                /*Wav file to FrameMatrix*/
                vector< vector<double> > WindowMatrixWav1 = MatrixFromFile (wav,RowWav1,ColWav1,Window);
             
               /* Calculation of Mel Frequency Cepstral Coefficients */
                unsigned int FFTSize = 512;
                vector< vector<double> > Wav1MatrixMFCC = CalcMFCCforMatrix (WindowMatrixWav1,FFTSize,RowWav1);
             
             
                for(int i = 0; i < Wav1MatrixMFCC.size(); ++i){
                    for(int j = 0; j < Wav1MatrixMFCC.at(i).size(); ++j){
                        cout << Wav1MatrixMFCC.at(i).at(j) << " ";
                    }
                    cout << endl;
                }
             
             
              
                return 0;
             
            }
          Сообщение отредактировано: nsh -
            nsh Вы будете помочь мне? :(
              Цитата
              Я не понимаю почему wav фаил разбиваем по окном и почему для 16кГц выбираем int Window = 500, для чего надо разбивать а не взять весь wav фаил.


              Частотный состав звуков речи очень быстро изменяется. Преобразование Фурье подразумевает сигнал с постоянным частотным составом. Для того, чтобы проанализировать состав звуков по частотам с помощью преобразования Фурье, нужно разбить речь на интервалы, где частотный состав почти постоянен и заняться анализом каждого интервала в отдельности.

              Цитата
              И второй вопрос не могу понять с каким алгоритмом напсан функция MatrixFromFile, почему NoPairCount Начинается с Window/2? Буду очень блогодарень если поможете.


              Чтобы обеспечить плавность анализа, окна берутся с перекрытием. Второе окно начинается от середины первого. Третье окно начинается от конца первого и от середины второго. NoPairCount это на самом деле индекс в звуковых данных, откуда данные копируются в окно. Во последовательности перекрывающихся окон четные окна начинаются со сдвигом в половину окна. Попробуйте нарисовать картинку, станет более понятно.
                nsh Спасибо. А вы можете мне сказать какую книгу прочитать чтобы понимать как все это делается. Я совсем не предстовляю как энкодируется и декодируется wav фаил, в чем разница между stereo и моно, 8 бит и 16 бит, right channel left channel, что вообще channel? И в моем коде не понимаю что из себя представляет sample, и от чего зависит калияество sample-ов.
                  Это достаточно простые вещи, я не думаю, что стоит искать книгу. Достаточно просто посмотреть на файлы. Например запись может содержать несколько потоков звука одновременно, это и есть каналы. Правый канал - это то, что слышит правое ухо, левый канал - левое. Значения сигналов для каждого из каналов сохраняется в файле по очереди. Сначала значение первого канала, затем второго. Размерность значения и есть битность.
                    nsh У меня еще один вопрос. Кажется все понял, но не могу понять для чего нужен FFt size, с чем он связан и почему для 16KHz нужно взяать его размер 512.
                      David1993, я тем же вопросом интересовался, прочитай тему - Некоторые ньюансы, связанные с FFT
                        У меня возникло пару вопросов.
                        1) Звук пропускаю через БПФ, выделяю 3 полосы(можно больше) в линейном масштабе, пропускаю каждую через скользящее среднее, чтобы отсеить резкие изменения и прочую нестабильность. Затем делаю DTW получившихся последовательностей с эталоном.
                        Как на картинке: http://s16.postimg.org/b877y36ut/sounds_dtw.png
                        Имеет ли право на жизнь такой подход?
                        2) Когда я запускаю DTW мне кажется, что результат ошибки сильно зависит от длины сравниваемых последовательностей. Например, 2 длинные похожие последовательности будут иметь абсолютную ошибку намного больше, чем 2 короткие непохожие.
                        Я сейчас подумываю перейти от абсолютной к относительной оценке: делить ошибку на число точек в наиболее длинной последовательности. Таким образом можно в более вменяемых величинах задавать порог срабатывания команды.
                        Что посоветуете или скажете?

                        О применении:
                        Хочу распознавать 2-3 слова(умный выключатель для своего дома). Вполне допустимо чтобы система была дикторозависимой. Приемлемое качество 70-80%.
                        Пока моделирую на ПК, в случае успеха алгоритм переедет во встроенную систему(до 16КБ ОЗУ, до 40 MIPS, процессор правда 32бит).
                          Цитата
                          Имеет ли право на жизнь такой подход?


                          Да, но лучше ещё логарифмическую шкалу ввести и среднее вычесть. Это сделает систему инвариантной к громкости сигнала.

                          Цитата
                          Я сейчас подумываю перейти от абсолютной к относительной оценке: делить ошибку на число точек в наиболее длинной последовательности. Таким образом можно в более вменяемых величинах задавать порог срабатывания команды.


                          Деление на длину большого смысла не имеет. Порог может быть различным даже для слов одинаковой длины. Проще всего порог настраивать для каждого слова в отдельности на тестовых примерах - запустить большой объем записи и выбрать минимальный порог для допустимого числа ложных срабатываний.
                            Я правильно понял, что мне надо просто преобразовать последовательности в логарифмическую шкалу(Мел-шкалу?), а затем делать DTW между ними?
                              Цитата
                              Я правильно понял, что мне надо просто преобразовать последовательности в логарифмическую шкалу(Мел-шкалу?), а затем делать DTW между ними?


                              Мел шкала частот и логарифмическая шкала амплитуд это разные вещи. Важно не только использовать логарифмическую шкалу, но ещё и усреднять сигнал, чтобы получить инвариантность к изменению амплитуды сигнала. Если сигнал усилен в два раза, то после взятия логарифма и усреднения сигнал не будет отличаться от простого, не усиленного сигнала. В вашем же варианте будет существенная разница в расстоянии DTW.

                              Подробнее об извлечении признаков лучше прочесть в книге.
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0401 ]   [ 15 queries used ]   [ Generated: 1.05.24, 07:54 GMT ]