Точное определение появления акустических сигнатур, таких как птичий щелчок, человеческая речь и т. д., из больших аудиофайлов.

Введение
Большие данные обеспечивают множество приложений, при условии, что мы преодолеваем первое и, возможно, самое большое препятствие из всех, определяя интересные закономерности или даже отделяя значимые части от мусора. Экологи сталкиваются с той же проблемой, имея доступ к часам записи леса со всеми его элементами в целом, как мы можем выделить важные из них, такие как звук приближающегося тигра или птичий щелчок. Для этого требуется интеллектуальная техника для отделения мусора, который может включать фоновый шум леса, такой как звук дуновения ветра, шелест листьев или событие отдаленного движения (в текущем контексте). Удалив все это, мы сможем идентифицировать интересные части, которые классифицируются как акустические события.
Шаг 1: Предварительная обработка сигнала
Во-первых, давайте получим данные в общем формате. Для начала мы можем понизить выборку данных до 22 050 Гц и с глубиной 16 бит. Это означает, что для 1 секунды аудиоданных у нас есть ~ 22 тысячи сэмплов, где каждый сэмпл может иметь около 2¹⁶ (65 536) уровней сэмплов или разрешения.

Теперь вместо того, чтобы выполнять дальнейший анализ этой модифицированной формы волны, которая имеет дело только с 2 измерениями, т. е. временем и амплитудой, давайте преобразуем данные в 3 измерения, включив также частоту. Мы можем сделать это, сгенерировав спектрограмму звуковой волны. Для этого нам нужно сначала создать кадры из 512 сэмплов с перекрытием 50%, к которым применяется окно Хэмминга. После этого мы передаем каждый кадр функции FFT (быстрое преобразование Фурье) и получаем в ответ значения амплитуды для 256 частотных элементов. Чтобы сгладить результаты, мы применяем скользящее среднее шириной 3. Наконец, значения амплитуды преобразуются в децибелы с помощью следующей функции:

Теперь, вместо выполнения всех этих шагов, мы можем использовать библиотеку python matplotlib, и преобразование становится таким же простым, как:
>> import matplotlib.pyplot as plt >> import numpy as np >> _, freqs, t, im = \ plt.specgram(x = indata[0], Fs = indata[1], window = np.hamming(512), NFFT = 512, noverlap = 256)
Здесь indata[0] — массив амплитуд сигнала, indata[1] содержит частоту дискретизации (здесь 22050). window обозначает примененное окно сглаживания и его размер, здесь его размер равен размеру каждого кадра, то есть 512. NFFT является размером каждого кадра, а noverlap является размером выборки перекрытия, так как 50% от 512 составляет 256. После этого наша форма волны преобразуется в

Шаг 2: Винеровская фильтрация
Прежде чем идти дальше, нам нужно сгладить края сгенерированной спектрограммы. Это поможет убрать зернистость фона и размытие акустических событий. Это также помогает уменьшить количество очень мелких распределенных событий, генерируемых в конечном выводе. Для этого мы можем использовать двумерную матрицу Винера 5x5 и применить ее к спектрограмме.
>> from scipy.signal import wiener >> im = wiener(im, (5, 5))
Вывод выглядит как размытое изображение исходного изображения,

Шаг 3: Шумоподавление
Чтобы лучше оценить акустические события, нам нужно обрабатывать шум, который генерируется вместе с событиями, особенно те, которые распространяются по частотной области. Вклад шума в записи данных об окружающей среде уменьшается с увеличением частоты. Для этого применяется модифицированное адаптивное выравнивание уровня. Для каждой строки изображения спектрограммы вычисляется гистограмма значения интенсивности в децибелах, где ширина бина составляет 1 дБ. После сглаживания гистограммы мы определяем модальную интенсивность шума, которая находится в максимальном бине в нижней половине гистограммы.

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

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

