Weird bug in getframe

4 vues (au cours des 30 derniers jours)
Markus Klyver
Markus Klyver le 5 Août 2018
Commenté : Image Analyst le 5 Août 2018
Hello!
I have encountered a very weird behaviour of the getframe function. I essentially create a new frame in a for loop by
figure(10)
image(xvekt*1e6,yvekt*1e6,I2/max(max(I2))*64)
hold on
plot(D_core/2*cos(linspace(0,2*pi,50))*1e6,D_core/2*sin(linspace(0,2*pi,50))*1e6,'Color',[1 1 1]*0.6,'LineWidth',2)
colormap(jet)
hold off
zoom(5)
drawnow
pause(.1)
F(steg_nummer) = getframe;
Exactly what the code does is not very important, but notice the pause(0.1) before the getframe call to make sure getframe really captures the frame. steg_nummer is the iteration variable.
After the for loop, I attempt to save the animation by
v = VideoWriter('C:\newfile.avi');
open(v);
for k=1:length(F)
k
writeVideo(v,F(k))
end
close(v)
But this fails. As above, I'm displaying the k for debugging purposes, and it appears that the cdata sometimes is a 0x0-matrix, which is weird.
The for loop
for k=1:length(F)
disp(size(F(k).cdata))
end
returns
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
0 0
0 0
0 0
0 0
344 436 3
and writeVideo of course fails at the first 0x0 cdata matrix. I have tried switching to software OpenGL by opengl('software') in the beginning of the script, but without any luck. What is going on here?
  5 commentaires
Markus Klyver
Markus Klyver le 5 Août 2018
@Jan: I upgraded to 2018a, but the problem still persists. All code spans over several files. How can I send them?
Image Analyst
Image Analyst le 5 Août 2018
Use the paper clip icon.

Connectez-vous pour commenter.

Réponse acceptée

Walter Roberson
Walter Roberson le 5 Août 2018
Your code does
if size(size(F(k).cdata)) ~= [1, 3]
writeVideo(v,F(k))
end
I recommend you use ndim(F(k).cdata) instead of testing size(size())
Currently you ask to write only if the data does not have 3 dimensions. That occurs if the data is empty -- so you are asking to write only the frames that are empty.
You end up with empty frames because you have
if steg_nummer <50 | rem(steg_nummer,5)==0 % för att snabba på simuleringen plottas inte alla BPM-steg
so you only do the capture for the first 49 frames, and every 5th frame after that. The other ones end up empty.
If only want to skip frames in the output, then you will need to use another variable which is the counter of how many frames you have written.

Plus de réponses (1)

Image Analyst
Image Analyst le 5 Août 2018
Did you preallocate F, like I did in this snippet from my attached demo?
% Set up the movie structure.
% Preallocate movie, which will be an array of structures.
% First get a cell array with all the frames.
allTheFrames = cell(numberOfFrames,1);
vidHeight = 344;
vidWidth = 446;
allTheFrames(:) = {zeros(vidHeight, vidWidth, 3, 'uint8')};
% Next get a cell array with all the colormaps.
allTheColorMaps = cell(numberOfFrames,1);
allTheColorMaps(:) = {zeros(256, 3)};
% Now combine these to make the array of structures.
myMovie = struct('cdata', allTheFrames, 'colormap', allTheColorMaps);
% Create a VideoWriter object to write the video out to a new, different file.
% writerObj = VideoWriter('problem_3.avi');
% open(writerObj);
% Need to change from the default renderer to zbuffer to get it to work right.
% openGL doesn't work and Painters is way too slow.
set(gcf, 'renderer', 'zbuffer');
Did you ever click anywhere else, especially on another axes, while this loop was executing? You might try passing in the axes handle into getframe().
  2 commentaires
Markus Klyver
Markus Klyver le 5 Août 2018
Nope, I just call it using
F(index) = getframe
Preallocating didn't resolve the issue.
Image Analyst
Image Analyst le 5 Août 2018
The problem is this line:
if steg_nummer <50 | rem(steg_nummer,5)==0 % för att snabba på simuleringen plottas inte alla BPM-steg
Until steg_nummer is 50 you set every structure of the F array. But after steg_nummer = 50, you set only structure numbers 55, 60, 65, 70, etc. -- only every 5th one. Thus those structures are unassigned and null. What is the purpose of the rem test???

Connectez-vous pour commenter.

Catégories

En savoir plus sur Animation dans Help Center et File Exchange

Produits


Version

R2015a

Community Treasure Hunt

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

Start Hunting!

Translated by