Я извлекаю аудиоклипы из видеофайла для распознавания речи. Эти видео поступают с мобильных/других самодельных устройств и, следовательно, содержат много шума. Я хочу уменьшить фоновый шум звука, чтобы речь, которую я передаю в свой движок распознавания речи, была четкой. Я использую ffmpeg для всего этого, но застрял на этапе шумоподавления.
До сих пор я пробовал следующие фильтры:
ffmpeg-20140324-git-63dbba6-win64-static\bin>ffmpeg -i i nput.wav -filter_complex "highpass=f=400,lowpass=f=1800" out2.wav
ffmpeg -i i nput.wav -af "equalizer=f=1000:width_type=h:width=900:g=-10" output.wav
ffmpeg -i i nput.wav -af "bandreject=f=1200:width_type=h:width=900:g=-10" output.wav
Но результаты очень разочаровывают. Я рассуждал так: поскольку речь находится в диапазоне 300-3000 Гц, я могу отфильтровать все остальные частоты, чтобы подавить любой фоновый шум. Что я упускаю?
Кроме того, я прочитал о фильтрах Вайнера, которые можно использовать для улучшения речи, и обнаружил,этотно я не уверен, как им пользоваться.
решение1
Если вы хотите изолировать слышимую речь, попробуйте объединить фильтр нижних частот с фильтром верхних частот. Для пригодного звука я заметил, что отфильтровывание 200 Гц и ниже, а затем отфильтровывание 3000 Гц и выше довольно хорошо сохраняет пригодный для использования голосовой звук.
ffmpeg -i <input_file> -af "highpass=f=200, lowpass=f=3000" <output_file>
В этом примере сначала добавьте фильтр высоких частот, чтобы обрезать низкие частоты, а затем используйте фильтр низких частот, чтобы обрезать высокие частоты. При необходимости вы можете пропустить файл через это больше одного раза, чтобы очистить высокие частоты дБ в диапазонах частот обрезки.
решение2
Теперь в FFmpeg есть 3 собственных фильтра для борьбы с фоновым шумом:
afftdn
: Устраняет шумы аудиосэмплов с помощью FFTanlmdn
: Уменьшает широкополосный шум в аудиосэмплах с помощью алгоритма нелокальных среднихarnndn
: Уменьшает шум речи с помощью рекуррентных нейронных сетей. Примеры файлов моделей для загрузки можно найти здесьздесь.
Также с некоторых пор можно использовать фильтры ladspa
(поиск шумоподавителя) и/или lv2
(поиск речевого шумоподавителя) с FFmpeg.
решение3
Обновление: недавно добавлен FFmpeg afftdn
, который использует метод порогового значения шума для каждого бина БПФ, описанный ниже, с различными вариантами адаптации/вычисления соответствующих пороговых значений «на лету».
anlmdn
(нелокальные средства) — это метод, который хорошо работает для видео; аудиофильтр я не пробовал.
Любой из них должен бытьмноголучше, чем фильтр верхних/нижних частот, если только ваш единственный шум не представляет собой гул на частоте 60 Гц или что-то в этом роде. (Человеческая речь может звучать нормально в довольно узкой полосе пропускания, но есть гораздо лучшие способы очистить широкополосный шумовой фоновый шипение.)
В ffmpeg нет приличных встроенных аудиофильтров для шумоподавления. В Audacity есть довольно эффективный фильтр шумоподавления, но он предназначен для использования в двухпроходном режиме с выборкой только шума, а затем входных данных.
Комментарии вверхуhttps://github.com/audacity/audacity/blob/master/src/effects/NoiseReduction.cppобъясните, как это работает. (в основном: подавляет каждый FFT-диапазон ниже порогового значения. Таким образом, он пропускает только сигналы, которые громче, чем уровень шума в этой полосе частот. Он может делать удивительные вещи, не создавая проблем. Это как полосовой фильтр, который адаптируется к сигналу. Поскольку энергия шума распределена по всему спектру, пропускание только нескольких узких полос значительно снизит общую энергию шума.
Смотрите такжеПодавление шума в аудио: как Audacity соотносится с другими вариантами?для получения более подробной информации о том, как это работает, а также о том, что пороговая обработка бинов БПФ тем или иным способом также является основой типичных коммерческих фильтров шумоподавления.
Перенос этого фильтра в ffmpeg был бы немного неудобен. Возможно, лучше было бы реализовать его как фильтр с 2 входами, а не как 2-проходной фильтр. Поскольку ему нужно всего несколько секунд, чтобы получить профиль шума, ему не нужно считывать весь файл. И в любом случае вам НЕ СЛЕДУЕТ подавать ему весь аудиопоток как образец шума. Ему нужно увидеть образец ТОЛЬКО шума, чтобы установить пороговые значения для каждого бина FFT.
Так что да, 2-й вход, а не 2-проходной, имел бы смысл. Но это делает его намного менее простым в использовании, чем большинство фильтров ffmpeg. Вам понадобится куча вуду с разделением потока / извлечением временного диапазона. И, конечно, вам нужно ручное вмешательство, если только у вас нет образца шума в отдельном файле, который будет подходить для нескольких входных файлов. (один образец шума с одного микрофона / настройки должен быть хорош для всех клипов из этой настройки.)
решение4
Завершитьпользователь564335ответ:
Этот: -af arnndn=m=cb.rnnn
вероятно, лучший фильтр шума, который я использовалffmpeg
(на основе ИИ).
Так:
ffmpeg -i <input_file> -af arnndn=m=cb.rnnn <output_file>
Нет необходимости в полосовых фильтрах частот. Обученные модели ( files.rnnn
)доступна здесь(вам необходимо скачать и использовать один из файлов).
Модель cb
( conjoined-burgers
) — это та, которую я нашел.Наиболее впечатляющимloudnorm
и универсальный. Я также нашел этот фильтр довольно эффективным ( например, он не использует больше ресурсов ЦП, чем фильтр).
Кроме того, начиная с версии ffmpeg 5.0, появился новый фильтр шума:афвтдн.
Если я правильно помню, я пробовал, но, на мой взгляд, это было не так эффективно, как обученная нейронная сеть выше.