Python SciPy

SciPy를 활용한 필터 설계 및 적용 (butter, filtfilt)

PyExplorer 2025. 3. 11. 08:59
728x90

SciPy를 활용한 필터 설계 및 적용 (butter, filtfilt)

1. 개요

디지털 신호 처리에서는 노이즈 제거, 특정 주파수 대역의 강조 또는 차단과 같은 목적으로 필터를 설계하고 적용하는 과정이 중요합니다. SciPy의 scipy.signal 모듈은 이러한 작업을 간편하게 수행할 수 있도록 다양한 필터 설계 및 적용 도구를 제공합니다.

이번 포스팅에서는 Butterworth 필터를 중심으로 저역 통과(low-pass), 고역 통과(high-pass), 대역 통과(band-pass), 대역 차단(band-stop) 필터를 설계하고 filtfilt 함수를 활용하여 신호에 적용하는 방법을 살펴보겠습니다.


2. Butterworth 필터란?

Butterworth 필터는 통과 대역에서 평탄한 주파수 응답을 갖는 필터입니다. 다른 필터들과 비교했을 때 급격한 전이 특성은 없지만, 신호의 왜곡을 최소화하면서 안정적인 성능을 제공합니다.

Butterworth 필터는 다음과 같은 특징을 갖습니다.

  • 통과 대역에서 주파수 응답이 매우 평탄하다.
  • 위상 왜곡이 비교적 적다.
  • 차단 대역에서 선형적으로 감쇠된다.

이러한 특징 덕분에 오디오, 바이오메디컬 신호 처리 등 다양한 분야에서 널리 사용됩니다.


3. SciPy에서 필터 설계하기

SciPy의 scipy.signal.butter 함수를 이용하면 Butterworth 필터를 간단하게 설계할 수 있습니다. butter 함수는 다음과 같이 사용됩니다.

from scipy.signal import butter

b, a = butter(N, Wn, btype='low', analog=False, output='ba')
  • N: 필터의 차수(Order)를 의미합니다. 값이 클수록 필터의 성능이 향상되지만 위상 왜곡이 증가할 수 있습니다.
  • Wn: 차단 주파수(Normalized frequency)입니다. 일반적으로 0과 1 사이의 값으로 설정합니다.
  • btype: 필터의 종류를 지정합니다. ('low', 'high', 'bandpass', 'bandstop')
  • analog: 아날로그 필터 여부를 결정합니다. 디지털 필터를 사용하는 경우 False로 설정합니다.
  • output: 출력 형식을 결정합니다. 기본적으로 분자와 분모 계수(ba)로 반환됩니다.

4. 필터 적용하기 (filtfilt)

필터를 설계한 후에는 scipy.signal.filtfilt 함수를 활용하여 실제 신호에 적용할 수 있습니다. filtfilt는 신호를 전방향과 역방향으로 두 번 필터링하는 방식으로, 위상 왜곡을 최소화하는 장점이 있습니다.

from scipy.signal import filtfilt

filtered_signal = filtfilt(b, a, signal)
  • b, a: 필터 계수입니다.
  • signal: 필터링할 원본 신호입니다.
  • filtered_signal: 필터가 적용된 결과 신호입니다.

filtfilt는 신호의 위상을 유지하면서도 필터링 효과를 적용할 수 있어 많은 신호 처리 작업에서 선호됩니다.


5. 예제: 노이즈가 포함된 신호 필터링

아래는 노이즈가 포함된 사인파 신호에 저역 통과 필터를 적용하는 예제입니다.

(1) 예제 코드

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, filtfilt

# 샘플링 주파수와 시간 설정
fs = 1000  # Hz
t = np.linspace(0, 1.0, int(fs), endpoint=False)

# 원본 신호 (10Hz 사인파)
signal = np.sin(2 * np.pi * 10 * t)

# 노이즈 추가
noise = 0.5 * np.random.normal(size=t.shape)
noisy_signal = signal + noise

# 저역 통과 필터 설계
cutoff = 20  # 차단 주파수 (Hz)
nyquist = 0.5 * fs
normal_cutoff = cutoff / nyquist
b, a = butter(4, normal_cutoff, btype='low', analog=False)

