27.푸리에 변환, 신호 분석과 푸리에 급수 개념

신호 분석의 기본적인 도구 중 하나는 푸리에 변환(Fourier Transform)입니다. 푸리에 변환은 신호를 주파수 도메인으로 변환하여 신호의 주파수 성분을 분석할 수 있게 해줍니다. 이를 통해 복잡한 신호의 구조를 이해하고, 주요 주파수 성분을 추출할 수 있습니다. 푸리에 급수(Fourier Series)는 주기적인 신호를 대칭적으로 표현하는 방법으로, 푸리에 변환의 기초가 되는 개념입니다. 이 글에서는 푸리에 변환, 푸리에 급수의 개념에 대해 자세히 설명하고, 관련 예제와 적용 사례를 살펴봅니다.

1. 푸리에 급수

푸리에 급수는 주기적인 신호를 주파수 성분으로 분해하는 방법입니다. 임의의 주기 함수 \( f(t) \)가 주어졌을 때, 이 함수는 다음과 같은 형태로 근사화될 수 있습니다.

f(t) = a_0 + \sum_{n=1}^{\infty} \left( a_n \cos\left(\frac{2\pi nt}{T}\right) + b_n \sin\left(\frac{2\pi nt}{T}\right) \right)

여기서 \( T \)는 함수의 주기이며, \( a_n \)과 \( b_n \)는 각 주파수 성분에 대한 계수입니다. 이 계수들은 다음과 같이 정의됩니다:

a_0 = \frac{1}{T} \int_0^T f(t) dt

a_n = \frac{2}{T} \int_0^T f(t) \cos\left(\frac{2\pi nt}{T}\right) dt

b_n = \frac{2}{T} \int_0^T f(t) \sin\left(\frac{2\pi nt}{T}\right) dt

1.1 예제: 정현파 함수의 푸리에 급수

예를 들어, 아래와 같은 정현파 함수 \( f(t) = A \sin\left(\frac{2\pi t}{T}\right) \)의 푸리에 급수를 구해봅시다.

# Python 코드 예제
import numpy as np
import matplotlib.pyplot as plt

# 매개변수 설정
A = 1       # 진폭
T = 2       # 주기
t = np.linspace(0, 4*T, 1000) # 시간 벡터

# 정현파 함수 정의
f = A * np.sin(2 * np.pi * t / T)

# 푸리에 급수 계산
a0 = (1/T) * np.trapz(f, t)
an = []
bn = []

for n in range(1, 6):  # n=1부터 5까지
    an.append((2/T) * np.trapz(f * np.cos(2 * np.pi * n * t / T), t))
    bn.append((2/T) * np.trapz(f * np.sin(2 * np.pi * n * t / T), t))

# 결과 출력
print("a0 =", a0)
for n in range(5):
    print(f"a{n+1} =", an[n])
    print(f"b{n+1} =", bn[n])

# 원래 함수와 푸리에 급수 그래프 표시
plt.figure(figsize=(12, 6))
plt.plot(t, f, label='원래 함수 f(t)', color='blue')

# 푸리에 급수 항 계산
F_approx = a0
for n in range(5):
    F_approx += an[n] * np.cos(2 * np.pi * (n + 1) * t / T) + bn[n] * np.sin(2 * np.pi * (n + 1) * t / T)

plt.plot(t, F_approx, label='푸리에 급수 근사', color='red', linestyle='--')
plt.title('푸리에 급수 근사')
plt.xlabel('시간 (t)')
plt.ylabel('신호 (f(t))')
plt.legend()
plt.grid()
plt.show()

2. 푸리에 변환

푸리에 변환은 비주기 신호와 같은 주파수 성분을 분석하기 위한 방법입니다. 주기적인 신호와 달리, 비주기 신호는 무한한 주파수 성분으로 구성되어 있습니다. 따라서 푸리에 변환은 신호를 주파수 도메인으로 변환하여 이를 분석하는 도구로 활용됩니다.

수학적으로, 연속 신호 \( f(t) \)의 푸리에 변환 \( F(\omega) \)는 다음과 같이 정의됩니다.

F(\omega) = \int_{-\infty}^{\infty} f(t) e^{-i\omega t} dt

여기서 \( \omega \)는 각 주파수입니다. 푸리에 변환의 역변환은 다음과 같이 주어집니다.

f(t) = \frac{1}{2\pi} \int_{-\infty}^{\infty} F(\omega) e^{i\omega t} d\omega

2.1 예제: 푸리에 변환 계산

