周波数フィルタの作成
脳波・脳磁図の波形データが読み込めたとしても、生波形には通常生体信号以外の 雑音も含まれていて、周波数フィルタによる信号処理が必要となります。 MATLABを使えば簡単にフィルタをかけることができます。 sptool関数を使えばGUIでフィルタが作れますが、 まずは自分でフィルタをかけれるようになりましょう。 平成24年9月20日の広大霞キャンパス基礎棟2Fで行ったMATLABセミナーの資料の一部です。 参加人数は7人くらいでした。
Contents
1~50Hzのチャープ信号の作成
chirp関数を使って1~50Hzに時間とともに変調するチャープ信号を作成します。
sfreq=600;% サンプリング周波数 t=linspace(0,5,5*sfreq);% 5秒 fstart=1;fend=50;% 1~50Hz y=chirp(t,fstart,t(end),fend);% チャープ信号
チャープ信号の表示
figure; subplot(2,1,1);% 波形表示 plot(t,y);xlabel('sec');ylabel('Amp'); win=2^8;% window subplot(2,1,2);% 時間周波数変化 [S,F,T,P]=spectrogram(y,win,win/2,win,sfreq); imagesc(T,F,P); set(gca,'YDir','normal','ylim',[fstart,fend]); xlabel('sec');ylabel('Hz');
無限インパルス応答(IIR)・楕円フィルタの作成
ellip関数を使って楕円関数を作成します。 ellipord関数を使えば最低次数を出力するらしいのですが、 不慣れなので次数は決め打ちで3にしてます。
bandpass=[8,14]; % 通過周波数帯域 n=3;Rp=0.1;Rs=60;% 次数は3 [b,a]=ellip(n,Rp,Rs,bandpass*2/sfreq);
IIRフィルタの周波数応答の表示
freqz関数を使います。
figure;freqz(b,a,1000,sfreq); set(findobj(gcf,'type','axes'),'xlim',[0,30]);
IIRフィルタ前後の波形表示
フィルタ処理後は次数+α分位相がズレるのでfiltfilt関数でズレを補正します。
figure; for n=1:3 subplot(3,1,n); switch n case 1;yy=y;txt='元波形'; case 2;yy=filter(b,a,y);txt='フィルタ後波形'; case 3;yy=filtfilt(b,a,y);txt='位相補正後フィルタ波形'; end; plot(t,yy);title(txt); xlabel('time');ylabel('amp'); end; set(findobj(gcf,'type','axes'),'ylim',[-2,2]);
IIRフィルタの時間周波数変化表示
figure; win=2^8; for n=1:3 subplot(3,1,n); switch n case 1;yy=y;txt='元データ'; case 2;yy=filter(b,a,y);txt='フィルタ処理後'; case 3;yy=filtfilt(b,a,y);txt='位相補正+フィルタ処理後'; end; [S,F,T,P]=spectrogram(yy,win,win/2,win,sfreq); if n==1 clim=[min(P(:)),max(P(:))]; end; imagesc(T,F,P);title(txt); xlabel('sec');ylabel('Hz'); end; h=findobj(gcf,'type','axes'); set(h,'YDir','normal','ylim',[fstart,fend],'clim',clim);
有限インパルス応答(FIR)・最小二乗線形フィルタ
FIRもいろいろあるんですが、firls関数を使ってみました。 FIRは分母が1なのでIIRよりも次数を増やさないといいフィルタになりません。
bandpass=[8,14]; % 通過周波数帯域 w=0.05*[-1,1]; f=[0,bandpass(1)+w,bandpass(2)+w,sfreq/2]/(sfreq/2); a=1;% FIRなので分母は1 n=128;% 次数は128 bp=[0,0,1,1,0,0]; b=firls(n,f,bp);
FIRフィルタの周波数応答の表示
freqz関数を使います。
figure;freqz(b,a,1000,sfreq); set(findobj(gcf,'type','axes'),'xlim',[0,30]);
FIRフィルタ前後の波形表示
figure; for n=1:3 subplot(3,1,n); switch n case 1;yy=y;txt='元波形'; case 2;yy=filter(b,a,y);txt='フィルタ後波形'; case 3;yy=filtfilt(b,a,y);txt='位相補正後フィルタ波形'; end; plot(t,yy);title(txt); xlabel('time');ylabel('amp'); end; set(findobj(gcf,'type','axes'),'ylim',[-2,2]);
FIRフィルタの時間周波数変化表示
figure; win=2^8; for n=1:3 subplot(3,1,n); switch n case 1;yy=y;txt='元データ'; case 2;yy=filter(b,a,y);txt='フィルタ処理後'; case 3;yy=filtfilt(b,a,y);txt='位相補正+フィルタ処理後'; end; [S,F,T,P]=spectrogram(yy,win,win/2,win,sfreq); if n==1 clim=[min(P(:)),max(P(:))]; end; imagesc(T,F,P);title(txt); xlabel('sec');ylabel('Hz'); end; h=findobj(gcf,'type','axes'); set(h,'YDir','normal','ylim',[fstart,fend],'clim',clim);