# 필터 적용
filtered_signal = filtfilt(b, a, noisy_signal)

# 결과 시각화
plt.figure(figsize=(12, 8))
plt.plot(t, noisy_signal, label='노이즈가 포함된 신호', alpha=0.6)
plt.plot(t, signal, label='원본 신호', linestyle='dashed')
plt.plot(t, filtered_signal, label='필터 적용 후 신호', linewidth=2)
plt.xlabel('시간 [초]')
plt.ylabel('진폭')
plt.legend(loc='upper right')
plt.grid(True)
plt.title('Butterworth 저역 통과 필터 적용 예제')
plt.show()

(2) 코드 설명

  1. 신호 생성: 10Hz 사인파에 랜덤 노이즈를 추가하여 신호를 생성합니다.
  2. 필터 설계: 차단 주파수가 20Hz인 4차 저역 통과 필터를 설계합니다.
  3. 필터 적용: filtfilt 함수를 사용해 필터를 적용하고, 위상 왜곡 없는 결과를 얻습니다.
  4. 시각화: 필터 적용 전후의 신호를 비교합니다.

(3) 결과 분석

결과 그래프를 살펴보면, 노이즈가 포함된 신호에 비해 필터링된 신호는 원본 사인파와 훨씬 더 유사해진 것을 확인할 수 있습니다. 이는 Butterworth 필터가 신호의 주요 구성 요소를 보존하면서 노이즈를 효과적으로 제거했음을 보여줍니다.


6. 다양한 필터 적용 방법

(1) 고역 통과 필터

고역 통과 필터는 특정 주파수 이상의 성분만 통과시키는 필터입니다.

# 고역 통과 필터 설계 (30Hz 이상 통과)
high_cutoff = 30
normal_high_cutoff = high_cutoff / nyquist
b, a = butter(4, normal_high_cutoff, btype='high', analog=False)
high_passed_signal = filtfilt(b, a, noisy_signal)

(2) 대역 통과 필터

특정 주파수 범위만 통과시키는 필터입니다.

# 대역 통과 필터 설계 (10Hz ~ 30Hz)
band_low = 10
band_high = 30
normal_band = [band_low / nyquist, band_high / nyquist]
b, a = butter(4, normal_band, btype='band', analog=False)
band_passed_signal = filtfilt(b, a, noisy_signal)

(3) 대역 차단 필터

특정 주파수 범위를 차단하는 필터입니다.

# 대역 차단 필터 설계 (20Hz ~ 40Hz 차단)
stop_low = 20
stop_high = 40
normal_stop = [stop_low / nyquist, stop_high / nyquist]
b, a = butter(4, normal_stop, btype='bandstop', analog=False)
band_stopped_signal = filtfilt(b, a, noisy_signal)

7. 실전 응용 사례

  1. 생체 신호 처리: 심전도(ECG) 신호에서 노이즈를 제거하거나 특정 주파수 성분만 분석할 때 활용됩니다.
  2. 오디오 신호 처리: 오디오 파일에서 불필요한 잡음을 제거하거나 특정 주파수를 강조하는 데 사용됩니다.
  3. 환경 데이터 분석: 환경 센서에서 수집된 데이터에서 신호의 급격한 변화나 이상치를 감지할 때 필터링 기법이 유용합니다.

8. 결론

SciPy의 signal.butterfiltfilt 함수는 디지털 신호 처리에서 필터 설계와 적용을 간편하게 수행할 수 있도록 도와줍니다. Butterworth 필터는 평탄한 응답과 위상 왜곡 최소화라는 장점을 제공하여, 다양한 신호 처리 분야에서 널리 사용되고 있습니다.

실제 프로젝트에서 노이즈를 제거하거나 특정 주파수 대역을 분석해야 할 때, 본 포스팅에서 소개한 방법을 활용해보시기 바랍니다.


9. 참고 자료

  1. SciPy 공식 문서: scipy.signal
  2. Oppenheim, A. V., & Schafer, R. W. (2009). "Discrete-Time Signal Processing."
728x90