我试图将我在循环中创建的一堆图拼接成一个视频文件。我已经在这几个小时了,但没有运气。这是我最小的工作示例,我尝试使用VideoWriter函数来创建视频。我总是得到一个错误,说我的框架无法复制到视频对象中。格儿。
这是我的最低工作示例:
n=(1:50)*2*pi;
for t = 1:1000
Y = sin(n*50/t);
plot(Y); %plot shows a sine wave with decreasing frequency
F(t) = getframe; %I capture the plot here
end
writerObj = VideoWriter('test2.avi'); %Attempt to create an avi
open(writerObj);
for t= 1:time
writeVideo(writerObj,F(t))
end
close(writerObj);
答案 0 :(得分:2)
您缺少恒定的图像高度。您可以通过例如ylim
:
time = 100;
for t = 1:time
fplot(@(x) sin(x*50/t),[0,2*pi]); % plot
ylim([-1,1]); % guarantee consistent height
F(t) = getframe; % capture it
end
writerObj = VideoWriter('test2.avi');
open(writerObj);
writeVideo(writerObj, F)
close(writerObj);
我进一步用“连续”替换你的离散图(使用fplot
)。
答案 1 :(得分:1)
Matheburg答案是正确的,并确定导致错误的部分(在某些时候,轴的比例被调整大小,导致框架大小改变)。
他的解决方案运行正常,如果fplot
的使用对您有效,那么按照他的方式。
如果您仍想使用传统的plot
(2d lineserie
对象)方法,那么我通常会如何组织“动画”图:
plot
功能是高级别的。这意味着它在运行时绘制数据(显然),但也做了很多其他事情。在任何情况下,它都会生成一个全新的绘图(如果未指定hold on
则删除上一个绘图),还会重新调整轴限制和许多其他设置(颜色,样式等等)。
如果在动画中你只想更新绘图数据(点/线位置)但不更改任何其他设置(轴限制,颜色等...),最好定义绘图及其设置一个仅限时间,在循环之外,然后在循环中,您只更新绘图对象的YData
(和/或XData
,如果相关)。
这是通过在创建时检索绘图对象句柄来完成的,然后使用set
方法(与plot
不同,只会修改您明确指定的参数,并且不会修改其他任何内容)。
在你的情况下它看起来像这样:
n=(1:50)*2*pi ;
Y = sin(n*50) ;
hp = plot(Y) ; %// Generate the initial plot (and retrieve the handle of the graphic object)
ylim([-1,1]) ; %// Set the Y axes limits (once and for all)
writerObj = VideoWriter('test2.avi'); %// initialize the VideoWriter object
open(writerObj) ;
for t = 1:1000
Y = sin(n*50/t) ; %// calculate new Y values
set(hp,'YData',Y) ; %// update the plot data (this does not generate a "new" plot), nor resize the axes
F = getframe ; %// Capture the frame
writeVideo(writerObj,F) %// add the frame to the movie
end
close(writerObj);
此外,此方法通常运行得更快,如果循环有大量迭代,则会节省大量时间。
旁注:如上所述,马特堡解决方案也运行良好。对于这样的应用程序,速度的差异将不是主要问题,但请注意生成的图(和电影)略有不同(由于它使用fplot
而不是plot
)。因此,我鼓励您尝试这两个版本并选择最适合您的版本。