1

I want to convert this answer's code to imshow. It creates a movie in MOVIE2AVI by

%# preallocate
nFrames = 20;
mov(1:nFrames) = struct('cdata',[], 'colormap',[]);
%# create movie
for k=1:nFrames
   surf(sin(2*pi*k/20)*Z, Z)
   mov(k) = getframe(gca);
end
close(gcf)
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10);

My pseudocode

%# preallocate
nFrames = 20;
mov(1:nFrames) = struct('cdata',[], 'colormap',[]);
%# create movie
for k=1:nFrames
    imshow(signal(:,k,:),[1 1 1]) % or simply imshow(signal(:,k,:))
    drawnow
    mov(k) = getframe(gca);
end
close(gcf) 
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10);

However, this creates the animation in the screen, but it saves only a AVI -file which size is 0 kB. The file myPeaks1.avi is stored properly after running the surf command but not from imshow. I am not sure about the command drawnow.

Actual case code

%% HSV 3rd version 
% https://stackoverflow.com/a/29801499/54964
rgbImage = imread('https://i.stack.imgur.com/cFOSp.png');
% Extract blue using HSV 
hsvImage=rgb2hsv(rgbImage);
I=rgbImage;
R=I(:,:,1);
G=I(:,:,2);
B=I(:,:,3);
R((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
G((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
B((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
I2= cat(3, R, G, B);

% Binarize image, getting all the pixels that are "blue"
bw=im2bw(rgb2gray(I2),0.9999);

% The label most repeated will be the signal. 
% So we find it and separate the background from the signal using label.
% Label each "blob"
lbl=bwlabel(~bw);

% Find the blob with the highes amount of data. That will be your signal.
r=histc(lbl(:),1:max(lbl(:)));
[~,idxmax]=max(r);
% Profit!
signal=rgbImage;
signal(repmat((lbl~=idxmax),[1 1 3]))=255;
background=rgbImage;
background(repmat((lbl==idxmax),[1 1 3]))=255;

%% Error Testing
comp_image = rgb2gray(abs(double(rgbImage) - double(signal)));
if ( sum(sum(comp_image(32:438, 96:517))) > 0 )
    break; 
end

%% Video       
% 5001 units so 13.90 (= 4.45 + 9.45) seconds. 
% In RGB, original size 480x592. 
% Resize to 480x491
signal = signal(:, 42:532, :); 
% Show 7 seconds (298 units) at a time. 
% imshow(signal(:, 1:298, :)); 

%% Video VideoWriter
% movie2avi deprecated in Matlab
% https://stackoverflow.com/a/11054155/54964
% https://stackoverflow.com/a/29952648/54964
%# figure
hFig = figure('Menubar','none', 'Color','white');
Z = peaks; 
h = imshow(Z, [], 'InitialMagnification',1000, 'Border','tight');
colormap parula; axis tight manual off; 
set(gca, 'nextplot','replacechildren', 'Visible','off');
% set(gcf,'Renderer','zbuffer'); % on some Windows


%# preallocate
N = 40; % 491;
vidObj = VideoWriter('myPeaks3.avi');
vidObj.Quality = 100;
vidObj.FrameRate = 10;
open(vidObj);

%# create movie
for k=1:N
   set(h, 'CData', signal(:,k:k+40,:))
   % drawnow
   writeVideo(vidObj, getframe(gca));
end

%# save as AVI file
close(vidObj);

How can you substitute the drawing function by imshow or corresponding? How can you store the animation correctly?

Community
  • 1
  • 1
Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697

1 Answers1

3

Here is some code to try:

%// plot
hFig = figure('Menubar','none', 'Color','white');
Z = peaks;
%h = surf(Z);
h = imshow(Z, [], 'InitialMagnification',1000, 'Border','tight');
colormap jet
axis tight manual off

%// preallocate movie structure
N = 40;
mov = struct('cdata',cell(1,N), 'colormap',cell(1,N));

%// aninmation
for k=1:N
   %set(h, 'ZData',sin(2*pi*k/N)*Z)
   set(h, 'CData',sin(2*pi*k/N)*Z)
   drawnow
   mov(k) = getframe(hFig);
end
close(hFig)

%// save AVI movie, and open video file
movie2avi(mov, 'file.avi', 'Compression','none', 'Fps',10);
winopen('file.avi')

Result (not really the video, just a GIF animation):

animation


Depending on the codecs installed on your machine, you can apply video compression, e.g:

movie2avi(mov, 'file.avi', 'Compression','XVID', 'Quality',100, 'Fps',10);

(assuming you have the Xvid encoder installed).


EDIT:

Here is my implementation of the code you posted:

%%// extract blue ECG signal
%// retrieve picture: http://stackoverflow.com/q/29800089
imgRGB = imread('https://i.stack.imgur.com/cFOSp.png');

%// detect axis lines and labels
imgHSV = rgb2hsv(imgRGB);
BW = (imgHSV(:,:,3) < 1);
BW = imclose(imclose(BW, strel('line',40,0)), strel('line',10,90));

%// clear those masked pixels by setting them to background white color
imgRGB2 = imgRGB;
imgRGB2(repmat(BW,[1 1 3])) = 255;

%%// create sliding-window video
len = 40;
signal = imgRGB2(:,42:532,:);
figure('Menubar','none', 'NumberTitle','off', 'Color','k')
hImg = imshow(signal(:,1:1+len,:), ...
    'InitialMagnification',100, 'Border','tight');

vid = VideoWriter('signal.avi');
vid.Quality = 100;
vid.FrameRate = 60;
open(vid);

N = size(signal,2);
for k=1:N-len
    set(hImg, 'CData',signal(:,k:k+len,:))
    writeVideo(vid, getframe());
end

close(vid);

The result look like this:

signal_animation

Amro
  • 123,847
  • 25
  • 243
  • 454
  • 2
    @Masi: I'm not really a Mac person (the above was tested on Windows).. But if you're having trouble with the codecs, you can always just create the video with no compression in MATLAB (warning file can get really big for long movies!), and then convert the video as a post-processing step using an external tool like [FFmpeg](https://en.wikipedia.org/wiki/FFmpeg) or [MEncoder](https://en.wikipedia.org/wiki/MEncoder).. – Amro Apr 29 '15 at 19:32
  • 2
    @Masi: I should also say that [`movie2avi`](http://www.mathworks.com/help/matlab/ref/movie2avi.html) was recently deprecated in MATLAB, and the documentation now suggests using [`VideoWriter`](http://www.mathworks.com/help/matlab/ref/videowriter-class.html) instead (which should be able to encode H.264 mp4 videos) – Amro Apr 29 '15 at 19:36
  • 1
    @Masi [`imtool`](http://www.mathworks.com/help/images/ref/imtool.html) is really meant for viewing images not videos. Are you looking for [`implay`](http://www.mathworks.com/help/images/ref/implay.html)? Also there's [`vision.VideoPlayer`](http://www.mathworks.com/help/vision/ref/vision.videoplayer-class.html) from the CVST toolbox. Of course you can always just read the video frame-by-frame displayed as a series of regular images – Amro Mar 13 '16 at 21:27
  • 1
    @Masi I dont see how; when a plot is saved as a video it becomes just that "a video"! You cant pick graphic objects displayed, it is simply a series of frames/images. You gotta keep the original plots. If those are not available, your next option is some sort of digitization (think OCR and such). I'm thinking something like this: http://www.mathworks.com/matlabcentral/fileexchange/7173-grabit – Amro Mar 13 '16 at 23:42
  • 1
    @Masi nothing really, MATLAB has support for data cursors out of the box: http://www.mathworks.com/help/matlab/creating_plots/data-cursor-displaying-data-values-interactively.html. For example try `plot(cumsum(randn(50,1)), 's-'), datacursormode on` and interactively select data points... In your case, all you have to do is insert a `pause` inside the for-loop, something like: `for i=1:N, plot(..); pause; end`. – Amro Mar 14 '16 at 06:38
  • I will try the cursors pretty soon. How can you make the video play faster? I do `vid.FrameRate = 60*2^4;` but not faster. – Léo Léopold Hertz 준영 Mar 14 '16 at 16:35