Áp dụng bộ lọc trong scipy.signal: Sử dụng bộ lọc hoặc bộ lọc?


21

Tôi thấy trong một luồng SO một đề xuất sử dụng filtfiltđể thực hiện lọc ngược / xuôi thay vì lfilter.

Động lực để sử dụng một so với kỹ thuật khác là gì?


Lọc chậm hơn
Aaron

bản sao có thể có của Ưu điểm của bộ lọc MATLAB là gì
Matt L.

1
@Aaron filtfiltthực hiện cùng một bộ lọc hai lần, theo hai hướng ngược nhau, do đó, không chậm hơn so với thực hiện lfilterhai lần theo một hướng, đó là cách bạn sẽ nhận được cùng một đáp ứng tần số.
endolith

Vâng, đó là tất cả những gì tôi muốn nói. Nó chậm gấp đôi.
Aaron

Tôi chưa quen với điều này và đang tìm kiếm xung quanh để sử dụng bộ lọc. @endolith nói rằng scipy.signal sử dụng tín hiệu gốc. Tôi không chắc tín hiệu ban đầu có nghĩa là gì và làm thế nào chúng ta có được nó. Tôi có một tệp wav mà tôi tải vào hệ thống của mình nhưng tôi không nghĩ đó là tín hiệu ban đầu vì nó được chia thành một mảng gọn gàng và số lượng mẫu. Xin vui lòng nếu ai đó có thể giúp đỡ. Cảm ơn bạn!
Arunima Pathania

Câu trả lời:


30
  • filtfiltlà bộ lọc không pha, không chuyển tín hiệu khi nó lọc. Vì pha bằng 0 ở mọi tần số, nó cũng là pha tuyến tính. Lọc ngược thời gian đòi hỏi bạn phải dự đoán tương lai, vì vậy nó không thể được sử dụng trong các ứng dụng thực tế "trực tuyến", chỉ để xử lý ngoại tuyến các bản ghi tín hiệu.

  • lfilterlà bộ lọc chuyển tiếp theo thời gian nhân quả, tương tự như bộ lọc điện tử thực tế. Nó không thể là pha không. Nó có thể là pha tuyến tính (FIR đối xứng), nhưng thường thì không. Thông thường nó thêm số lượng trễ khác nhau ở các tần số khác nhau.

Một ví dụ và hình ảnh nên làm cho nó rõ ràng. Mặc dù cường độ đáp ứng tần số của các bộ lọc là giống hệt nhau (trên cùng bên trái và trên cùng bên phải), đường thông thấp pha 0 nối với tín hiệu gốc, chỉ không có nội dung tần số cao, trong khi lọc pha tối thiểu làm chậm tín hiệu theo cách nguyên nhân :

bộ lọc vs lfilter

from __future__ import division, print_function
import numpy as np
from numpy.random import randn
from numpy.fft import rfft
from scipy import signal
import matplotlib.pyplot as plt

b, a = signal.butter(4, 0.03, analog=False)

# Show that frequency response is the same
impulse = np.zeros(1000)
impulse[500] = 1

# Applies filter forward and backward in time
imp_ff = signal.filtfilt(b, a, impulse)

# Applies filter forward in time twice (for same frequency response)
imp_lf = signal.lfilter(b, a, signal.lfilter(b, a, impulse))

plt.subplot(2, 2, 1)
plt.semilogx(20*np.log10(np.abs(rfft(imp_lf))))
plt.ylim(-100, 20)
plt.grid(True, which='both')
plt.title('lfilter')

plt.subplot(2, 2, 2)
plt.semilogx(20*np.log10(np.abs(rfft(imp_ff))))
plt.ylim(-100, 20)
plt.grid(True, which='both')
plt.title('filtfilt')

