3次元配列をフーリエ変換し、座標ごとの振幅を取り出すにはどうすればよいですか?
Show older comments
data=214(x)×407(y)×49(t)の3次元配列を、xyの座標位置ごとにフーリエ変換したいです(214×407回分、別々にフーリエ変換したいです)。
また、計算される座標ごとの振幅の大きさを、各座標の濃淡で表現したいです。
最終的に、周波数ごとに振幅の大きさが分かるような画像を作りたいと考えています。なお、もとの49次元の画像には値のない画素(Nan)があります。
下記のコードを実行すると、フーリエ変換した変数Yが49のz軸の方向に、同じ値で計算されました(Y(:,:,1)とY(:,:,2)が同じ行列になりました。z軸の方向にフーリエ変換した結果を振幅で取り出したいのですが、その方法をご教示いただけないでしょうか。
前回こちらでご回答いただき、途中まで解決したものの、上記のことが分からず、重複のご質問をしております。よろしくお願いいたします。
L=49;
Fs=1;
n=2^nextpow2(L);
Y=fft(data,n,3);
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;
1 Comment
Naoya
on 14 Nov 2022
コードを確認する限りでは、xyの座標位置ごとに1次元のフーリエ変換をz方向に掛けていることはご所望の通り実施できている模様です。
P1(2:end-1) = 2*P1(2:end-1);
の部分は、通常、フーリエ変換を掛ける次元方向に適用するものになりますので、
P1(:,:,2:end-1) = 2*P1(:,:,2:end-1);
が所望になると思います。
また、
n=2^nextpow2(L);
Y=fft(data,n,3);
で 64点で fft を行っていますので、 Y の 3次元めのサイズは 64となりますので、
f は、
f = Fs*(0:(n/2))/n;
になります。
周波数ごとにxy座標の振幅値を求めるのであれば、 P(:,:,N) で求められます。 (ここで N は 周波数ビンとなり、 1 ~ 33 となり、それぞれ f のベクトルの要素に相当します)
Accepted Answer
More Answers (1)
non
on 14 Nov 2022
6 Comments
Naoya
on 14 Nov 2022
さらに確認をさせていただきましたが、以下2点の修正は必要の模様です。
% nextpow2 は 2のべき乗の指数部を返すので以下が正しい記述となります
n= nextpow2(L) --> n=2^nextpow2(L);
% FFTの点数はL ではなくn点となっていますので以下がよろしいと思います
P1 = P2(:,:,1:L/2+1); --> P1 = P2(:,:,1:n/2+1);
non
on 15 Nov 2022
Naoya
on 16 Nov 2022
PC1M をrand関数で3次元行列を疑似的に作って確認してみましたが、 a,aa,aaa,aaaa はそれぞれ異なる 2次元行列となっておりました。
3次元行列 PC1M について、PC1M(:,:,1), PC1M(:,:,2), PC1M(:,:,3) ... にて何かお気づきの点などありますでしょうか?
non
on 16 Nov 2022
Naoya
on 16 Nov 2022
matファイルの中身を確認してみましたが、変数PC1M の行列が 49次元 (214x407x1x1x...x1x49) となっておりましたので、 214x407x49 にまずは修正の必要があります。
これについては、 squeeze コマンドで不要な次元削減を行うことができます。
PC1M = squeeze(PC1M);
non
on 17 Nov 2022
Categories
Find more on Signal Processing Toolbox 入門 in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!