How do I export an animated figure to some video format for use in a presentation?
63 次查看(过去 30 天)
显示 更早的评论
With code adapted from other help threads, I have an animated figure which plays a video (about 20 sec) in one subplot while simultaneously plotting associated data in the next subplot. I run the code in Live editor (and just normally, for that matter) and the figure works perfectly.
How do I get this animated figure into a video file of some kind for use in a presentation? (code below)
Incidentally, the live editor includes a small export button at the bottom right of the figure, but this seems to freeze the code and I only get a blank gray section when I click it. (pics)
%setup subplots
ax1 = subplot(2,1,1); % For video
ax2 = subplot(2,1,2); % For data plot
%setup videoreader object
CH47Landing = 'D:\Manual Backup\PROJECTS\Ice\Engineer Lake\Landing.mp4';
v = VideoReader(CH47Landing);
nFrames = v.Duration*v.FrameRate; % Number of frames
% Display the first frame in the top subplot
vidFrame = readFrame(v);
image(vidFrame, 'Parent', ax1);
ax1.Visible = 'off';
%Load Data
lt = TIMESTAMP; %use your actual data
y = ld5;
nDataPoints = length(lt); % Number of data points
step = 0.033; % Increase this value to get a higher plot rate
index = 1:step:nDataPoints;
i = 2;
% Diplay the plot corresponds to the first frame in the bottom subplot
h = plot(ax2,lt(1:floor(index(i))),y(1:floor(index(i))),'-k');
%Fix the Axes
ax2.XLim = [lt(1) lt(end)];
ax2.YLim = [min(y) max(y)];
%Animate
while hasFrame(v)
pause(1/v.FrameRate);
vidFrame = readFrame(v);
image(vidFrame, 'Parent', ax1);
ax1.Visible = 'off';
i = i + 1;
set(h,'YData',y(1:floor(index(i))), 'XData', lt(1:floor(index(i))))
subplot(2,1,1)
xlim([1 1921])
ylim([1 925])
subplot(2,1,2)
set(gca, 'YDir','reverse')
ylabel('Deflection (mm)')
xticklabels({'12:02:00 PPM','12:02:15 PM','12:02:29PM'})
title('CH47; 31Jan23; h(i)=70cm; AirT=18°F. PT=#5')
xlim([datetime(2023,2,16,12,2,0)...
datetime(2023,2,16,12,2,40)])
ylim([0 15])
end
0 个评论
采纳的回答
Kevin Holly
2023-3-23
Daniel,
Please see the files attached and the code below. Saving the video should be faster when the figure's "Visible" property is set to "off" and when running it on a .m script instead of the Live Script.
Setup Figure
figure("Visible","off")
tiledlayout(2,1)
%setup subplots
ax1 = nexttile; % For video
ax2 = nexttile; % For data plot
%setup videoreader object
CH47Landing = 'xylophone.mp4';
v = VideoReader(CH47Landing);
nFrames = v.Duration*v.FrameRate; % Number of frames
% Display the first frame in the top subplot
vidFrame = readFrame(v);
image(vidFrame, 'Parent', ax1);
ax1.Visible = 'off';
%Load Data
lt = seconds(v.CurrentTime:1/v.FrameRate:v.NumFrames/v.FrameRate); %Note, this video is in seconds, so datetime was not used
y = rand(v.NumFrames,1)*15;
nDataPoints = length(lt); % Number of data points
step = 0.033; % Increase this value to get a higher plot rate
index = 1:step:nDataPoints;
ii = 2;
% Diplay the plot corresponds to the first frame in the bottom subplot
h = plot(ax2,lt(1:floor(index(ii))),y(1:floor(index(ii))),'-k');
%Fix the Axes
ax2.XLim = [lt(1) lt(end)];
set(gca, 'YDir','reverse')
ylim(ax2,[0 15])
title('CH47; 31Jan23; h(i)=70cm; AirT=18°F. PT=#5')
ylabel(ax1,'Deflection (mm)')
Save one frame at a time
vsave = VideoWriter('SavedFilebyFrame','MPEG-4');
h = plot(ax2,lt(1:floor(index(ii))),y(1:floor(index(ii))),'-k');
% lt = datetime(lt,'ConvertFrom','datenum','Format','HH:mm:ss.SSS');
open(vsave)
%Animate
while hasFrame(v)
vidFrame = readFrame(v);
image(vidFrame, 'Parent', ax1);
ax1.Visible = 'off';
ii = ii + 1;
set(h,'YData',y(1:floor(index(ii))), 'XData', lt(1:floor(index(ii))))
xlim(ax2,[0 max(h.XData)])
ylabel(ax1,'Deflection (mm)')
img = getframe(gcf);
writeVideo(vsave,img.cdata)
end
close(vsave)
Save entire video at once
Create 4D matrix of video
ii=0;
v = VideoReader(CH47Landing);
lt = 1/v.FrameRate:1/v.FrameRate:v.NumFrames*v.FrameRate;
while hasFrame(v)
ii = ii + 1;
vidFrame(:,:,:,ii) = readFrame(v);
end
Write video
figure("Visible","off")
vsave = VideoWriter('SavedFile','MPEG-4');
h = plot(ax2,lt(1:floor(index(ii))),y(1:floor(index(ii))),'-k');
% lt = datetime(lt','ConvertFrom','datenum','Format','HH:mm:ss.SSS');
open(vsave)
for ii = 1:v.NumFrames
% pause(1/v.FrameRate);
image(vidFrame(:,:,:,ii), 'Parent', ax1);
ax1.Visible = 'off';
set(h,'YData',y(1:floor(index(ii))), 'XData', lt(1:floor(index(ii))))
xlim(ax2,[0 max(h.XData)])
img = getframe(gcf);
writeVideo(vsave,img.cdata);
end
close(vsave)
0 个评论
更多回答(2 个)
Anton Kogios
2023-2-22
编辑:Anton Kogios
2023-2-22
Documentation for recording animations: https://mathworks.com/help/matlab/creating_plots/record-animation-for-playback.html
and exporting animations: https://mathworks.com/help/symbolic/writeanimation.html
In your while loop, at the end add
vid(i) = getframe(gcf);
and then at the end of the script add
v = VideoWriter('recordedAnimation,'MPEG-4');
open(v)
for i = 1:length(vid)
writeVideo(v,vid(i))
end
close(v)
You may have to modify the above code since I cannot test it given you haven't provided the Landing.mp4 video. There is plenty of helpful documention if you search this topic up on Google. This may also help: https://mathworks.com/matlabcentral/answers/455886-how-to-save-animated-plots
7 个评论
Anton Kogios
2023-3-1
编辑:Anton Kogios
2023-3-1
This should be at the very end, outside the for loop (the while loop in your code above):
v = VideoWriter('recordedAnimation','MPEG-4');
open(v)
for i = 1:length(vid)
writeVideo(v,vid(i))
end
close(v)
And this should be before the for loop (the while loop in your code above):
vid(1:990) = struct('cdata',zeros(420,560,3,'uint8'),'colormap',[]);
It may be best if you start with a simple example first and get that to work. You should also read the documentation I mentioned in my first answer so you know what the code is actually doing, rather than copy-pasting what I say at the incorrect locations.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 GigE Vision Hardware 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!