scipy.signal에 필터 적용 : lfilter 또는 filtfilt를 사용 하시겠습니까?


21

나는 SO 스레드 에서 filtfilt대신에 뒤로 / 앞으로 필터링을 수행 하는 제안을 보았습니다 lfilter.

다른 기술에 대해 하나를 사용하는 동기는 무엇입니까?


필터 여과가 느림
Aaron


1
@Aaron filtfilt은 반대 방향으로 동일한 필터를 두 번 수행하므로 lfilter한 방향으로 두 번 수행하는 것보다 느리지 않으므로 동일한 주파수 응답을 얻는 방법입니다.
endolith

그래 그게 전부 야 두 배 느립니다.
Aaron

나는 이것에 익숙하지 않고 filtfilt를 사용하려고했습니다. @endolith는 scipy.signal이 원래 신호를 사용한다고 말했다. 원래 신호의 의미와 신호를 얻는 방법을 잘 모르겠습니다. 나는 시스템에로드하는 wav 파일을 가지고 있지만 그것이 numpy 배열과 샘플 수로 나뉘어져 있기 때문에 그것이 원래의 신호라고 생각하지 않습니다. 누군가 도울 수 있다면 부탁드립니다. 고맙습니다!
Arunima Pathania

답변:


30
  • filtfilt제로 위상 필터링은 필터링 할 때 신호를 이동시키지 않습니다. 모든 주파수에서 위상이 0이므로 선형 위상이기도합니다. 시간을 거꾸로 필터링하면 미래를 예측해야하므로 "온라인"실제 응용 프로그램에서는 신호 기록의 오프라인 처리에만 사용할 수 없습니다.

  • lfilter실제 전자 필터와 유사한 인과 적 인 타임 필터링입니다. 영상이 될 수 없습니다. 선형 위상 (대칭 FIR) 일 수 있지만 일반적으로 그렇지 않습니다. 일반적으로 다른 주파수에서 다른 양의 지연을 추가합니다.

예와 이미지는 분명해야합니다. 필터의 주파수 응답의 크기는 동일하지만 (왼쪽 위와 오른쪽 위), 제로 위상 저역 통과는 고주파 성분없이 원래의 신호와 일치하며 최소 위상 필터링은 신호를 인과적인 방식으로 지연시킵니다 :

filtfilt 대 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
lfilter최소 위상 필요는 없다,이 필터 계수에 따라 사용할 수 있지만, 어떤 경우에는 인과 있는 filtfilt아니다. 따라서 filtfilt지연이 0이고 lfilter항상 약간의 지연을 추가 하는 비교 결과는 사실이 아니기 때문에 filtfilt처음에는 원인이 아니기 때문 입니다. 실제로 중요한 것은 filtfilt위상 왜곡을 유발하지 않는 반면 lfilter, 선형 위상 FIR 필터로 사용되지 않는 경우 (즉, 분모 = 1 인 경우)입니다.
Matt L.

N 번째 차수의 filtfilt필터링은 (2N-1) 차수의 필터링에 해당 한다는 점에 주목할 가치가 있습니다 lfilter.
Thomas Arildsen

@ThomasArildsen 2N 아닌가요? 이것이 내가 대본에서 보여준 것입니다
endolith

@ ArunimaPathania 당신은 질문 아래가 아니라 내 대답 아래에 의견을 말해야합니다. "원래 신호"는 필터링하는 신호를 의미합니다. lfilter또는로 필터링 할 수 있습니다 filtfilt. 그림과 같이 그들은 다르게 행동합니다
endolith

7

@endolith 님의 답변이 완전하고 정확합니다! 먼저 그의 게시물을 읽은 다음이 게시물을 읽으십시오. 저의 명성으로 인해 @Thomas Arildsen@endolith가 다음같이 얻은 필터의 효과적인 순서에 대해 논쟁 하는 의견에 응답하지 못했습니다 filtfilt.

  • lfilter 주어진 필터를 적용하고 푸리에 공간에서 이것은 필터 전송 기능 ONCE를 적용하는 것과 같습니다.

  • filtfilt동일한 필터를 두 번 적용하면 효과는 필터 전송 기능 SQUARED를 적용하는 것과 같습니다. scipy.signal.butter전달 기능이있는 버터 워스 필터 ( )의 경우

()=11ω2어디에  필터의 순서

효과적인 이득은

()에프나는에프나는=()2=11ω2

221

()에프나는에프나는(2).

1
답변으로 의견을 추가하지 마십시오. 그러나 SE.DSP에 오신 것을 환영합니다. 나는 이것이 대답에 추가한다고 생각합니다 ... 적어도 충분한 의견을 말하려고 노력하십시오! :-)
Peter K.

나는 이것이 사실이라고 생각하지 않습니다. G (n)은 필터의 진폭 게인입니다. 복잡한 전송 기능을 캐스케이드하면 2n으로 작동한다고 생각합니다.
마이크

나는 6 차 Butterworth가 2x (3 차 Butterworth)와 같은 G (ω)를 제공하지만 3 차의 차단 주파수가 1.6으로 조정 된 것을 빠른 시뮬레이션으로 확인했다. 컷오프 주파수의 스케일링을 제외하고 결과는 동일합니다. 따라서 순서는 2n으로 확장되지만 캐스케이드 할 때 통과 대역이 줄어들고 보상이 필요합니다. 누군가는 이론을 자유롭게 설명 할 수 있지만 모든 수학 과정을 거치고 싶지는 않습니다.
마이크
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.