Create a video with imagesc (VideoWriter)

Hello,
I've got a program that looks pretty much like that, and I would like to create a video resulting of all the plots created during the k iteration:
for k=1:10000
.%calculations
.%calculations
W=reshape(w,y,x); %Where W is a Matrix
lsd=imagesc(W);
drawnow
end
Any clue? Thank you

 Accepted Answer

See my attached demo which creates a surf plot (you could easily adapt it to display an image), then builds a video frame by frame.

4 Comments

Thanks it worked!
The only thing now is that I wish to record several hours of plot, but the 29s of film I get already weight 346Mo.
(I used :
writerObj = VideoWriter('Film.avi','Uncompressed AVI');
)
Is there a way to decrease the size WITHOUT having a really bad film quality ?(I tried without 'Uncompressed AVI' already, but way too pixelized)
actually I just tried this:
numberOfFrames=10000;
allTheFrames = cell(numberOfFrames,1);
vidHeight = 10000;
vidWidth = 10000;
allTheFrames(:) = {zeros(vidHeight, vidWidth, 3, 'uint8')};
allTheColorMaps = cell(numberOfFrames,1);
allTheColorMaps(:) = {zeros(256, 3)};
writerObj = VideoWriter('Film.avi');
open(writerObj);
set(gcf, 'renderer', 'zbuffer');
y=300;
x=1000;
for k=1:numberOfFrames
%Calculation
W=reshape(w,y,x);
lsd=imagesc(W);
drawnow
thisFrame = getframe(gca);
writeVideo(writerObj, thisFrame);
myMovie(k) = thisFrame;
end
close(writerObj)
but I got the following error message: "Frame must be 344 by 343"
Can you help me with that?
Remember to pass in 'FrameRate' when you call VideoWriter. The default is 30 fps, and if your data is intended to be faster than that then the resulting movie would be longer duration than you expected.
VideoWriter does not do well with compression. I would recommend post-processing with a transcoder.
getframe() has a variable sized output unless you specify the rectangle at the time you getframe(). Axes vary slightly in size depending on the data, so getframe() will record varying sizes of data.
If you had used the mat2gray() that I suggested then that would not be an issue.
The size of thisFrame seems like it changed. During this lengthy processing time, did you perhaps move or resize the window?

Sign in to comment.

More Answers (2)

imagesc(W) displays the given data, W, after changing the color scaling to be from min(W(:)) to max(W(:)) so that the minimum value in W gets mapped to the first color in the color map and the maximum value in W gets mapped to the last color in the color map.
imagesc(W) does not itself put up any color map: whatever color map was in place would be used.
The rescaling that imagesc does from min to max is the same as what you would get if you used
Wscaled = mat2gray(W);
mat2gray() is a pretty obscure name for this functionality, but as of R2017b you can instead use
Wscaled = rescale(W);
Either way, Wscaled would be values in the range 0 to 1.
You can then im2uint8() to get values in the range 0 to 255, and you can then ind2rgb() passing in a color map in order to get out an RGB image that represents the data. After that you can write the RGB as a video frame by using the functionality of videowriter()

5 Comments

Thanks for your answer, unfortunately I only have a student license wich doesn't contain im2uint8() fonction. Is there any way around?
im2uint8() is part of the Image Processing Toolbox. That is included in the Student Suite, which you probably have.
In any case, for this purpose, you could probably use
ind2rgb( uint8(Wscaled * (256*(1-eps))), YourColormapGoesHere )
Thank you Walter, I rather use your way as it looks shorter to me in terms of code lines. I'm just a beginner with matlab so not everthing you said is innate to me. I think I could really use some help with the code writing itself.
That's what I've got so far following your lead:
video = VideoWriter('newfile.avi', 'Uncompressed AVI');
video.FrameRate = 60;
open(video)
y=300;
x=1000;
for k=1:10000
.%calculations
.%calculations
W=reshape(w,y,x); %Where W is a Matrix
Wscaled = rescale(W);
RGB=ind2rgb( uint8(Wscaled * (256*(1-eps))), parula );
drawnow
writeVideo(video,RGB)
end
close(video)
Doesn't work well, but I'm a bit lost, I don't know if I used the commands properly or how to modify them...
By the way I should probably have had a floor() call inside the uint8() call
uint8( floor(Wscaled * (256*(1-eps))) )
We do not have your full code, and you did not show any error message, so it is difficult for us to guess what "Doesn't work well" means.

Sign in to comment.

io mb
io mb on 30 Mar 2019
I found a way to record W, letting imagesc() in the code :
video = VideoWriter('newfile.avi', 'Uncompressed AVI');
open(video)
for k=1:10000
.%calculations
.%calculations
W=reshape(w,y,x); %Where W is a Matrix
lsd=imagesc(W);
drawnow
F(k) = getframe(gcf);
writeVideo(video,F)
end
close(video)
The problem now is, that for 3 minutes realtime recording I get a 11 minutes video wich loop from k=0 to the new k (it gets every time further).

1 Comment

that's because you're writing the entire 'F' at each iteration.
i.e. should write the following line outside (rather than inside) the 'for' loop :
writeVideo(video,F)

Sign in to comment.

Categories

Find more on Convert Image Type in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!