본문 바로가기
Python Library/SciPy

[SciPy] 영 위상 필터 (Zero-Phase Filter)

by goatlab 2023. 7. 10.
728x90
반응형
SMALL

영 위상 필터 (Zero-Phase Filter)

 

영 위상 필터 (Zero-Phase Filter)는 신호 처리에서 사용되는 필터 중 하나이다. 이 필터는 신호를 두 번 처리하여 위상 지연을 제거하는 방법으로 작동한다. 영 위상 필터는 전체적인 신호의 위상을 유지하면서 주파수 응답을 변형시키는 필터이다. 이 필터는 주로 신호 처리에서 사용되며, 신호의 위상이 중요한 경우에 사용된다.

 

Scipy에서의 기능은 선형 디지털 필터를 앞으로 한 번, 뒤로 한 번 총 두 번 적용한다. 결합된 필터는 위상이 0이고 필터 차수가 원본의 두 배이다.

 

이 기능는 2차 섹션에서 숫자 문제가 적기 때문에 대부분의 필터링 작업에서 sosflitflit (output='filter'를 사용한 필터 설계) 필터링 기능이 flitflit 필터링보다 선호되어야 한다.

 

예제

 

먼저 주파수가 5Hz와 250Hz이고 2000Hz로 샘플링된 두 개의 사인파의 합인 1초 신호를 생성한다.

 

import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

t = np.linspace(0, 1.0, 2001)
xlow = np.sin(2 * np.pi * 5 * t)
xhigh = np.sin(2 * np.pi * 250 * t)
x = xlow + xhigh

 

이제 나이키스트 주파수 (125Hz)의 0.125배의 cutoff로 저역 통과 버터워스 필터를 만들어 필터 필터를 사용하여 x에 적용한다. 결과는 위상 편이 없이 대략 xlow여야 한다.

 

b, a = signal.butter(8, 0.125)
y = signal.filtfilt(b, a, x, padlen=150)
np.abs(y - xlow).max()
9.108629580020788e-06

 

홀수 확장이 정확하고 적당히 긴 패딩으로 필터의 과도현상이 실제 데이터에 도달할 때까지 소멸되었기 때문에 이 예제에 대해 상당히 깨끗한 결과를 얻는다. 일반적으로 edge에서의 과도 효과는 피할 수 없다.

b, a = signal.ellip(4, 0.01, 120, 0.125)  # Filter to be applied.

 

sig는 필터링할 임의의 입력 신호이다.

 

rng = np.random.default_rng()
n = 60
sig = rng.standard_normal(n)**3 + 3*rng.standard_normal(n).cumsum()

 

Gustafsson 방법을 사용하여 한 번, 패딩을 사용하여 한 번, sig에 필터를 적용하고 비교 결과를 그림으로 표시한다.

 

fgust = signal.filtfilt(b, a, sig, method="gust")
fpad = signal.filtfilt(b, a, sig, padlen=50)
plt.plot(sig, 'k-', label='input')
plt.plot(fgust, 'b-', linewidth=4, label='gust')
plt.plot(fpad, 'c-', linewidth=1.5, label='pad')
plt.legend(loc='best')
plt.show()

 

irlen 증명은 Gustafsson 방법의 성능을 향상시키는 데 사용될 수 있다. 그 다음, 필터의 임펄스 응답 길이를 추정한다.

 

z, p, k = signal.tf2zpk(b, a)
eps = 1e-9
r = np.max(np.abs(p))
approx_impulse_len = int(np.ceil(np.log(eps) / np.log(r)))
approx_impulse_len

 

irlen 증명을 사용하거나 사용하지 않고 더 긴 신호에 필터를 적용한다. y1과 y2의 차이는 작다. 긴 신호의 경우 irlen을 사용하면 성능이 크게 향상된다.

 

x = rng.standard_normal(4000)
y1 = signal.filtfilt(b, a, x, method='gust')
y2 = signal.filtfilt(b, a, x, method='gust', irlen=approx_impulse_len)
print(np.max(np.abs(y1 - y2)))

 

https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.filtfilt.html#scipy.signal.filtfilt

 

scipy.signal.filtfilt — SciPy v1.11.1 Manual

[1] F. Gustaffson, “Determining the initial states in forward-backward filtering”, Transactions on Signal Processing, Vol. 46, pp. 988-992, 1996.

docs.scipy.org

 

728x90
반응형
LIST

'Python Library > SciPy' 카테고리의 다른 글

[SciPy] 사비츠키-골레이 필터 (Savitzky-Golay Filter)  (0) 2023.08.03
[SciPy] B-spline  (0) 2023.07.31
[SciPy] 버터워스 필터 (Butterworth Filter)  (0) 2023.07.05
[SciPy] Special functions  (0) 2022.12.22
[SciPy] Introduction  (0) 2022.12.22