Шаг 4: Двоичное преобразование
Поскольку наша конечная цель — найти действительные события, любое потенциальное событие может иметь только два возможных состояния: либо оно является событием, либо нет. Следовательно, нам нужно преобразовать наше изображение в бинарное изображение, которое демонстрирует бинарное присутствие события. Это можно сделать, установив один порог интенсивности, и любое значение выше этого является событием, а любое значение ниже — фоновым шумом. Этот порог зависит от пользователя и приложения, но в большинстве случаев подойдет значение от 6 до 9 дБ. В нашем случае давайте выберем значение 6 дБ и преобразуем изображение в двоичное на основе нашей обсуждаемой логики.
>> binary_threshold = 6 >> im_bw = np.array([x[:] for x in im]) >> im_bw[np.where(im > binary_threshold)] = 1 >> im_bw[np.where(im <= binary_threshold)] = 0

Здесь черный — фон, а белый — подпись события.
Шаг 5. Воссоединение прерванных событий
Событие распространяется по временному и частотному измерению и отличается наличием непрерывного распространения в этих измерениях. Проще говоря, одно белое пятно на бинарной сонограмме — это одно событие. Несколько событий будут разделены черными пятнами между ними. Но из-за бинарного преобразования одного порогового значения на последнем этапе одно событие низкой интенсивности может разбиться на несколько событий меньшей интенсивности. Чтобы справиться с этим, нам нужно идентифицировать и объединить такие события, чтобы сформировать одно событие. Мы делаем это, объединяя события, которые отделены друг от друга N или меньшим количеством пикселей по вертикали или горизонтали. По умолчанию мы можем выбрать N равным 1. Таким образом, если между двумя белыми каплями есть черное однопиксельное пятно, мы заполняем черное пятно, чтобы соединить два события.
Шаг 6: Определите акустические события
Теперь нам нужно идентифицировать отдельные события, которые можно обработать с помощью обработки изображений. На бинарном изображении сонограммы нам нужно определить границы выделенных белых пятен. Это делает это проблемой поиска контура или границы. Используя библиотеку обработки изображений Python CV2, которая имеет очень эффективную реализацию поиска контуров, все, что нам нужно, это передать изображение и получить список контуров (здесь события) в качестве вывода.
>> _, contours, _ = cv2.findContours(im, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

Шаг 7: Удаление мелких событий
Даже после всех предварительных шагов по удалению нежелательных событий всегда существует возможность возникновения какого-то необъяснимого или нежелательного события, которое не было учтено в предыдущих шагах. Чтобы справиться с этим, мы выполним окончательную постобработку обнаруженных событий на этом последнем шаге. Обратите внимание, что для каждого обнаруженного контура или события, поскольку они представляют собой не что иное, как пятно или пятно на 2D-изображении, мы можем связать с ними область. Таким образом, у каждого события есть некоторая площадь, которая представляет собой не что иное, как площадь белого пятна. Все, что мы хотим сказать, это то, что если площадь события меньше некоторого порога, это его шум, в противном случае оно действительное. Вместо того, чтобы слепо доверять порогу пользователя, мы можем применить анализ распределения изображений для автоматической проверки порога. Для этого допустим, что у нас есть пользовательский порог 200 ( p_small ), т. е. для пользователя любое событие с площадью менее 200 является шумом, мы идентифицируем все события с площадью менее 200 и сформируем 10-биновую гистограмму. Проверенный порог — это первый минимум с левой стороны гистограммы. Любое событие с площадью меньше этого идентифицированного порога удаляется, а оставшиеся (в том числе с площадью более p_small) считаются идентифицированными событиями.

Отсюда мы видим, что проверенный порог также равен 200, похоже, что пользователь все время был прав. Но в большинстве случаев это может быть неправдой, и проверить это не так уж и дорого. Следовательно, здесь мы выбираем правильный порог 200 и удаляем все события с площадью меньше этой.
Заключение
Для каждого обнаруженного события мы можем определить его время начала (координата самого левого пикселя соответствующего белого пятна), его продолжительность (распространение пятна по оси x), а также его высокую и низкую частоту (верхняя и нижняя). координата наибольшего пикселя капли по оси Y). В итоге ввод аудиофайла преобразуется в таблицу обнаруженных событий вместе с их основной информацией. Две переменные взаимодействия: binary_threshold и p_small, которые пользователь может увеличивать и/или уменьшать в соответствии с приложением и требуемым результатом для получения разнообразного результата.
использованная литература
[1] Акустический анализ природной среды, Майкл Тауси и Биргит Планитц.
Чтобы увидеть больше таких статей, пожалуйста, посетите мой личный блог.
Ваше здоровье.