Why does video slow down towards the end?
2 ビュー (過去 30 日間)
古いコメントを表示
Hello,
I've written a code to display circles on my video every 100th frame (9000 frames in total, 25fps). At the first frame, I draw 2 circles on the image and store the vertices of these circles. Later on, I display these circles again at each 100th frame. I've read somewhere that plotting could slow down the execution of this code, so could this be the reason why my video is playing way slower at the end compared to the beginning?
vid = VideoReader(video_name);
curr_axes = axes;
hfig = figure(1);
set(hfig,'WindowButtonDownFcn',@count_the_clicks) %Use callback to click
framecount = 0;
%Play video
while vid.hasFrame()
temp = vid.readFrame();
framecount = framecount + 1;
image(temp,'Parent',curr_axes);
%Draw 2 circles on the first videoframe, so that you can plot these circles
%again at each 100th frame (see below).
if framecount == 1
hfig6 = copyobj(hfig,0);
set(hfig6,'visible','off')
figure(hfig);
disp('Carefully select 2 objects you want to label by drawing ellipses')
p2 = imellipse;
vert_p2 = getVertices(p2);
wait(p2);
p3 = imellipse;
vert_p3 = getVertices(p3);
wait(p3);
vert_p_all = horzcat(vert_p2',vert_p3')';
end
curr_axes.Visible = 'off';
pause(0.55/vid.FrameRate)
%At each 100th frame, plot the drawn circles
if mod(framecount,100)==0
hold on
scatter(vert_p_all(:,1),vert_p_all(:,2),16,'oy','filled')
p1 = imrect; %Double-click to proceed to the next 100 frames of the video
wait(p1);
end
end
0 件のコメント
回答 (1 件)
Aman Vyas
2020 年 8 月 12 日
編集済み: Aman Vyas
2020 年 8 月 12 日
Hi,
You can try either of the following or both of the following as both would result in preventing the lag or delay in the video as it progresses.
1) You are trying to store images in the axes, since function image() is used.Try inserting a "cla('reset')" just before and see if that speeds it up. Otherwise you may be loading all of the images in there instead of replacing them.
2) Also, you have used "hold on" and haven't used "hold off" because of which all of the images are loaded to the same axes everytime and slows down as video progresses. Try using "hold off" function in the loop.
For more info on hold off function you can visit the links:
Hope it helps !
2 件のコメント
Miguel Fernando
2024 年 12 月 28 日
Not using hold off slowed the video processing so much that Matlab couldn't finish in one night a very short video with a few frames. Thank you very much for your help!
DGM
2024 年 12 月 28 日
It would probably be faster yet to keep the handles for the image and scatter objects and simply update them each frame instead of destroying them and recreating them each frame.
For instance, update the CData property of the image() object, and the XData,YData of the scatter() object.
The general theme is simple:
- The only objects in the figure should be those necessary. Don't accumulate unused objects.
- Change only what's necessary each frame.
- Property edits are usually faster than object creation. (I don't know of a good exception)
video_name = 'rhinos.avi'; % the file name
playbackspeed = 1; % the normalized playback speed
pauseeveryN = 50; % pause every N frames
vid = VideoReader(video_name);
curr_axes = axes;
hfig = figure(1);
framecount = 0;
% Play video
for f = 1:vid.NumFrames % there's no good reason to use a while loop
thisframe = vid.readFrame(); % use a meaningful name
% Draw 2 circles on the first videoframe
if f == 1
% create the image object once
hi = image(thisframe,'Parent',curr_axes);
msg = ['Carefully select 2 objects you want to label by drawing ellipses. ' ...
'Double-click on each ellipse to finish drawing it.'];
disp(msg)
p2 = imellipse(curr_axes); %#ok<*IMELLPS>
wait(p2); % wait until the user is done first
vert_p2 = getVertices(p2); % save _after_ the changes are made, not before!
p3 = imellipse(curr_axes);
wait(p3);
vert_p3 = getVertices(p3);
% just concatenate them the right way around to begin with
vert_p_all = [vert_p2; vert_p3];
% we don't need these for anything
% ... unless the whole pausing thing was a workaround for losing these
delete([p2 p3])
else
% update the image object
hi.CData = thisframe;
end
pause(1/(playbackspeed*vid.FrameRate))
% Every Nth frame, plot the drawn circles
% i have no idea why this is done. it seems like this is unnecessary
% and was probably only being done because the imellipse objects were buried.
if mod(f,pauseeveryN)==0
if f == pauseeveryN
% create the scatter during the first pause
hold on
hs = scatter(vert_p_all(:,1),vert_p_all(:,2),16,'oy','filled');
else
% and simply just change its visibility every other time
hs.Visible = 'on';
end
% just pause and wait for user to hit enter
% instead of drawing unnecessary random objects as a pausing mechanism
disp('Press Enter to Continue')
pause
% hide it on all other frames
hs.Visible = 'off';
end
end
参考
カテゴリ
Help Center および File Exchange で Tracking and Motion Estimation についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!