Main Content

푸리에 변환(Fourier Transform)

푸리에 변환은 시간이나 공간에서 샘플링된 신호를 시간 주파수 또는 공간 주파수에서 샘플링된 동일한 신호로 변환하는 수학적 공식입니다. 신호 처리에서 푸리에 변환은 신호의 중요한 특성, 즉 주파수 성분을 나타낼 수 있습니다.

푸리에 변환은 n개의 균일하게 샘플링된 점을 갖는 벡터 x에 대해 다음과 같이 정의됩니다.

yk+1=j=0n-1ωjkxj+1.

ω=e-2πi/nn개의 복소 단위근 중 하나입니다. 여기서 i는 허수 단위입니다. xy에 대해, 인덱스 jk의 범위는 0에서 n-1 사이입니다.

MATLAB®의 fft 함수는 고속 푸리에 변환 알고리즘을 사용하여 데이터의 푸리에 변환을 계산합니다. 15Hz와 20Hz의 주파수 성분을 가지며, 시간 t에 대한 함수인 정현파 신호 x가 있다고 가정하겠습니다. 10초의 기간 동안 1/50초 단위로 샘플링된 시간 벡터를 사용합니다.

Ts = 1/50;
t = 0:Ts:10-Ts;
x = sin(2*pi*15*t) + sin(2*pi*20*t);
plot(t,x)
xlabel('Time (seconds)')
ylabel('Amplitude')

Figure contains an axes object. The axes object with xlabel Time (seconds), ylabel Amplitude contains an object of type line.

신호의 푸리에 변환을 계산하고, 주파수 영역에서의 신호의 샘플링에 대응하는 벡터 f를 생성합니다.

y = fft(x);
fs = 1/Ts;
f = (0:length(y)-1)*fs/length(y);

신호의 크기를 주파수의 함수로 플로팅할 경우, 크기에서의 스파이크는 신호의 주파수 성분 15Hz와 20Hz에 해당합니다.

plot(f,abs(y))
xlabel('Frequency (Hz)')
ylabel('Magnitude')
title('Magnitude')

Figure contains an axes object. The axes object with title Magnitude, xlabel Frequency (Hz), ylabel Magnitude contains an object of type line.

푸리에 변환은 또한 신호의 음수 주파수에 해당하는 스파이크의 대칭 복사본을 생성합니다. 이 주기성을 더 잘 시각화하기 위해 fftshift 함수를 사용할 수 있습니다. 이 함수는 푸리에 변환에서 0을 중심으로 원형 이동을 수행합니다.

n = length(x);
fshift = (-n/2:n/2-1)*(fs/n);
yshift = fftshift(y);
plot(fshift,abs(yshift))
xlabel('Frequency (Hz)')
ylabel('Magnitude')

Figure contains an axes object. The axes object with xlabel Frequency (Hz), ylabel Magnitude contains an object of type line.

잡음이 있는 신호

과학 응용 분야에서 신호는 종종 신호의 주파수 성분으로 착각하기 쉬운 랜덤 잡음으로 인해 손상됩니다. 푸리에 변환은 랜덤 잡음을 처리하고 주파수를 나타낼 수 있습니다. 예를 들어, 원래 신호 x에 가우스 잡음을 넣어 새 신호 xnoise를 만들어 보겠습니다.

rng('default')
xnoise = x + 2.5*randn(size(t));

주파수의 함수로 나타낸 신호 전력은 신호 처리에서 흔히 사용되는 메트릭입니다. 전력은 신호의 푸리에 변환의 크기 제곱이며, 주파수 샘플 개수를 기준으로 정규화됩니다. 잡음이 있는 신호의 파워 스펙트럼을 계산하고 영주파수를 중심으로 플로팅합니다. 잡음이 있지만, 전력의 스파이크 때문에 신호의 주파수를 알아볼 수 있습니다.

ynoise = fft(xnoise);
ynoiseshift = fftshift(ynoise);
power = abs(ynoiseshift).^2/n; 
plot(fshift,power)
title('Power')
xlabel('Frequency (Hz)')
ylabel('Power')

Figure contains an axes object. The axes object with title Power, xlabel Frequency (Hz), ylabel Power contains an object of type line.

계산 효율성

