Применение временного фильтра в Python

Я пытаюсь применить полосовой фильтр с изменяющимися во времени частотой среза к сигналу, используя Python. Подпрограмма, которую я сейчас использую, разбивает мой сигнал на отрезки времени одинаковой длины, затем для каждого сегмента я применяю фильтр с параметрами, зависящими от времени, прежде чем объединить сигнал обратно. Параметры основаны на ранее существующих оценках.

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

Я надеялся, что кто-нибудь может сообщить мне, существуют ли какие-либо подпрограммы для реализации фильтров с изменяющимися во времени параметрами в Python? В качестве альтернативы, советы о том, как я мог бы обойти эту проблему, будут высоко оценены.

РЕДАКТИРОВАТЬ - пример того, что я хочу сделать, добавлен ниже.

Позволять'скажем, у меня есть сигнал х (т). Я хочу отфильтровать первую половину с помощью полосового фильтра с параметрами (100,200) Гц. Второй тайм хочу отфильтровать по параметрам (140, 240) Гц. Я перебираю x (t), применяя свой фильтр к каждой половине, а затем рекомбинирую результаты. Пример кода может выглядеть следующим образом:



outputArray = np.empty(len(x))
segmentSize = len(x) / 2
filtParams  = [(100, 200), (140, 240)]

for i in range(2):
    tempData     = x[i*segmentSize:(i+1)*segmentSize]
    tempFiltered = bandPassFilter(tempData, parameters=filtParams[i])
    outputArray[i*segmentSize:(i+1)*segmentSize] = tempFiltered

(Для экономии места пустьПредположим, у меня есть функция, которая выполняет полосовую фильтрацию).

Как видите, сегменты данных не перекрываются и просто "вставили» обратно вместе в новом массиве.

РЕДАКТИРОВАТЬ 2 - пример кода моей проблемы @ H.D.

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

Я подумал, что будет немного полезнее, если я опишу свои цели более подробно. Как я уже писалв другом местеЯ пытаюсь извлечьмгновенная частота (IF) сигнала, используя преобразование Гильберта. Мои данные содержат значительный шум, но у меня есть хорошая оценка ширины полосы, где лежит мой сигнал ПЧ. Однако проблема, с которой я столкнулся, заключается в том, что ЕСЛИ часто является нестационарным. Используя "статический» Подход фильтра. Поэтому мне часто приходится использовать широкую полосу пропускания, чтобы обеспечить захват всех частот.

Следующий код демонстрирует влияние увеличения полосы пропускания фильтра на сигнал ПЧ. Он включает в себя функцию генерации сигнала, реализацию полосового фильтра с использованием пакета scipy.signal и способ для извлечения IF из результирующего отфильтрованного сигнала.

from audiolazy import *
import scipy.signal as sig
import numpy as np
from pylab import *

def sineGenerator( ts, f, rate, noiseLevel=None ):
    """generate a sine tone with time, frequency, sample rate and noise specified"""

    fs = np.ones(len(ts)) * f    
    y  = np.sin(2*np.pi*fs*ts)

    if noiseLevel: y = y + np.random.randn(len(y))/float(noiseLevel)
    return y

def bandPassFilter( y, passFreqs, rate, order ):
    """STATIC bandpass filter using scipy.signal Butterworth filter"""

    nyquist = rate / 2.0
    Wn      = np.array([passFreqs[0]/nyquist, passFreqs[1]/nyquist])    
    z, p, k = sig.butter(order, Wn, btype='bandpass', output='zpk')
    b, a    = sig.zpk2tf(z, p, k)

    return sig.lfilter(b, a, y)

if __name__ == '__main__':
     rate = 1e4
     ts   = np.arange(0, 10, 1/rate)

     # CHANGING THE FILTER AFFECTS THE LEVEL OF NOISE
     ys    = sineGenerator(ts, 600.0, 1e4, noiseLevel=1.0) # a 600Hz signal with noise
     filts = [[500, 700], [550, 650], [580, 620]]

    for f in filts:
        tempFilt = bandPassFilter( ys, f, rate, order=2 )
        tempFreq = instantaneousFrequency( tempFilt, rate )

        plot( ts[1:], tempFreq, alpha=.7, label=str(f).strip('[]') )

    ylim( 500, 750 )
    xlabel( 'time' )
    ylabel( 'instantaneous frequency (Hz)' )

    legend(frameon=False)
    title('changing filter passband and instantaneous frequency')
    savefig('changingPassBand.png')

В сигнале присутствует одночастотный компонент (при 600 Гц). Легенда показывает параметры фильтра, используемые в каждом случае. Используя ужестатический» фильтр дает "очиститель" выход. Но насколько узким может быть мой фильтр, зависит от частоты. Например, рассмотрим следующий сигнал с двумя частотными составляющими (один на частоте 600 Гц, другой на частоте 650 Гц).

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

Моя идея состоит в том, что, используя меняющийся во времени фильтр, я могуоптимизировать» фильтр для моего сигнала в определенные моменты времени. Так что для вышеуказанного сигнала я мог бы хотеть фильтровать около 580-620 Гц в течение первых 5 секунд, затем 630-670 Гц в течение следующих 5 секунд. По сути, я хочу минимизировать шум в конечном сигнале ПЧ.

На основе примера кода, который вы послали, я написал функцию, которая использует аудиолазию для реализации статического фильтра Баттерворта для сигнала.

def audioLazyFilter( y, rate, Wp, Ws ):
    """implement a Butterworth filter using audiolazy"""

    s, Hz = sHz(rate)
    Wp    = Wp * Hz # Bandpass range in rad/sample
    Ws    = Ws * Hz # Bandstop range in rad/sample

    order, new_wp_divpi = sig.buttord(Wp/np.pi, Ws/np.pi, gpass=dB10(.6), gstop=dB10(.1))
    ssfilt = sig.butter(order, new_wp_divpi, btype='bandpass')
    filt_butter = ZFilter(ssfilt[0].tolist(), ssfilt[1].tolist())

    return list(filt_butter(y))

Данные ПЧ, полученные с использованием этого фильтра в сочетании с процедурой преобразования Гильберта, хорошо сравниваются с данными, полученными с использованием scipy.signal:

AL_filtered = audioLazyFilter( ys, rate, np.array([580, 620]), np.array([570, 630]) )
SP_filtered = bandPassFilter( ys, [580, 620], rate, order=2 )
plot(ts[1:], instantaneousFrequency( SP_filtered, 1e4 ), alpha=.75, label='scipy.signal Butterworth filter')
plot(ts[1:], instantaneousFrequency( AL_filtered, 1e4 ), 'r', alpha=.75, label='audiolazy Butterworth filter')

Теперь у меня вопрос: могу ли я объединить рутину аудиолазия Баттерворта с изменяющимися во времени свойствами, которые вы описали в своих оригинальных постах?

Ответы на вопрос(3)

Ваш ответ на вопрос