Tôi đang cố gắng tạo bộ lọc thông thấp đơn giản, nhưng tôi đã nhận được kết quả đáng ngạc nhiên khi xem xét đáp ứng tần số của bộ lọc Butterworth đơn giản.
Tôi đã sao chép nhiều ví dụ dưới đây từ bài đăng khác này . Tôi đã thêm một số mã ở dưới cùng của tập lệnh để so sánh phổ đầu vào và đầu ra với đáp ứng tần số của bộ lọc. Tôi hy vọng rằng phổ đầu ra sẽ là sản phẩm của phổ đầu vào và đáp ứng tần số :
Tuy nhiên, biểu đồ bên dưới cho thấy bộ lọc thực sự làm tăng một số thành phần tần số thấp - xem cách đường màu đỏ ở trên màu xanh lá cây bên dưới khoảng .
Bất cứ ai có thể giải thích tại sao điều này là?
import numpy as np
from scipy.signal import butter, lfilter, freqz
import matplotlib.pyplot as plt
from scipy.fftpack import fft as fft
def butter_lowpass(cutoff, fs, order=5):
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
b, a = butter(order, normal_cutoff, btype='low', analog=False)
return b, a
def butter_lowpass_filter(data, cutoff, fs, order=5):
b, a = butter_lowpass(cutoff, fs, order=order)
y = lfilter(b, a, data)
return y
# Filter requirements.
order = 6
fs = 30.0 # sample rate, Hz
cutoff = 3.667 # desired cutoff frequency of the filter, Hz
# Get the filter coefficients so we can check its frequency response.
b, a = butter_lowpass(cutoff, fs, order)
# Plot the frequency response.
w, h = freqz(b, a, worN=8000)
plt.subplot(2, 1, 1)
plt.plot(0.5*fs*w/np.pi, np.abs(h), 'b')
plt.plot(cutoff, 0.5*np.sqrt(2), 'ko')
plt.axvline(cutoff, color='k')
plt.xlim(0, 0.5*fs)
plt.title("Lowpass Filter Frequency Response")
plt.xlabel('Frequency [Hz]')
plt.grid()
# Demonstrate the use of the filter.
# First make some data to be filtered.
T = 5.0 # seconds
n = int(T * fs) # total number of samples
t = np.linspace(0, T, n, endpoint=False)
# "Noisy" data. We want to recover the 1.2 Hz signal from this.
data = np.sin(1.2*2*np.pi*t) + 1.5*np.cos(9*2*np.pi*t) + 0.5*np.sin(12.0*2*np.pi*t)
# Filter the data, and plot both the original and filtered signals.
y = butter_lowpass_filter(data, cutoff, fs, order)
plt.subplot(2, 1, 2)
plt.plot(t, data, 'b-', label='data')
plt.plot(t, y, 'g-', linewidth=2, label='filtered data')
plt.xlabel('Time [sec]')
plt.grid()
plt.legend()
plt.subplots_adjust(hspace=0.35)
plt.show()
def calculateFFT(time,signal):
N=len(signal)
df=1/((time[-1]-time[0]))
frequencies=[i*df for i in range(int(N/2.0))]
fftValues = [2.0/N*abs(i) for i in fft(signal,N)[0:N/2.0] ]
return frequencies,fftValues
plt.subplot(2, 1, 1)
originalfreqs,originalFFT=calculateFFT(t,data)
plt.plot(originalfreqs,originalFFT,"g",label="original")
filteredfreqs,filteredFFT=calculateFFT(t,y)
plt.plot(filteredfreqs,filteredFFT,"r",label="filtered")
plt.legend()