sig = np.cumsum(randn(800))  # Brownian noise
sig_ff = signal.filtfilt(b, a, sig)
sig_lf = signal.lfilter(b, a, signal.lfilter(b, a, sig))
plt.subplot(2, 1, 2)
plt.plot(sig, color='silver', label='Original')
plt.plot(sig_ff, color='#3465a4', label='filtfilt')
plt.plot(sig_lf, color='#cc0000', label='lfilter')
plt.grid(True, which='both')
plt.legend(loc="best")

4
lfilterkhông nhất thiết là pha tối thiểu, nó có thể là bất cứ thứ gì tùy thuộc vào hệ số bộ lọc, nhưng trong mọi trường hợp, đó là nguyên nhân , điều filtfiltnày không phải. Vì vậy, kết quả của việc so sánh filtfiltcó độ trễ bằng 0 và lfilterluôn thêm một số độ trễ là không chính xác, bởi vì filtfiltnó không có nguyên nhân ở vị trí đầu tiên. Điều thực sự quan trọng là filtfiltnó không gây ra bất kỳ biến dạng pha nào, trong khi lfilterđó (trừ khi nó được sử dụng làm bộ lọc FIR pha tuyến tính, tức là với mẫu số = 1).
Matt L.

Cũng cần lưu ý rằng việc lọc thứ tự Nth filtfilttương ứng với việc lọc theo thứ tự (2N-1) với lfilter.
Thomas Arildsen

@ThomasArildsen Không phải chỉ là 2N sao? Đó là những gì tôi đã thể hiện trong kịch bản
endolith

@ArunimaPathania Bạn nên bình luận dưới câu trả lời của tôi, không phải dưới câu hỏi. "Tín hiệu gốc" chỉ có nghĩa là tín hiệu bạn đang lọc. Bạn có thể lọc với một trong hai lfilterhoặc filtfilt. Họ cư xử khác nhau, như được hiển thị
endolith

7

Trả lời bởi @endolith là đầy đủ và chính xác! Xin vui lòng đọc bài viết của mình đầu tiên, và sau đó bài này ngoài nó. Do uy tín thấp của tôi, tôi không thể trả lời các bình luận trong đó @Thomas Arildsen@endolith tranh luận về thứ tự hiệu quả của bộ lọc thu được bởi filtfilt:

  • lfilter không áp dụng bộ lọc đã cho và trong không gian Fourier, điều này giống như áp dụng chức năng truyền bộ lọc ONCE.

  • filtfiltáp dụng cùng một bộ lọc hai lần và hiệu quả giống như áp dụng chức năng chuyển bộ lọc SQUARED. Trong trường hợp bộ lọc Butterworth (scipy.signal.butter ) có chức năng chuyển

G(n)=11ω2nwhere n is order of filter

lợi ích hiệu quả sẽ là

G(n)filtfilt=G(n)2=11ω2n

2n2n1

G(n)filtfiltG(2n).

1
Hãy cố gắng không thêm ý kiến ​​như câu trả lời. Tuy nhiên, chào mừng bạn đến với SE.DSP và có +1 từ tôi. Tôi nghĩ rằng điều này thêm vào câu trả lời ... ít nhất là cố gắng để có đủ đại diện để bình luận! :-)
Peter K.

Tôi không nghĩ điều này là đúng. G (n) là mức tăng biên độ của bộ lọc. Nếu bạn xếp tầng chức năng chuyển phức tạp, tôi nghĩ nó sẽ hoạt động đến 2n.
Mike

Tôi đã xác nhận với một mô phỏng nhanh rằng aa bậc 6 Butterworth cho cùng một G (ω) là 2 x (bậc 3 Butterworth) xếp tầng nhưng với tần số cắt của bậc 3 được nhân lên 1.6. Các kết quả là giống hệt nhau ngoại trừ việc thu nhỏ tần số cắt. Vì vậy, thứ tự không chia tỷ lệ với 2n, nhưng lưu ý rằng băng thông sẽ giảm khi bạn xếp tầng và cần phải được bù. Ai đó cảm thấy thoải mái để giải thích lý thuyết nhưng tôi không thực sự muốn trải qua tất cả các toán học.
Mike
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.