Как удалить граничные эффекты, возникающие из-за нулевого заполнения в scipy / numpy fft?
Я сделал код python для сглаживания заданного сигнала с использованием преобразования Вейерштрасса, который в основном представляет собой свертку нормированного гауссова с сигналом.
Код выглядит следующим образом:
#Importing relevant libraries from __future__ import division from scipy.signal import fftconvolve import numpy as np def smooth_func(sig, x, t= 0.002): N = len(x) x1 = x[-1] x0 = x[0] # defining a new array y which is symmetric around zero, to make the gaussian symmetric. y = np.linspace(-(x1-x0)/2, (x1-x0)/2, N) #gaussian centered around zero. gaus = np.exp(-y**(2)/t) #using fftconvolve to speed up the convolution; gaus.sum() is the normalization constant. return fftconvolve(sig, gaus/gaus.sum(), mode='same')
Если я запустил этот код для функции шага, он сглаживает угол, но на границе он интерпретирует другой угол и сглаживает его тоже, что приводит к ненужному поведению на границе. Я объясняю это цифрой, показанной в приведенной ниже ссылке.
Граничные эффекты
Эта проблема не возникает, если мы непосредственно интегрируем, чтобы найти свертку. Следовательно, проблема заключается не в преобразовании Вейерштрасса, а потому проблема находится в fftconvolve-функции scipy.
Чтобы понять, почему возникает эта проблема, нам сначала нужно понять работу fftconvolve в scipy.
Функция fftconvolve в основном использует теорему свертки для ускорения вычислений.
Короче говоря:
Свертка (int1, int2) = ОБПФ (FFT (int1) * FFT (int2))
Если мы непосредственно применим эту теорему, мы не получим желаемого результата. Чтобы получить желаемый результат, нам нужно взять fft на массив, удваивающий размер max (int1, int2). Но это приводит к нежелательным граничным эффектам. Это связано с тем, что в fft-коде, если размер (int) больше размера (для которого нужно взять fft), он равен нулю, а затем принимает значение fft. Это нулевое заполнение – именно то, что отвечает за нежелательные граничные эффекты.
Можете ли вы предложить способ устранения этих граничных эффектов?
Я попытался удалить его простым трюком. После сглаживания функции я сравниваю значение сглаженного сигнала с исходным сигналом вблизи границ, и если они не совпадают, я заменяю значение сглаженной функции с входным сигналом в этой точке.
Это выглядит так:
i = 0 eps=1e-3 while abs(smooth[i]-sig[i])> eps: #compairing the signals on the left boundary smooth[i] = sig[i] i = i + 1 j = -1 while abs(smooth[j]-sig[j])> eps: # compairing on the right boundary. smooth[j] = sig[j] j = j - 1
Существует проблема с этим методом, из-за использования epsilon есть небольшие прыжки в сглаженной функции, как показано ниже:
прыжки в гладкой функции
Могут ли быть внесены какие-либо изменения в вышеуказанный метод для решения этой граничной задачи?
- Как улучшить изображение, а затем преобразовать его в двоичное изображение с помощью Python и OpenCV?
- FFT: найти и вырезать шумно 50 Гц в сигнале
- Анализ сигналов в Python – удаление выбросов из кривой
- Отображение бина Python scipy.fftpack.rfft
- Определите, как долго сигнал превышает предопределенный предел
То, что создает симметричное ядро фильтра на концах, зависит от того, что вы считаете данными за пределами концов.
Если вам не нравятся внешний вид текущего результата, который принимает нули за пределами обоих концов, попробуйте расширить данные с помощью другого предположения, например, отражения данных или продолжения полиномиальной регрессии. Расширьте данные на обоих концах, по крайней мере, на половину длины ядра фильтра (за исключением того, что ваше расширение имеет нули, которые предоставляются бесплатно с существующим нулевым заполнением, необходимым для некруговой свертки). Затем удалите добавленные конечные выдержки после фильтрации и посмотрите, нравится ли вам внешний вид вашего предположения. Если нет, попробуйте другое предположение. Или еще лучше, используйте фактические данные за пределами концов, если у вас есть такие.
Лучшим подходом, вероятно, является использование mode = 'valid'
:
The output consists only of those elements that do not rely on the zero-padding.
Если вы не можете обернуть свой сигнал или обработанный сигнал является выдержкой из более крупного сигнала (в этом случае: обработать полный сигнал, а затем область обрезки интереса), вы всегда будете иметь краевые эффекты при выполнении свертки. Вы должны выбрать, как вы хотите иметь дело с ними. Использование mode = valid
просто выставляет их, что является довольно хорошим решением. Если вы знаете, что сигнал всегда «ступенчатый», вы могли бы затем расширить фронт и конец обработанного сигнала, если это необходимо.
- scipy разреженная матрица: удалите строки, все элементы которых равны нулю
- Использование китайского языка для создания словаря в Python
- Python обнаруживает альтернативные пики
- Функция Matlab freqz в Python
- Удаление фонового шума из аудиосигналов с использованием FFT Python
- Как определить системы LTI с задержкой по времени в Scipy?
- Пакет Python для обработки сигналов
- DSP: обработка звука: squart или log для использования fft?
- Вычисление спектра мощности
- Фильтр высоких частот Python
- Python MNE – чтение данных ЭЭГ из массива