3

同様の質問についてstackoverflowを検索したところ、「movie2avi-frame-size-error-and-keeping-frame-size-constant」という質問が見つかりました。残念ながら、そこにある答えは私の問題を解決しませんでした (xlim、ylim、zlim の使用が提案されています)。

以下では、他の場所で与えられたよく知られた例を少し修正したバージョンを送ります。

%# figure
figure, set(gcf, 'Color','white')
Z = peaks; surf(Z);  axis tight
set(gca, 'nextplot','replacechildren', 'Visible','off');
[az,el]=view;
xl=xlim;
yl=ylim;
zl=zlim;

%# preallocate
nFrames = 20;
mov(1:nFrames) = struct('cdata',[], 'colormap',[]);

%# create movie
for k=1:nFrames
   view([(az-k*10) el]);
   xlim(xl);ylim(yl);zlim(zl);
   drawnow;pause(0.1);
   mov(k) = getframe(gca);
end
close(gcf)

%# save as AVI file, and open it using system video player
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10);

アイデアは、フィギュアを回転させてムービーを作成することです。最後のコマンド、つまり movie2avi を除いて、すべて正常に動作します。エラーメッセージは

Error using avifile/addframe>ValidateFrame (line 290)
Frame must be 435 by 344.

Error in avifile/addframe (line 158)
ValidateFrame(aviobj,width, height,dims);

Error in movie2avi (line 67)
avimov = addframe(avimov,mov);

Error in more_video_test (line 24)
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10); 

私はここでstackoverflowのアプローチを見て、ビデオをマットラボで作成し、次のことを発見しました:

a) 解決策 ffmpeg は機能しますが、回避したいと思います。
b) 他のすべてのソリューションは QTWriter でも失敗しました。これらの他のすべてのソリューションが機能するように、フレーム サイズを修正するにはどうすればよいですか?

どうもありがとう。

エド

4

3 に答える 3

3

問題は、グラフの回転により軸のサイズが変化するため、異なるサイズのフレームのシーケンスになってしまうことです。行を挿入すると、これを見ることができます

s = size(mov(k).cdata);
fprintf('%d %d\n', s(2), s(1))

ループ内で、フレームを取得した直後

mov(k) = getframe(gca);

結果は

435 344
435 343
435 343
436 342
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343
435 343

最初のフレームのサイズは 435 x 344 であるため、movie2aviは後続のフレームが同じサイズであると想定しますが、そうではありません。

これを修正するには、 を使用して軸のサイズ (および位置) を明示的に設定することをお勧めしますset(gca, 'Position', [...])。ただし、より簡単な回避策は、軸からではなく図からフレームをつかむことです。つまり、mov(k) = getframe(gca);使用する代わりに

mov(k) = getframe(gcf);

フレームは 560 x 420 の均一なサイズになります。

私のマシンでは、結果の avi のフレームが上下逆になっています。これも修正するために、追加で行を挿入できます

mov(k).cdata = mov(k).cdata(end :-1: 1, :, :);

フレームをつかんだ後。

于 2013-09-28T14:30:30.980 に答える
1

私の質問に対する別の解決策を見つけました。

%# figure
figure, set(gcf, 'Color','white')
Z = peaks; surf(Z);  axis tight
set(gca, 'nextplot','replacechildren', 'Visible','off');
axis vis3d

% With VideoWriter

writerObj = VideoWriter('myPeaks3.avi');
open(writerObj);

%# preallocate
nFrames = 90;
mov(1:nFrames) = struct('cdata',[], 'colormap',[]);

%# create movie
for k=1:nFrames
   camorbit(360/nFrames,0,'data','z');
   drawnow;
   mov(k) = getframe(gcf);
   writeVideo(writerObj,mov(k));
end;

% Close file

close(writerObj);
于 2013-10-02T16:32:20.493 に答える