описание проблемы
Я хочу использовать распознавание голоса как часть аппаратного проекта, который я хотел бы быть полностью автономным (я использую небольшие маломощные и низкоскоростные устройства, такие как Arduino и Raspberry Pi, Kinects и т. Д., Не использую традиционный компьютер с ОС вовлечена. Таким образом, закрытый / самодостаточный проект).
Распознавание голоса может быть очень сложным в зависимости от желаемого уровня сложности. У меня есть то, что я считаю сравнительно простым набором требований. Я только хочу узнать свой собственный голос, и у меня есть небольшой словарь из примерно 20 слов, которые я хотел бы узнать. Таким образом, мне не требуются сложные библиотеки распознавания речи и текста или какое-либо отличное программное обеспечение сторонних производителей, которое я нахожу через интернет-поисковые системы (в этом нет недостатка!). Я считаю, что мои требования «достаточно просты» (в пределах разумного), чтобы я мог написать собственное решение. Мне интересно, если кто-то написал свой собственный процесс, как это, и является ли мой метод в значительной степени ошибочным? Есть ли лучший способ сделать это, не требуя высокого уровня математики или необходимости писать сложный алгоритм? Это решение, которое я попытался придумать ниже.
Описание решения
Я буду писать это на C, но я хочу обсудить независимый от языка процесс, сосредоточив внимание на самом процессе. Так что давайте проигнорируем это, если сможем.
1 Я предварительно запишу свой словарь слов, чтобы они соответствовали тем, о которых говорят. Мы можем представить, что у меня есть 20 записей моих 20 разных слов, или, возможно, короткие фразы или предложения из двух или трех слов. Я считаю, что это облегчает процесс сравнения двух записываемых файлов, чем преобразование аудио в текст и сравнение двух строк.
2 Микрофон подключен к моему аппаратному устройству, на котором выполняется мой код. [1]. Код непрерывно берет выборки фиксированной длины, например, 10 мс, и сохраняет 10 последовательных выборок, например, в стиле циклического каротажа. [2]. (Я придумываю эти цифры на макушке, чтобы они были только примерами для описания процесса).
[1] Скорее всего, это будет связано через полосовой фильтр и операционный усилитель, как и записи в словаре, для сохранения меньшего размера сохраненных и собранных аудиосэмплов.
[2] Я не уверен, как именно я возьму сэмпл, мне нужно разработать метод, хотя бы я производил числовое число (целое число / число с плавающей запятой / двойное число), которое представляет аудио сэмпла 10 мс (возможно, значение CRC или сумма MD5 и т. д. аудиосэмпла), или поток цифр (возможно, поток аудиоданных частот). В конечном итоге «образец» будет числовой цифрой или цифрами. В этой части будет задействовано гораздо больше аппаратного обеспечения, поэтому здесь не для обсуждения.
3 Код просматривает сохраненные 10 последовательных сэмплов и ищет увеличение громкости, чтобы указать, что слово или фраза произносятся (перерыв в тишине), а затем увеличивается - последовательный сбор сэмплов, например, до 500 сэмплов. Это будет означать, что он захватывает 5 секунд аудио в сэмплах 10 мсек.
Именно эти сэмплы или «срезы» сравниваются между сохраненным звуком и захваченным звуком. Если достаточно высокий процент отснятых выборок соответствует эквивалентным сохраненным, код принимает то же слово.
The start of a store recording of the world "hello" for example,
stored words are split into 10 msec samples also
Stored Sample No | 1| 2| 3| 4| 5| 6| 7| 8|
Stored Sample Value |27|38|41|16|59|77|200|78|
Incoming audio (me saying "hello") with some "blank" samples
at the start to symbolise silence
Incoming Sample No | 1| 2| 3| 4| 5| 6| 7| 8| 9|10| 11|12|
Incoming Sample Value | | | |20|27|38|46|16|59|77|200|78|
4 Как только код собрал полный поток сэмплов, он вначале отбирает пробные сэмплы для создания следующей аудиозаписи. Это также может переместить набор образцов назад и вперед на несколько мест, чтобы лучше выровнять его с сохраненным образцом.
Это производит пример набора, как показано ниже:
Stored Sample No | 1| 2| 3| 4| 5| 6| 7| 8|
Stored Sample Value |27|38|41|16|59|77|200|78|
Incoming Sample No |-1| 1| 2| 3| 4| 5| 6| 7| 8|
Incoming Sample Value |20|27|38|46|16|59|81|201|78|
5 Я полагаю, что при наличии процентного значения для того, насколько близко должна быть каждая выборка, образец 7 отличается значением 1, которое меньше, чем% 1, и процентным значением для общего количества образцов, которое должно быть в пределах их процентного соотношения выборки. код имеет легко настраиваемый уровень точности.
Я никогда раньше не делал ничего подобного со звуком, это может быть много работы. Вот почему я задаю этот вопрос, если вы, возможно, уже знаете, что ответ на этот вопрос очевиден (каким бы ни был этот ответ). Я надеюсь, что это не будет сложной вычислительной задачей, так как часть оборудования, которое я буду использовать, будет занимать мало секунды. В сотнях мегагерц (возможно, 1 ГГц, используя разогнанный Rasp Pi). Так что это довольно грубый способ сопоставления аудиосэмплов с использованием меньшей вычислительной мощности. Я не стремлюсь к мгновенным результатам, но менее чем за 30 секунд для достойного доказательства концепции.
PS У меня нет представителя, чтобы пометить это новым тегом, таким как «аудио», «распознавание звука», «голос», «распознавание голоса» и т. Д.
источник
Ответы:
Ну, я не верю, что Arduino обладает силой, способной сделать это. он работает на частоте 16 МГц. Arduino имеет около 32 КБ памяти. Даже 20 слов, сэмплированных в Mp3 (меньше, чем wav), не поместятся в нем, несмотря на то, что это только ваш собственный голос.
Rasberi Pi может добиться цели, его работа на частоте 700 МГц зависит от версии, в которой он может иметь 512 МБ памяти. Это все еще не много теста.
Вам может понадобиться фурье ( http://www.drdobbs.com/cpp/a-simple-and-efficient-fft-implementatio/199500857 )
Или, если вы намереваетесь использовать объем, сделайте несколько средних с предыдущими выборками, например,
x = (x + x [n-1] + x [n-2] + x [n-3]) / 4 //, что довольно просто нужно больше
Следующее, что вам нужно сделать, это подумать, если бы вы построили эти значения X, то вам нужно какое-то обнаружение наклона этой линии, потому что обнаружение команд, основанных на громкости, во многом зависит от расстояния, в то время как вы бы предпочли обнаружить шаблон слова
Тогда немного зависит, как записать уклон, чтобы паттерн подходил в другой раз. Я имею в виду, что никто не говорит в точном темпе, с которым может сравниться компьютер, а наклон может быть немного круче. В конце я думаю, что эти линии немного крутые, а их длина по оси Y должна быть в среднем
источник
Arduino и Raspberry Pi - это макетные платы с небольшими чипами на них. Вы должны сосредоточиться на чипе в первую очередь. Ищите что-нибудь с набором инструментов DSP (цифровая обработка сигналов), возможно, у вас уже есть набор инструментов DSP и вы его не знаете. Наборы инструментов DSP имеют такие алгоритмы вызова, как fft (быстрое преобразование Фурье) и ifft (обратное fft) для быстрого анализа в частотной области.
Сосредоточьтесь на своем программном стиле: ваши образцы в стеке или в очереди? Вы будете хотеть очередь для этого типа данных. Очередь выглядит так:
Следующая итерация:
Заметьте, как все смещается в сторону «вправо»? Я думаю, что вы описали «круговой» алгоритм. Просто перезапишите самые старые сэмплы вторыми самыми старыми сэмплами, затем перезапишите вторые самые старые сэмплы третьим самым старым, ..., вплоть до начала очереди, куда вы вставляете самые новые данные.
«Код непрерывно отбирает выборки фиксированной длины, скажем, 10 мсек» <- неправильно. Подумайте так: код дискретно отбирает квантованные (высотные) выборки со скоростью выборки 10000 выборок в секунду, что делает каждую выборку с интервалом 0,1 мс.
Какова ваша частота дискретизации? Какой битрейт на вашем квантователе? Меньшие цифры помогут вам освободить память. Я бы предложил низкую частоту дискретизации, например 6600 выборок в секунду (Найквист). Я подозреваю, что 4 бит (16 уровней) будет достаточно для распознавания. Это 3300 байт записи в секунду. Теперь выполните FFT и удалите все, что выше 3300 Гц (фильтр телефонии). Теперь у вас есть 1650 байтов, используемых для одной секунды звука. Эти приемы DSP сэкономят много памяти.
Я не знаю, кто думает, что 512 МБ мало. С вышеупомянутой информацией, которая составляет 300 000+ секунд записи ... более 3 дней.
Я думаю, что вы найдете частотную область (используя fft) как лучшую среду для распознавания голоса.
Надеюсь, я вас не смутил хуже :)
источник