MATLABを用いて信号処理の基礎の基礎

信号を読んで, 可視化して, FFTして, フィルターして, 逆FFTして, 可視化する.

研究室でフーリエ変換を教えるために作った教育用のコード. MATLABの公式のFFT関数の説明に少し書き足した感じ.

コード

使う信号

MATLABにデフォルトで入っている gong.mat という信号を使う. 信号 y と サンプリングレート Fs がロードされる. ちなみに, sound(y, Fs) で音を聞ける. ゴングの音かな.

name
MATLAB
load gong.mat
t = (0:length(y)-1)/Fs;
d = y; % 特に意味は無いが, dという名前に変えた
plot(t, d); xlabel('time [sec]'); ylabel('amp [?]')
ylim([-1.5, 1.5])
axis tight

信号の切り抜き

$t_1 = 1$ [sec] から $t_2 = 2$ [sec] を抜き出して可視化してみる.

name
MATLAB
%%%% t1とt2を入力 %%%% 
t1 = 1; t2 = 2;  
%%%%%%%%%%%%%%%%%%%%%
isIn = (t1 < t) & (t < t2);
dp = d(isIn); % data partially のつもり
tp = t(isIn); % time partially のつもり
plot(tp, dp); xlabel('time [sec]'); ylabel('amp [?]')

FFTをかける

本家の解説 に基づいて作成.

name
MATLAB
L = length(dp);
Y = fft(dp);
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = Fs*(0:(L/2))/L;
plot(f, P1)
% plot(f, P1) % logをとると見やすい. 必要ならコメントアウト.
xlabel('f (Hz)')
ylabel('|P1(f)|')
axis tight

band-pass フィルター

$f_1 - f_2$ [Hz] を残してフィルタリング ( band-pass フィルター ).

name
MATLAB
%%%% f1とf2を入力 %%%%
f1 = 500; f2 = 1500;  
%%%%%%%%%%%%%%%%%%%%%

isOmit = ~((f1 < f) & (f < f2));
Y_filtered = Y;
% 左側をフィルタ
tmp = Y_filtered(1:length(isOmit));
tmp(isOmit) = 0;
Y_filtered(1:length(isOmit)) = tmp;
% 右側をフィルタ
isOmit = fliplr(isOmit);
tmp = Y_filtered(end-length(isOmit)+1:end);
tmp(isOmit) = 0;
Y_filtered(end-length(isOmit)+1:end) = tmp;
% フィルタ後を可視化
plot(abs(Y_filtered))
xlabel('f (Hz)')
ylabel('|P1(f)|')
axis tight

逆FFT

逆FFTして ( ifft ) , フィルタの効果をみる.

name
MATLAB
d_filtered = real(ifft(Y_filtered));
t = tiledlayout(2, 1); t.Padding = 'compact'; t.TileSpacing = 'compact';
nexttile
	plot(tp, dp); 
	xlabel('time [sec]'); ylabel('amp [?]'); legend('before filter', box='off')
nexttile
	plot(tp, d_filtered); 
	xlabel('time [sec]'); ylabel('amp [?]'); legend('after filter', box='off')

よわからないけど, 拡大するとなめらかになっているかも.

name
MATLAB
t = tiledlayout(2, 1); t.Padding = 'compact'; t.TileSpacing = 'compact';
nexttile
	plot(tp, dp); 
	ylabel('amp [?]'); legend('before filter', box='off')
	xlim([1.1, 1.2])
nexttile
	plot(tp, d_filtered); 
	xlabel('time [sec]'); ylabel('amp [?]'); legend('after filter', box='off')
	xlim([1.1, 1.2])

この記事のTOP    BACK    TOP