動画の3次元フーリエ​変換でスペクトル描画​中でのエラーについて

動画の3次元フーリエ変換を行い、振幅特性を知るためにスペクトラムを描こうとして、
次のコードを作成しましたが、下記のエラーが発生してしまいました。エラーの意味も分からず対処に苦慮しております。
対処法をご教授頂けませんでしょうか?
よろしくお願いいたします。
(作成中のコード)
%No defect動画のフレームを読み込み、グレースケール変換
vnd= VideoReader("C:\Users\user\MATLAB Drive\Examples\Ultrasonic_analysis\3803nd_20230512.avi");
%3D FFTの点数(高さ 幅 時間)
sizeFft=[748 1124 2];
nFrames=24;
clear array3d_nd;
%ハニング窓の設定
win=hanning(nFrames)
%各フレームをグレースケールに変換
k=1;
while hasFrame(vnd)
mvnd(:,:,:,k) = readFrame(vnd);% データ読み込み
gray_mvnd(:,:,k) = rgb2gray(mvnd(:,:,:,k));% グレースケールに変換
%rectを定義してトリミング
rect=images.spatialref.Rectangle([40 890.0],[210.0 450.0]) % xの下限と上限 yの下限と上限
cuttedimage_nd(:,:,k)=imcrop(gray_mvnd(:,:,k),rect) % 画像トリミング
%トリミングした画像にハニング窓を掛ける
array3d_nd(:,:,k)=win(k)*double(cuttedimage_nd(:,:,k))/255.0;
%array3d_nd(:,:,k)=win(k)*single(cuttedimage_nd(:,:,k))/255.0;
k=k+1;
end
clear frameSeq cuttedimage_nd
% 3Dフーリエ変換の計算
freqChart3d=abs(fftshift(fftn(array3d_nd,sizeFft)));
clear array3d_nd
%3Dスペクトラムの表示(累乗則変換を利用)
freqChart3d=freqChart3d/max(freqChart3d(:));
freqChart3d=freqChart3d.^0.1;
[wt,wh,wv]=meshgrid(...
-1:2/sizeFft(3):1-2/sizeFft(3),...
-1:2/sizeFft(1):1-2/sizeFft(1),...
-1:2/sizeFft(2):1-2/sizeFft(2));
freqChart3d=permute(freqChart3d,[2 3 1]);
slice(wt,wh,wv,freqChart3d,...
0,0,0,'nearest');
shading flat;
axis vis3d;
colormap("jet");
xlabel('\omega_T ( \times\pi rad)');
ylabel('\omega_H ( \times\pi rad)');
zlabel('\omega_V ( \times\pi rad)');
clear freqChart3d wt wh wv;
%mesh(log(absfftdenoised_nd(:,:,1,24)));view(0,90)
%meshgrid(log(freqChart3d));view(-45,45)
(エラー内容)
次を使用中: griddedInterpolant
GridVectors は、値配列と互換性のあるサイズをもつグリッドを定義しなければなりません。
エラー: interp3 (行 144)
F = griddedInterpolant(X, Y, Z, V, method,extrap);
エラー: slice (行 103)
vi = interp3(x,y,z,v,xi,yi,zi,method);
エラー: fouriertrans3d_Nodefect_20230512_20230820 (行 38)
slice(wt,wh,wv,freqChart3d,...

回答(1 个)

Shunichi Kusano
Shunichi Kusano 2023-8-24

0 个投票

slice関数のところでエラーが出ているようです。
見てみるとおそらくですがwt,wh,wvのサイズとfreqChart3dのサイズが異なっていると思いますので、合うように作り変えてみてください。

4 个评论

敬
2023-8-24
ありがとうございます。早速試してみます。
敬
2023-8-25
ご指摘の内容について、
wt,wh,wvのサイズが1124×2×748、一方freqChart3dのサイズが748×2×1124担っていることがエラーの原因と理解しています。そこで下記のようにコードを作成してみました。
下のようなエラーが出ました。ChatGPTでエラー原因を調べました(下記)。sizeFftの配列が原因とのことですがChatGPTが指摘していることはできているように思えます。3次元フーリエ変換を実施するにあたり各変数の配列の大きさを合わせるのが考え方が分かっていないです。真因と対策が分からず苦慮しております。再びご指導頂けますでしょうか?
よろしくお願いいたします。
(再度作ったコード)
%No defect動画のフレームを読み込み、グレースケール変換
vnd = VideoReader("C:\Users\user\MATLAB Drive\Examples\Ultrasonic_analysis\3803nd_20230512.avi");
%フレーム数とサイズを指定する
nFrames=vnd.numFrames;
vid.Height=vnd.Height;
vid.Width=vnd.Width;
vid.FrameRate=vnd.FrameRate
vid.Duration=vnd.Duration
%3D FFTの点数(高さ 幅 時間)
sizeFft=[748 1124 2];
%動画のサイズ
%nFrames=
%vid.Height=
%vid.Width=
clear array3d_nd;
%ハニング窓の設定
win=hanning(nFrames)
%動画の配列を作成し、初期化する
mvnd=zeros(vid.Height,vid.Width,3,int64(vid.FrameRate*vid.Duration),'uint8');
%フレームを作成し、それぞれグレースケールに変換
k=1;
while hasFrame(vnd)
mvnd(:,:,:,k) = readFrame(vnd);% データ読み込み
gray_mvnd(:,:,1,k) = rgb2gray(mvnd(:,:,:,k));% グレースケールに変換
%rectを定義してトリミング
rect=images.spatialref.Rectangle([40 890.0],[210.0 450.0]) % xの下限と上限 yの下限と上限
cuttedimage_nd(:,:,1,k)=imcrop(gray_mvnd(:,:,1,k),rect) % 画像トリミング
%トリミングした画像にハニング窓を掛ける
array3d_nd(:,:,1,k)=win(k)*double(cuttedimage_nd(:,:,1,k))/255.0;
k=k+1;
end
clear frameSeq cuttedimage_nd;
% 3Dフーリエ変換の計算
freqChart3d=abs(fftshift(fftn(array3d_nd,sizeFft)));
clear array3d_nd;
%3Dスペクトラムの表示(塁乗則変換を利用)
freqChart3d=freqChart3d/max(freqChart3d(:));
freqChart3d=freqChart3d.^0.1;
[wt,wh,wv]=meshgrid(...
-1:2/sizeFft(3):1-2/sizeFft(3),...
-1:2/sizeFft(1):1-2/sizeFft(1),...
-1:2/sizeFft(2):1-2/sizeFft(2));
freqChart3d=permute(freqChart3d,[2 3 1]);
slice(wt,wh,wv,freqChart3d,...
0,0,0,'nearest'); % slice
shading flat;
axis vis3d;
colormap("jet");
xlabel('\omega_T ( \times\pi rad)');
ylabel('\omega_H ( \times\pi rad)');
zlabel('\omega_V ( \times\pi rad)');
clear freqChart3d wt wh wv;
(エラー)
次を使用中: fftn
FFTN の出力サイズは、少なくとも NDIMS の要素がなければなりません。
エラー: fouriertrans3d_Nodefect_20230512_20230820 (行 43)
freqChart3d=abs(fftshift(fftn(array3d_nd,[748 1124 2]))
(ChatGPTの指摘)
エラーの原因は、sizeFft ベクトルの要素数が 2 以下であることです。fftn 関数は、出力サイズを指定するベクトルの要素数が、入力配列の次元数と同じかそれ以上であることを要求します。1 によると、入力配列 array3d_nd は 3 次元配列なので、sizeFft ベクトルは少なくとも 3 つの要素を持たなければなりません。例えば、sizeFft = [748 1124 2] とすると、エラーは発生しません。
対処法としては、sizeFft ベクトルの要素数を増やすか、入力配列 array3d_nd の次元数を減らすかのどちらかです。後者の場合は、squeeze 関数を使って余分な次元を削除できます。例えば、array3d_nd = squeeze (array3d_nd) とすると、array3d_nd のサイズは [748 1124] になります。この場合は、sizeFft ベクトルも 2 次元に合わせて変更する必要があります。
参考文献: 1: 動画の3次元フーリエ変換でスペクトル描画中でのエラーについて - MATLAB Answers - MATLAB Central
以上
エラー文を見ますと
FFTN の出力サイズは、少なくとも NDIMS の要素がなければなりません。
ということなので、入力している配列のサイズと指定したフーリエ変換のサイズが何らか不一致しているようには見えるのですが、スクリプトを見る上では問題は無いようには見えます。
スクリプトを一行一行実行しつつ、結果を見て想定とあっているか確認していくほかないかと思います。こちらのページにデバッグの仕方の説明がありますので参考にしてみてください。
まずは今回エラーが出ているfftnの行にブレークポイントを付けて実行し、fftn実行時のarray3d_ndのサイズについて確認してみるのがいいのではないでしょうか。
敬
2023-8-28
ありがとうございます。ご提案のデバックをやってみます。

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 フーリエ解析とフィルター処理 的更多信息

产品

提问:

敬
2023-8-22

评论:

敬
2023-8-28

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!