Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
614 views
in Technique[技术] by (71.8m points)

video - To refresh imshow in Matlab?

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('http://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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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('http://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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...