필터 지우기
필터 지우기

How do I export an animated figure to some video format for use in a presentation?

조회 수: 78 (최근 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

채택된 답변

Kevin Holly
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)

추가 답변 (2개)

Anton Kogios
Anton Kogios 2023년 2월 22일
편집: Anton Kogios 2023년 2월 22일
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
Daniel
Daniel 2023년 3월 1일
Ok looks like this outputs the Matlab figure which plays the video, but then it does not plot the data or output a video file.
Anton Kogios
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.

댓글을 달려면 로그인하십시오.


Simon Chan
Simon Chan 2023년 2월 22일
  댓글 수: 1
Daniel
Daniel 2023년 3월 1일
I would definitely be fine with that option. The difficulty I think is that there is a video in the script already, and I am not sure how to handle that. If it were a simple matter of animating a plotting function or something, it might be easier, but I need this video in the output as well.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Audio and Video Data에 대해 자세히 알아보기

제품


릴리스

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by