320x100
320x100
신호 처리를 하다 보면 가장 먼저 접하게 되는 개념이 '푸리에 변환'이다. 이번 글에서는 파이썬의 numpy를 통해 푸리에 변환하는 방법에 대해 정리하고자 한다. 그 전에... 푸리에 변환에 대한 이론적 배경을 정확하게 알고있는 게 아니라 틀린 부분이 있을 수 있다는 점을 미리 밝힙니다!!
푸리에 변환 (Fourier transform)
시간 영역에서 표현되는 신호를 주파수 영역으로 변환하여 다른 관점에서 신호를 분석하는 방법
Python에서 푸리에 변환을 하고 싶으면 np.fft.fft( ) 함수를 아래와 같이 이용하면 된다.
import numpy as np
import matplotlib.pyplot as plt
fs = 100
t = np.arange(0, 3, 1 / fs)
f1 = 35
f2 = 10
signal = 0.6 * np.sin(2 * np.pi * f1 * t) + 3 * np.cos(2 * np.pi * f2 * t + np.pi/2)
fft = np.fft.fft(signal) / len(signal)
fft_magnitude = abs(fft)
- [Line 4~8]
35Hz를 갖는 0.6 진폭의 신호와 10Hz를 갖는 3 진폭 신호를 생성한 뒤,
두 신호를 더하여 설명에 사용할 신호를 생성한다. - [Line 10]
생성된 신호를 np.fft.fft( ) 함수로 푸리에 변환 시킨다.
여기서 중요한 점은,
함수의 반환값 (여기서는 fft 변수에 저장)을 신호의 길이로 나눠줘야 한다는 점!
바꿔말하면 normalization 해줘야하는 다는 건데, 안 해주면 Line 12의 fft_magnitude 값이 엄청 커진다.
그래야 분석 대상 신호를 만들때 설정한 진폭 (각각 0.6 과 3)에 맞춰서 magnitude 그래프가 그려진다.
np.fft.fft( ) 결과에 왜 normalization을 적용해야만 하는지 설명해주는 사이트는 아직 찾지 못 했다. - [Line 12]
푸리에 변환 결과를 통해 우리가 얻을 수 있는 그래프는 두 종류가 있다.
(1) 푸리에 스펙트럼 그래프 : 주파수에 따른 magnitude 그래프
(2) 위상 그래프 : 주파수에 따른 angle 그래프
우리가 원하는 건 magnitude 그래프이고,
이를 얻기 위해선 복소수 타입인 np.fft.fft( ) 함수 반환값에 절대값을 취해주면 된다.
생성된 신호와 푸리에 변환 결과를 표현하면 다음과 같다.
plt.subplot(2,1,1)
plt.plot(t,signal)
plt.grid()
plt.subplot(2,1,2)
plt.stem(fft_magnitude)
plt.ylim(0,2.5)
plt.grid()
plt.show()
뭔가 이상하다. 우리가 생각했던 결과와는 다르게 나타나는 것 같이 보인다. magnitude 값은 뭔가 맞는 것 같으면서도 x축을 보니 너무도 다르다. 그 이유에 알아보자.
- np.fft.fft( )는 반환값을 '양의 영역 다음에 음의 영역 순서'로 반환한다.
그래서 위의 그래프를 기존으로 0~149는 양의 영역 / 150 ~ 299는 음의 영역에 해당되는 값들이다.
우리는 제대로 된 그래프를 얻기 위해선 이를 음 → 양 순서로 바꿔줘야한다. - x축이 이상하게 잡힌 건 Line 6에서 stem 그래프를 그려줄 때 x축을 지정 안 해줬기 때문이다.
우리는 위에서 fs = 100Hz로 잡았기 때문에 x축이 -50Hz ~ 50Hz가 되도록 설정해줘야 한다.
이제 문제 해결을 위해 다음의 코드를 사용하면 된다.
length = len(signal)
f = np.linspace(-(fs / 2), fs / 2, length)
plt.stem(f, np.fft.fftshift(fft_magnitude))
plt.ylim(0,2.5)
plt.grid()
plt.show()
- [Line 1,2]
stem 그래프의 x축을 지정해주는 코드이다. x축 변수를 새로 생성해서 맞춰준다 생각하면 된다.
np.linspace( start, end, num )은 start로 시작해 end까지 num개의 변수를 일정한 간격으로 생성해주는 함수이다.
따라러 변수 f에는 -50 ~ 50까지 일정한 간격으로 생성된 300개의 데이터가 저장된다. - [Line 4]
np.fft.fftshift( )는 위에서 말한 np.fft.fft( ) 반환 값의 순서를 '음 → 양' 으로 변경해주는 함수이다.
최종 결과를 그래프로 표현해보면 다음과 같음.
f : -35, -10, 10, 35 에서 magnitude : 0.3, 1.5, 1.5, 0.3 으로 그려지는 것을 확인할 수 있다. 이 그래프가 위에서 생성한 신호의 최종 푸리에 변환 그래프이다. 만약 양의 영역만 확인하고 싶다면 indexing을 해주면 된다.
「https://pinkwink.kr/708 의 설명을 참고했습니다.」
! 광고 보고 끝 !
728x90
'Python' 카테고리의 다른 글
Python Multiprocessing 작업하며 발생한 이슈들 정리 (3) | 2021.11.04 |
---|---|
Matplotlib을 이용해 그래프 그리기 (0) | 2021.08.31 |
Python으로 DICOM 파일 다루는 방법 (11) | 2021.08.31 |
Python의 fileinput module로 파일 수정하는 방법 (1) | 2021.08.31 |
imgaug 라이브러리 사용 방법 (0) | 2021.08.31 |