HOWTO · Python
Implementar filtro passa-baixo em Python
Aprenda a filtrar dados amostrados em Python com um filtro Butterworth do SciPy, uma média móvel ou suavização gaussiana, e entenda a frequência de corte e os limites de amostragem.
Nesta página
Um filtro passa-baixas deixa passar componentes de baixa frequência e atenua os de frequência mais alta; isso não significa necessariamente que todos os componentes acima da frequência de corte sejam removidos. Para dados amostrados, escolha a frequência de corte usando as mesmas unidades da taxa de amostragem. Este guia apresenta três maneiras de filtrar ou suavizar um sinal unidimensional com NumPy e SciPy. Este tema de processamento de sinais é apenas um dos muitos cobertos no tutorial de Python completo.
Os exemplos a seguir são autocontidos, mas não são executados aqui e nenhum resultado é mostrado para eles. Instale NumPy, SciPy e Matplotlib no ambiente Python antes de executá-los.
Use um filtro Butterworth do SciPy com uma frequência de corte definida
Um filtro Butterworth tem uma banda passante maximamente plana. Defina a frequência de corte abaixo da frequência de Nyquist, que corresponde à metade da taxa de amostragem. No exemplo, fs é de 500 amostras por segundo e a frequência de corte é de 100 Hz. Passar fs para scipy.signal.butter permite expressar a frequência de corte nessas mesmas unidades. A ordem controla a inclinação da transição: uma ordem maior produz uma queda mais acentuada, mas aumenta a sensibilidade a transientes e ao comportamento numérico.
Este exemplo usa seções de segunda ordem e sosfiltfilt para filtrar o sinal nos sentidos direto e inverso. Isso evita o atraso de fase em análises offline, mas exige dados para as duas direções e pode afetar as extremidades de um sinal finito. Para dados em fluxo ou em tempo real, use um filtro causal, como sosfilt, e leve em conta o atraso de fase e o transiente inicial.
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import butter, sosfiltfilt
fs = 500.0
cutoff = 100.0
order = 4
time = np.arange(500) / fs
signal = np.sin(2 * np.pi * 10 * time) + 0.5 * np.sin(2 * np.pi * 180 * time)
sections = butter(order, cutoff, btype="lowpass", fs=fs, output="sos")
filtered = sosfiltfilt(sections, signal)
plt.plot(time, signal, label="input")
plt.plot(time, filtered, label="filtered")
plt.xlabel("Time (seconds)")
plt.ylabel("Amplitude")
plt.legend()
plt.tight_layout()
plt.show()
Ajuste cutoff e order conforme o sinal e as frequências que deseja preservar. sosfiltfilt é indicado para dados offline; seu resultado não é intercambiável com o de um filtro causal em tempo real.
Aplique um filtro passa-baixas de média móvel
Uma média móvel substitui cada ponto pela média de uma janela de tamanho fixo. É um método simples de suavização, não um projeto Butterworth com uma resposta de frequência de corte especificada. Com o modo de convolução valid do NumPy, o resultado contém apenas janelas completas e, por isso, tem window_size - 1 amostras a menos que a entrada. Ao plotá-lo, alinhe os valores de tempo de acordo com esse comprimento.
import matplotlib.pyplot as plt
import numpy as np
fs = 100.0
window_size = 5
time = np.arange(100) / fs
signal = np.sin(2 * np.pi * 3 * time) + 0.2 * np.sin(2 * np.pi * 25 * time)
weights = np.ones(window_size) / window_size
smoothed = np.convolve(signal, weights, mode="valid")
smoothed_time = time[window_size - 1:]
plt.plot(time, signal, label="input")
plt.plot(smoothed_time, smoothed, label="moving average")
plt.xlabel("Time (seconds)")
plt.ylabel("Amplitude")
plt.legend()
plt.tight_layout()
plt.show()
Escolha um tamanho de janela positivo que não seja maior que o comprimento do sinal. Aumentar a janela faz a média abranger mais amostras e intensifica a suavização, mas também amplia as mudanças e desloca o alinhamento do resultado calculado sobre as janelas. Para usar um alinhamento centralizado, leve em conta o atraso da janela ao interpretar os valores de tempo.
Use um filtro gaussiano para suavizar dados amostrados
Um filtro gaussiano unidimensional atribui pesos às amostras próximas por meio de um núcleo com formato gaussiano. Em scipy.ndimage.gaussian_filter1d, sigma é medido em amostras, não em segundos nem em hertz. Se necessário, converta a escala de tempo desejada em amostras usando a taxa de amostragem. A suavização gaussiana é útil para obter uma suavização geral, mas não cria uma frequência de corte definida e abrupta.
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import gaussian_filter1d
fs = 100.0
sigma_seconds = 0.04
time = np.arange(100) / fs
signal = np.sin(2 * np.pi * 3 * time) + 0.2 * np.sin(2 * np.pi * 25 * time)
smoothed = gaussian_filter1d(signal, sigma=sigma_seconds * fs)
plt.plot(time, signal, label="input")
plt.plot(time, smoothed, label="Gaussian smoothed")
plt.xlabel("Time (seconds)")
plt.ylabel("Amplitude")
plt.legend()
plt.tight_layout()
plt.show()
O exemplo converte uma escala de suavização de 0.04 segundos em quatro amostras. Por padrão, as extremidades são tratadas refletindo o sinal. Escolha outro mode se os seus dados seguirem um modelo diferente nas extremidades e interprete esses trechos com cuidado.
Escolha um filtro e entenda suas limitações
Use um filtro Butterworth quando precisar de uma resposta de frequência definida e souber a taxa de amostragem. Use uma média móvel para uma suavização simples baseada em janelas e a suavização gaussiana quando for apropriado atribuir pesos suaves às amostras próximas. Esses métodos têm respostas, atrasos e comportamentos nas extremidades diferentes. Compare o resultado com os dados originais e verifique se as características importantes para a sua tarefa continuam visíveis.
Para dados amostrados, a frequência de Nyquist corresponde à metade da taxa de amostragem. A frequência de corte de um filtro passa-baixas deve ficar abaixo de Nyquist, e a taxa de amostragem precisa ser alta o suficiente para representar as frequências de interesse. Nenhum filtro recupera informações que não foram capturadas durante a amostragem. A filtragem offline nos sentidos direto e inverso pode reduzir o deslocamento de fase, enquanto a filtragem causal serve para processamento em fluxo, mas introduz atraso e comportamento inicial. Em registros finitos, os resultados próximos às extremidades também são mais sensíveis ao preenchimento e às condições iniciais.
Perguntas frequentes
O que faz um filtro passa-baixas?
Ele deixa passar componentes de baixa frequência e atenua os de frequência mais alta, de acordo com sua resposta. A frequência de corte marca uma transição nessa resposta; não significa que todas as frequências mais altas desapareçam por completo.
Quando devo usar um filtro passa-baixas?
Use-o quando a variação de frequência mais alta for ruído para a sua tarefa e você souber a taxa de amostragem e a frequência de corte. Verifique se a suavização não remove mudanças rápidas que sejam relevantes no sinal.
Qual é a diferença entre um filtro Butterworth e uma média móvel?
Um filtro Butterworth é projetado a partir de uma frequência de corte, de uma taxa de amostragem e de uma ordem. Uma média móvel usa um número fixo de amostras por janela e tem outra resposta de frequência; o comprimento da janela não substitui diretamente a frequência de corte de um Butterworth.
Posso usar esses filtros com dados em tempo real?
Um filtro causal pode processar as amostras à medida que chegam, mas seu atraso de fase e transiente inicial precisam ser considerados. O método de filtragem nos sentidos direto e inverso do exemplo Butterworth precisa do registro completo e é indicado para processamento offline. Uma média móvel pode ser atualizada conforme as amostras chegam, desde que você controle a janela e o alinhamento.
Quais bibliotecas Python posso usar?
NumPy fornece arrays e funções de convolução, enquanto SciPy oferece funções para projetar filtros Butterworth e fazer suavização gaussiana. Matplotlib permite plotar os sinais de entrada e filtrado para inspeção.