다음은 비주기 신호의 푸리에 변환을 계산하는 예제입니다.

# Python 코드 예제: 신호의 푸리에 변환
from scipy.fft import fft, fftfreq

# 신호 매개변수
Fs = 500  # 샘플링 주파수
T = 1/Fs  # 샘플링 간격
L = 1000  # 신호의 길이
t = np.linspace(0.0, L*T, L, endpoint=False)  # 시간 벡터

# 신호: 두 개의 주파수를 합성
f1 = 50  # 첫 번째 주파수
f2 = 120 # 두 번째 주파수
signal = 0.7 * np.sin(2 * np.pi * f1 * t) + 0.5 * np.sin(2 * np.pi * f2 * t)

# 푸리에 변환 수행
yf = fft(signal)
xf = fftfreq(L, T)[:L//2]

# 결과 그래프 표시
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
plt.plot(t, signal)
plt.title('신호')
plt.xlabel('시간 (t)')
plt.ylabel('신호 값')

plt.subplot(2, 1, 2)
plt.plot(xf, 2.0/L * np.abs(yf[:L//2]))
plt.title('푸리에 변환')
plt.xlabel('주파수 (Hz)')
plt.ylabel('진폭')
plt.grid()
plt.tight_layout()
plt.show()

3. 푸리에 변환과 신호 처리

푸리에 변환은 신호 처리, 데이터 압축, 이미지 처리 등 다양한 분야에서 활용됩니다. 예제로 오디오 신호의 분석이나 이미지의 필터링을 통해 푸리에 변환의 응용을 살펴보겠습니다.

3.1 오디오 신호 분석

오디오 신호는 여러 주파수 성분으로 구성되어 있습니다. 푸리에 변환을 이용하여 개별 주파수 성분의 크기를 분석할 수 있습니다. 이러한 분석 결과는 노이즈 제거, 이펙트 추가와 같은 오디오 신호 처리에 활용됩니다.

# 오디오 신호 분석 예제 (정현파)
from scipy.io import wavfile

# WAV 파일 읽기
sample_rate, data = wavfile.read('sample_audio.wav')
duration = data.shape[0] / sample_rate
time = np.linspace(0., duration, data.shape[0])

# 푸리에 변환
yf_audio = fft(data)
xf_audio = fftfreq(len(data), 1/sample_rate)

# 결과 그래프
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.plot(time, data)
plt.title('오디오 신호')
plt.xlabel('시간 (s)')
plt.ylabel('진폭')

plt.subplot(2, 1, 2)
plt.plot(xf_audio, 2.0/len(data) * np.abs(yf_audio))
plt.title('푸리에 변환 - 오디오 신호')
plt.xlabel('주파수 (Hz)')
plt.ylabel('진폭')
plt.xlim(0, 1000)  # 구간 제한
plt.grid()
plt.tight_layout()
plt.show()

3.2 이미지 처리

이미지는 픽셀로 구성된 2차원 신호입니다. 푸리에 변환을 사용하면 이미지의 주파수 성분을 분석하고, 필터링 기법을 적용하여 이미지를 개선할 수 있습니다. 예를 들어, 고주파 성분을 제거하여 노이즈를 줄이거나, 저주파 성분을 강조하여 이미지의 윤곽을 부각시킬 수 있습니다.

# 이미지 처리: 푸리에 변환 예제
from skimage import io, color

# 이미지 읽기
image = color.rgb2gray(io.imread('sample_image.jpg'))

# 푸리에 변환
F = np.fft.fft2(image)
F_shift = np.fft.fftshift(F)

# magnitude spectrum
magnitude_spectrum = np.log(np.abs(F_shift) + 1)

# 결과 표시
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('원본 이미지')
plt.axis('off')

plt.subplot(1, 2, 2)
plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('푸리에 변환의 진폭 스펙트럼')
plt.axis('off')

plt.tight_layout()
plt.show()

4. 결론

푸리에 변환과 푸리에 급수는 신호 분석의 강력한 도구로, 주기적 및 비주기적 신호를 분석하는 데에 필수적입니다. 이를 통해 신호의 주파수 성분을 효과적으로 이해하고, 다양한 응용 분야에서 활용할 수 있습니다. 신호 처리의 기초적인 원리를 이해하는 것은 음향, 이미지, 통신 등 여러 분야에서 중요한 밑바탕이 됩니다. 앞으로 푸리에 분석 기법이 더욱 발전하여 다양한 실생활 문제를 해결할 수 있기를 기대합니다.