Imagesc movie with multiple axes/matrices

I would like to do the same as this person:
Although, I want multiple axes/matrices in the same movie. I wrote the following code to achieve this:
for i = 1:l
% Switch to first axes
axes(syy_ax)
imagesc(syy(:,:,i))
colorbar
% Switch to second axes
axes(wd_ax)
imagesc(wd(:,:,i))
colorbar
all_mov(i) = getframe;
end
where syy_ax and wd_ax are axis handles, and syy and wd are 3D matrices. I realize how slow this is, but don't know an alternative. I tried specifying the axis in the plot function, but I don't think imagesc supports this. Could anyone suggest another way, please?

1 Commento

Have you considered concatenating the matrices into 1 matrix if possible?
Also the post you refer to is trying to display something over time, while your use of getframe implies you want to make a movie object?

Accedi per commentare.

Risposte (3)

Image Analyst
Image Analyst il 4 Gen 2013
Modificato: Image Analyst il 4 Gen 2013
Well how slow is it? I would think it would be too fast, if anything, and you'd want to put in pauses so the person viewing it will see more than a blip as the movie goes whizzing by. Just how many frames per second is it doing? Or is it so slow we're talking seconds per frame?
Also I'm puzzled by you using imagesc() rather than imshow()? So, you're okay with that bizarre, arbitrary, default colormap that imagesc() applies? Just by the luck of the draw, that happens to be the best colormap for your images? I'm surprised - you're lucky. For me, almost always I don't want the default colormap that imagesc chooses.
Also, please see the FAQ: http://matlab.wikia.com/wiki/FAQ#How_can_I_create_a_movie_from_my_MATLAB_figures.3F You can use export_fig() to save your figure, with both axes on it, out to files that can then be made into frames of your movie.
Its slow, just under two frames per second. Here's a copy of the complete code.
fig1 = figure('color','white');
maximize(fig1)
syy_ax = axes;
set(syy_ax,'Position',[0.05 0.05 0.4 0.95])
set(syy_ax,'XTick',[],'YTick',[],'XColor','w')
hold(syy_ax)
%
wd_ax = axes;
set(wd_ax,'Position',[0.55 0.05 0.4 0.95])
set(wd_ax,'XTick',[],'YTick',[],'XColor','w')
hold(wd_ax)
max_syy = max_val(syy);
max_wd = max_val(wd);
syylims = [0 ceil(max_syy)];
wdlims = [0 ceil(max_wd)];
s = size(syy);
l = s(3);
for i = 1:l
axes(syy_ax)
imagesc(syy(:,:,i),syylims)
colorbar
%
axes(wd_ax)
imagesc(wd(:,:,i),wdlims)
colorbar
all_mov(i) = getframe;
end
maximize and max_val are custom functions that only run once outside the loop. My matrices (syy and wd) are both size = [20 10 3200]. I am eventually going to need larger matrices and 3-5 more axes in the figure. I just thought because of how slow it is processing I am doing something terribly wrong.
In regards to the unattractive coloring, I don't mind so much right now. The resulting images are color contours of stress and work values. I plan on using interp2 to smooth it out and can change the colormap then if necessary. Any thoughts? Thanks so much!

8 Commenti

