我面临制作约10,000帧的电影和每帧约10,000像素的电影。 imagesc
。但是,即使我的计算机配备了8 GB的RAM(运行32位MATLAB),MATLAB也会抱怨Out Of Memory
大约1,000帧。另外,我也想要压缩我的电影。创建大型电影的最佳选择是什么?
答案 0 :(得分:9)
为了找出最佳选择,我测试了几种电影编写功能(Windows 7 MATLAB 2012a 32位)。
关键是确保在电影完成之前该功能将帧刷新到磁盘。 VideoWriter结合MPEG-4产生恒定(小)内存大小和压缩视频。
%%%
% General Setup
%%%
number_of_frames = 1000;
Z = peaks;
%%%
% Video Writer -- AVI
%%%
%%
f = figure('renderer', 'zbuffer');
a = axes('parent', f);
axis(a, 'tight');
surf(a, Z);
current_zlim = zlim();
set(a, 'nextplot', 'replacechildren', 'zlimmode', 'manual', 'zlim', current_zlim);
vid = VideoWriter('myPeaks - VideoWriter.avi');
vid.Quality = 100;
vid.FrameRate = 15;
open(vid);
current_memory_used_Bytes(1, number_of_frames + 1) = 0;
current_memory_struct = memory();
current_memory_used_Bytes(1) = current_memory_struct.MemUsedMATLAB;
for(k = 1 : number_of_frames)
surf(a, sin(2*pi*k/20)*Z, Z);
writeVideo(vid, getframe(f));
current_memory_struct = memory();
current_memory_used_Bytes(k + 1) = current_memory_struct.MemUsedMATLAB;
end
close(vid);
figure;
plot((current_memory_used_Bytes(2 : end) - current_memory_used_Bytes(1)) / 1e6);
xlabel('Frame Number');
ylabel('Movie Memory in RAM (MB)');
title('VideoWriter -- AVI');
saveas(gcf, 'myPeaks - VideoWriter -- AVI.png');
close all;
clearvars -except number_of_frames Z
%%%
% Video Writer -- MPEG-4
%%%
%%
f = figure('renderer', 'zbuffer');
a = axes('parent', f);
axis(a, 'tight');
surf(a, Z);
current_zlim = zlim();
set(a, 'nextplot', 'replacechildren', 'zlimmode', 'manual', 'zlim', current_zlim);
vid = VideoWriter('myPeaks - VideoWriter.mp4', 'MPEG-4');
vid.Quality = 100;
vid.FrameRate = 15;
open(vid);
current_memory_used_Bytes(1, number_of_frames + 1) = 0;
current_memory_struct = memory();
current_memory_used_Bytes(1) = current_memory_struct.MemUsedMATLAB;
for(k = 1 : number_of_frames)
surf(a, sin(2*pi*k/20)*Z, Z);
writeVideo(vid, getframe(f));
current_memory_struct = memory();
current_memory_used_Bytes(k + 1) = current_memory_struct.MemUsedMATLAB;
end
close(vid);
figure;
plot((current_memory_used_Bytes(2 : end) - current_memory_used_Bytes(1)) / 1e6);
xlabel('Frame Number');
ylabel('Movie Memory in RAM (MB)');
title('VideoWriter -- MPEG-4');
saveas(gcf, 'myPeaks - VideoWriter -- MPEG-4.png');
close all;
clearvars -except number_of_frames Z
%%%
% Movie2AVI
%%%
%%
f = figure('renderer', 'zbuffer');
a = axes('parent', f);
axis(a, 'tight');
surf(a, Z);
current_zlim = zlim();
set(a, 'nextplot', 'replacechildren', 'zlimmode', 'manual', 'zlim', current_zlim);
movie_frames(1 : number_of_frames) = struct('cdata', [], 'colormap', []);
current_memory_used_Bytes(1, number_of_frames + 1) = 0;
current_memory_struct = memory();
current_memory_used_Bytes(1) = current_memory_struct.MemUsedMATLAB;
for(k = 1 : number_of_frames)
surf(a, sin(2*pi*k/20)*Z, Z);
movie_frames(k) = getframe(f);
current_memory_struct = memory();
current_memory_used_Bytes(k + 1) = current_memory_struct.MemUsedMATLAB;
end
movie2avi(movie_frames, 'myPeaks - Movie2AVI.avi', 'compression', 'none', 'fps', 10);
figure;
plot((current_memory_used_Bytes(2 : end) - current_memory_used_Bytes(1)) / 1e6);
xlabel('Frame Number');
ylabel('Movie Memory in RAM (MB)');
title('Movie2AVI -- AVI');
saveas(gcf, 'myPeaks - Movie2AVI -- AVI.png');
close all;
clearvars -except number_of_frames Z
%%%
% IMWrite
%%%
%%
f = figure('renderer', 'zbuffer');
a = axes('parent', f);
axis(a, 'tight');
surf(a, Z);
current_zlim = zlim();
set(a, 'nextplot', 'replacechildren', 'zlimmode', 'manual', 'zlim', current_zlim);
current_frame = getframe(a);
[frame_indices, cmap] = rgb2ind(current_frame.cdata, 256, 'nodither');
movie_frames = repmat(frame_indices, [1 1 1 number_of_frames]);
current_memory_used_Bytes(1, number_of_frames + 1) = 0;
current_memory_struct = memory();
current_memory_used_Bytes(1) = current_memory_struct.MemUsedMATLAB;
for(k = 1 : number_of_frames)
surf(sin(2*pi*k/20)*Z, Z)
f = getframe(a);
movie_frames(:, :, 1, k) = rgb2ind(f.cdata, cmap, 'nodither');
current_memory_struct = memory();
current_memory_used_Bytes(k + 1) = current_memory_struct.MemUsedMATLAB;
end
imwrite(movie_frames, cmap, 'myPeaks - IMWrite.gif', 'DelayTime', 0, 'LoopCount', inf);
figure;
plot((current_memory_used_Bytes(2 : end) - current_memory_used_Bytes(1)) / 1e6);
xlabel('Frame Number');
ylabel('Movie Memory in RAM (MB)');
title('Movie2AVI -- AVI');
saveas(gcf, 'myPeaks - IMWrite.png');
close all;
clearvars -except number_of_frames Z
%%%
% MPGWrite
%%%
%%
f = figure('renderer', 'zbuffer');
a = axes('parent', f);
axis(a, 'tight');
surf(a, Z);
current_zlim = zlim();
set(a, 'nextplot', 'replacechildren', 'zlimmode', 'manual', 'zlim', current_zlim);
winsize = get(f, 'Position');
winsize(1:2) = [0 0];
movie_frames = moviein(number_of_frames, f, winsize);
current_memory_used_Bytes(1, number_of_frames + 1) = 0;
current_memory_struct = memory();
current_memory_used_Bytes(1) = current_memory_struct.MemUsedMATLAB;
for(k = 1 : number_of_frames)
surf(sin(2*pi*k/20)*Z, Z)
drawnow;
movie_frames(:, k) = im2frame(hardcopy(f, '-Dzbuffer', '-r0'));
current_memory_struct = memory();
current_memory_used_Bytes(k + 1) = current_memory_struct.MemUsedMATLAB;
end
mpgwrite(movie_frames, jet, 'myPeaks - MPGWrite.mpg');
figure;
plot((current_memory_used_Bytes(2 : end) - current_memory_used_Bytes(1)) / 1e6);
xlabel('Frame Number');
ylabel('Movie Memory in RAM (MB)');
title('MPGWrite -- MPG');
saveas(gcf, 'myPeaks - MPGWrite.png');
close all;
clearvars -except number_of_frames Z
正如我们所看到的,VideoWriter,IMWrite和Movie2AVI具有几乎恒定的内存要求,而AVI2File和MPGWrite所需的内存随帧数而变化。这是有道理的,因为后者需要在写电影之前保持每一帧,而前者似乎定期刷新到磁盘。
VideoWriter - AVI:154,529 KB
VideoWriter - MPEG-4:19,355 KB
IMWrite:13,385 KB
Movie2AVI - AVI:992,276 KB
MPGWrite:24,301 KB
如预期的那样,MPEG-4产生比AVI更高效的压缩。有趣的是,VideoWriter和IMWrite在这个测试中都优于MPGWrite(尽管我认为MPGWrite在VideoWriter之前已经存在很多年了!)。答案 1 :(得分:1)
根据我的经验,从MATLAB图中制作视频的最强大,最一致和最灵活的方法是将单个帧导出为图像,然后将图像与另一个程序(如ffmpeg)组合成电影。如果需要,这还使您有机会批量处理图像。我创建了一个完整的流程写法,您可以在此处找到:http://enstrophy.mae.ufl.edu/~mohseni/links/docs/video_guide.pdf