MATLAB Answers

Mike
0

getframe issue in for-loop.

Asked by Mike
on 19 Jun 2013
I'm trying to animate an image and save it as a .gif file. After crafting an equation, I use imshow within a loop and capture successive frames with getframe, which I then convert to an image and again into an indexed file. I've tried other approaches to this but always came up with the same problem. Even the sample 'peaks/surf' function in Matlab's documentation on creating animated gifs doesn't output the correct .gif file (meaning it lags because of repeated frames).
The problem I'm having is that it appears that at seemingly random times, getframe captures the previous frame rather than the current one. The issue does not occur on other computers I've tried it on, so I have a feeling it's a problem with the communication between my cpu and graphics processor (Mac OSX 10.7.5, Macbook Pro w Retina display 17"). It's almost as if the CPU is processing images faster than the GPU can send them to my monitor. Any insights on this theory are appreciated. I've tried updating Java and Matlab (v.2012a) to no avail. I also installed the recent updates for OSX, one of which addressed frame refresh rates for video games.
When I give the computer some time between the imshow and getframe operations by uncommenting the 'close' command (see code below) so that getframe cannot possible capture the wrong image, the .gif comes out perfectly. Otherwise, I get repeated frames in the output (see images in imgur album). The issue I have with using 'close' is that it really lengthens the execution time (about 4x).
See: http://imgur.com/a/pWCE5 to understand exactly what I mean.
My code is below, which is likely to produce the desired result without uncommenting 'close' on most people's computers. I realize it's a tough issue to tackle because it seems to be related to my GPU but I'm at a loss for what to do here... Thank you for your time.
clear all
tic
endloop=26;
for i=1:endloop % defines height values for next loop
if i<(endloop/2 + 2)
f(i)=3+i;
else
f(i)=f(i-1)-1;
end
end
[x,y]=meshgrid(-256:255,-256:255); % create grid
z=sqrt(x.^2+y.^2); % define circle
for k=1:endloop
c=(z<f(k));
cf=fftshift(fft2(c)); % apply transform
fl = log(1+abs(cf)); fm = max(fl(:));
imshow(im2uint8(fl/fm));
frame=getframe; % close;
im=frame2im(frame);
[imind,map]=rgb2ind(im,256);
if k==1
imwrite(imind,map,'circle3.gif','DelayTime',0.1,'LoopCount',inf);
else
imwrite(imind,map,'circle3.gif', 'DelayTime',0.1, 'WriteMode', 'append');
end
end
close all
toc

  0 Comments

Sign in to comment.

1 Answer

Answer by Ben Tordoff on 20 Jun 2013
 Accepted Answer

Hi Mike,
you could try inserting a 'drawnow' just before the 'getframe'. This tells all MATLAB graphics and events to flush. There are some circumstances where I have found that a 'drawnow' (or even multiple 'drawnow's) sorts out refresh problems.
Ben

  1 Comment

Ben, thank you. That worked splendidly.

Sign in to comment.