MATLAB Answers

Error using Video Writer

1 ビュー (過去 30 日間)
Matthias Heindl
Matthias Heindl 2020 年 8 月 10 日
コメント済み: Image Analyst 2020 年 8 月 12 日
Hey there,
I work on doing a simplified thermodynamic animation and I use the Video Writer object to accomplish that.
writeVideo requires each frame to be the exact same size. My frames are not. The reason for that may simply be, that it's a three dimensional simulation.
Is there a way, I can unify or fix the size for each frame?
The plot is created by using the 'surf' command and the 'patch' command. Since it's quite some lines of code, I decided not to share it here.
avi_video = VideoWriter('process_1.avi');
open(avi_video);
allTheFrames = cell(timeframes,1);
allTheFrames(:) = {zeros(vidHeight, vidWidth, 3, 'uint8')};
allColorMaps = cell(timeframes,1);
allColorMaps(:) = {zeros(256, 3)};
recalledmie = struct('cdata', allTheFrames, 'colormap', allColorMaps);
F_cell = struct2cell(F);
thisFirstFrame = cell2mat(F_cell(1, 1, calculations_per_frame));
continue_counter = 0;
for frame = 1 : timeframes
thisFrame = cell2mat(F_cell(1, 1, frame * calculations_per_frame));
if any(size(thisFrame) ~= size(thisFirstFrame))
continue_counter = continue_counter + 1;
continue
end
recalledmie(frame) = im2frame(thisFrame);
writeVideo(avi_video, thisFrame);
end
close(avi_video);
Furthermore I tried to work my way around that problem by setting up an if condition (Is the size of the current frame equal to the size of the first frame, and if not 'continue'), but too many frames seem to be of a slightly different size. I was not able to get a proper video from that.

  2 件のコメント

Sudheer Bhimireddy
Sudheer Bhimireddy 2020 年 8 月 10 日
Did you try limiting the axis or axis length based on your values?
Matthias Heindl
Matthias Heindl 2020 年 8 月 10 日
No, not exactly.
My Code looks something like this
for t = 1:time_iterations
fig = figure(1);
hold on
for 1:number_objects_1
surf(x,y,z,'red')
end
for 1:number_objects_3
surf(x,y,z,'blue')
end
...
patch(x_rectangles, y_rectangles, z_rectangles, [0.6 0.6 0.6])
...
end
This means on each iteration there is only a single figure as far as I understand.
I tried to implement the 'axes' command in this structure by initializing it before the t-loop, but I failed. Is there another way to do it? / How can I apply your suggestion on the code above?

サインインしてコメントする。

採用された回答

Image Analyst
Image Analyst 2020 年 8 月 10 日
If your subsequent images are not the same size as the first frame, you could call imresize() to make them the same size.

  2 件のコメント

Matthias Heindl
Matthias Heindl 2020 年 8 月 10 日
avi_video = VideoWriter('process_1.avi');
open(avi_video);
allTheFrames = cell(timeframes,1);
allTheFrames(:) = {zeros(vidHeight, vidWidth, 3, 'uint8')};
allColorMaps = cell(timeframes,1);
allColorMaps(:) = {zeros(256, 3)};
recalledmie = struct('cdata', allTheFrames, 'colormap', allColorMaps);
F_cell = struct2cell(F);
thisFirstFrame = cell2mat(F_cell(1, 1, calculations_per_frame));
thisFirstFrame_1 = size(thisFirstFrame, 1); %%%
thisFirstFrame_2 = size(thisFirstFrame, 2); %%%
imresize_counter = 0;
for frame = 1 : timeframes
thisFrame = cell2mat(F_cell(1, 1, frame * calculations_per_frame));
if any(size(thisFrame) ~= size(thisFirstFrame))
imresize_counter = continue_counter + 1; %%%
thisFrame = imresize(thisFrame, [thisFirstFrame_1, thisFirstFrame_2]); %%%
end
recalledmie(frame) = im2frame(thisFrame);
writeVideo(avi_video, thisFrame);
end
close(avi_video);
This has worked for me, thank you!
I have marked the significant changes with triple %%%
Image Analyst
Image Analyst 2020 年 8 月 12 日
Thanks for accepting the answer. By the way,
if any(size(thisFrame) ~= size(thisFirstFrame))
could also be done like this:
if ~isequal(size(thisFrame), size(thisFirstFrame))
which is how I'd do it.

サインインしてコメントする。

その他の回答 (1 件)

Sudheer Bhimireddy
Sudheer Bhimireddy 2020 年 8 月 10 日
Your code looks strange. Do you have 'hold on' before the loop?
Also if you have complete extents of your x,y variables, you can find the global maximums and use them with xlim and ylim as shown below.
fig = figure(1);
f = gcf;
f.Position=[100 100 1050 340]; % <-this will be figure window display size in pixels
f.PaperUnits='inches';
f.PaperPosition=[0 0 4 3]; %<-this will be print size, all the frames will have this size
for t = 1:time_iterations
clf;
hold on;
for 1:number_objects_1
surf(x,y,z,'red')
end
for 1:number_objects_3
surf(x,y,z,'blue')
end
...
xlim([x_min x_max]);
ylim([y_min y_max]);
end

  3 件のコメント

Matthias Heindl
Matthias Heindl 2020 年 8 月 10 日
'hold on' was already in my real code, I added it here, thank you.
I used xlim, ylim and zlim with very generous values. I will try to adapt to your suggestion.
Could it be a problem, that I have some objects plotted outside of my frame? Some objects in my video are flying in
Sudheer Bhimireddy
Sudheer Bhimireddy 2020 年 8 月 10 日
As long as your framesize is fixes, it should not matter. If the framesize is not fixed, the figure axis object might be trying to adjust the limits to include the objects. More than xlim and ylim; try the first five lines of my code and see what happens (note that I have moved your figure initiation line outside the loop). If you are still getting an error, try to attach two consecutive frames as pictures.
Matthias Heindl
Matthias Heindl 2020 年 8 月 10 日
Adding the first five lines of your code didn't bring the expected results.
I don't really understand, what you mean by your second suggestion, maybe you can clarify that for others who might also have a similar problem.
The problem is solved for me, thank you

サインインしてコメントする。

Community Treasure Hunt

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

Start Hunting!

Translated by