yn개 성분을 각각 계산하는 데 푸리에 변환 공식을 직접 사용하려면 n2에 가까운 부동소수점 연산이 필요합니다. 고속 푸리에 변환 알고리즘의 경우에는 계산하는 데 n log n 수준의 연산만 필요합니다. 이러한 계산 효율성은 수백만 개의 데이터 점을 갖는 데이터를 처리할 때 큰 이점이 됩니다. 고속 푸리에 변환 알고리즘에 대한 여러 특화된 구현은 n이 2의 거듭제곱일 때 등 n이 작은 소인수일 때 훨씬 더 효율적입니다.

캘리포니아 연안에서 수중 마이크로 수집한 오디오 데이터를 예로 들어 보겠습니다. 이 데이터는 코넬대 생물 음향학 연구 프로그램(Cornell University Bioacoustics Research Program)에서 관리하는 라이브러리에서 찾아볼 수 있습니다. 태평양 흰긴수염고래 소리가 포함된 bluewhale.au의 데이터 일부를 불러오고 형식을 지정하겠습니다. 흰긴수염고래 울음소리는 주파수가 낮기 때문에 사람에게는 거의 들리지 않습니다. 피치를 올려서 울음소리가 더 명확하게 들리도록 데이터의 시간 스케일을 1/10로 압축했습니다. sound(x,fs) 명령을 사용하여 전체 오디오 파일을 청취할 수 있습니다.

whaleFile = 'bluewhale.au';
[x,fs] = audioread(whaleFile);
whaleMoan = x(2.45e4:3.10e4);
t = 10*(0:1/fs:(length(whaleMoan)-1)/fs);

plot(t,whaleMoan)
xlabel('Time (seconds)')
ylabel('Amplitude')
xlim([0 t(end)])

Figure contains an axes object. The axes object with xlabel Time (seconds), ylabel Amplitude contains an object of type line.

원래 길이보다 큰 첫 번째 2의 거듭제곱이 되도록 새 신호 길이를 지정합니다. 그런 다음 fft를 사용하여 새 신호 길이에 대한 푸리에 변환을 계산합니다. fft는 데이터를 0으로 자동으로 채워서 샘플 크기를 늘립니다. 이러한 채우기 동작은 특히 큰 소인수로 구성된 샘플 크기의 경우 변환의 계산 속도를 크게 향상시킬 수 있습니다.

m = length(whaleMoan);
n = pow2(nextpow2(m));
y = fft(whaleMoan,n);

신호의 파워 스펙트럼을 플로팅합니다. 이 플롯은 긴 울음소리가 약 17Hz의 기본주파수와 일련의 고조파로 구성되어 있고, 두 번째 고조파가 두드러져 있음을 나타냅니다.

f = (0:n-1)*(fs/n)/10; % frequency vector
power = abs(y).^2/n;   % power spectrum
plot(f(1:floor(n/2)),power(1:floor(n/2)))
xlabel('Frequency (Hz)')
ylabel('Power')

Figure contains an axes object. The axes object with xlabel Frequency (Hz), ylabel Power contains an object of type line.

정현파의 위상

푸리에 변환을 사용하여 원래 신호에서 위상 스펙트럼을 추출할 수도 있습니다. 예를 들어 주파수 15Hz 및 40Hz의 두 정현파로 구성된 신호를 만들어 보겠습니다. 첫 번째 정현파는 위상 -π/4를 갖는 코사인파이고 두 번째 정현파는 위상 π/2를 갖는 코사인파입니다. 1초간 100Hz에서 신호를 샘플링합니다.

fs = 100;
t = 0:1/fs:1-1/fs;
x = cos(2*pi*15*t - pi/4) - sin(2*pi*40*t);

신호의 푸리에 변환을 계산합니다. 변환의 크기를 주파수의 함수로 플로팅합니다.

y = fft(x);
z = fftshift(y);

ly = length(y);
f = (-ly/2:ly/2-1)/ly*fs;

stem(f,abs(z))
xlabel("Frequency (Hz)")
ylabel("|y|")
grid

Figure contains an axes object. The axes object with xlabel Frequency (Hz), ylabel |y| contains an object of type stem.

크기가 작은 변환 값을 제거하여 변환 위상을 계산합니다. 위상을 주파수의 함수로 플로팅합니다.

tol = 1e-6;
z(abs(z) < tol) = 0;

theta = angle(z);

stem(f,theta/pi)
xlabel("Frequency (Hz)")
ylabel("Phase / \pi")
grid

Figure contains an axes object. The axes object with xlabel Frequency (Hz), ylabel Phase / blank pi contains an object of type stem.

참고 항목

| | | | | |

관련 항목

외부 웹사이트