This is somewhat faster:
for k = 1:l
if k == 1
h1 = imshow(syy(:,:,k), [], 'Parent', syy_ax);
else
set(h1, 'CData', syy(:,:,k));
end
colorbar('Peer', syy_ax);
if k == 1
h2 = imshow(wd(:,:,k), [], 'Parent', wd_ax);
else
set(h2, 'CData', wd(:,:,k));
end
colorbar('Peer', wd_ax);
drawnow;
% all_mov(k) = getframe;
end
A small improvement to above is run loop from k = 2:l and take out if statements. Also maybe initialize all_mov first (if you actually need it for anything).
Yep, agreed. Actually, the main reason it's faster is I took out the all_mov line - that was the line that was taking up the vast majority of time. It doesn't even take that long anyway - some people wait hours and hours to create a movie frame by frame. They just let it run overnight or whatever, but once you have the movie created, then that's what counts and it plays in real time. So they watch the movie AFTER it's been created, not WHILE it's being created, so the time doesn't really matter that much.
Thanks very much! I'll need some time to try using imshow with export_fig and do better at preallocating memory if necessary. Then I'll get back with you. Regarding the code I posted above, I did let the process run overnight and I just tried to play it. It played, but the figure and axes were the default size and only one image was partially displayed. I used the command: movie(all_mov,1,200). Why did the movie not retain the axes and figure properties as defined in the code? Any simple explanation for this?
It could be that subsampling for the display got rid of some single pixel lines like in your axes. Try making the window bigger. Regarding partial display, perhaps put in a drawnow or pause(0.1) to give the image time to be shown before it gets saved.
You should be aware of what getframe actually saves. f = getframe gets the current axis, so may exclude labels and other axes. Also does not save properties, just what it looks like. http://www.mathworks.nl/support/solutions/en/data/1-1BSP6/?solution=1-1BSP6
I had some success using the following code. It implements, imshow, the 'CData' property and uses export_fig instead of getframe. I altered my strategy for now to include a plot instead of another imshow on the second axis. I think the plot command within the loop is a slow operation (although not slower than export_fig). Is there an alternative that is similar to the 'CData' property? Also, would you please recommend a freeware that can string together my png's into a movie? Apparently video encoding is a huge area, and I hope to stay out of that one! Thanks!
fig1 = figure('color','white');
maximize(fig1)
pix_array = syy_pix_half;
plot_array = -syy_mcs_half;
img_ax = axes;
set(img_ax,'Position',[0.45 0.15 0.6 0.7])
set(img_ax,'XTick',[],'YTick',[],'XColor','w')
set(img_ax,'DataAspectRatio',[1 1 1])
hold(img_ax)
%
pl_ax = axes;
set(pl_ax,'Position',[0.10 0.15 0.4 0.75])
set(pl_ax,'XLim',[0 12000],'YLim',[0 8e6])
xlabel('Steps')
ylabel('Stress (Pa)')
hold(pl_ax)
max_arr = max_val(pix_array);
arrlims = [0 ceil(max_arr)];
s = size(pix_array);
l = s(3);
h1 = imshow(pix_array(:,:,1), arrlims, 'Parent', img_ax);
colorbar('peer',img_ax,'SouthOutside');
for i = 6000:7000
set(h1, 'CData', pix_array(:,:,i));
plot(plot_array(1:i),'Parent',pl_ax);
drawnow
filename = ['img_' num2str(i)];
export_fig(filename)
end
You can do it in MATLAB with avifile or videowriter, getframe should be faster than export_fig if you intialize a struct array.
That aside, freeware options that come to mind are imagemagick & ffmpeg (both commandline interfaces I believe).
If you insist on saving images, saveas() might be faster than exportfig.
Lastly, either when dumping images or grabbing frames, you may suppress the visible output to speed things up.

Accedi per commentare.

I dont use colorbars often, so this was my initial idea without them:
syy = reshape(syy,[size(syy,1) size(syy,2) 1 size(syy,3)]);
wd = reshape(wd,[size(wd,1) size(wd,2) 1 size(wd,3)]);
DATA = [syy wd]; clear syy wd %data is now formatted (n-m-1-p) and concatenated
MOV = immovie(DATA,jet(256)); %or some other map (< 256).
close;
Note you may need to convert DATA to indexed format (i.e. integers). A quick fix for this would be real2rgb (from the FEX) then rgb2ind.
fps = 5; %framerate
N = 1; %iterations
movie(MOV,N,fps) %Plays movie MOV, N times at fps frames per second.

Categorie

Richiesto:

il 4 Gen 2013

Community Treasure Hunt

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

Start Hunting!

Translated by