getframe function not centering properly when capturing image with overlays

11 次查看(过去 30 天)
I regularly have to analyze filmed experiments frame by frame and annotate each image with text and and overlaid plots, but I find that when I try to recombine the frames into a video with the getframe command the frame that is returned is either not centered on the image, or has a large margin added. Interestingly, the centered to off centered switch happens at a margin width of 25. I would ideally like to have no margins on the frame, ie have the returned frame be the same size as the original, but so far am having no luck.
I know I can modify the image directly and use im2frame, but this method is more cumbersome and not as versatile for the annotations I need to make so I'm hoping there is a way to make getframe work.
Below is an example code to illustrate the problem. Thanks for the help!
clear; close all; clc
fig1=figure;
imshow('peppers.png')
hold on
plot(0:512,192+20*sin((0:512)/10),'y')
drawnow
hold off
ax = gca;
ax.Units = 'pixels';
pos = ax.Position;
marg1 = 26; % 26 centers image, but margin is too large
rect1 = [-marg1, -marg1, pos(3)+2*marg1, pos(4)+2*marg1];
f1=getframe(ax,rect1);
marg2 = 25; % 25 doesn't center image
rect2 = [-marg2, -marg2, pos(3)+2*marg2, pos(4)+2*marg2];
f2=getframe(ax,rect2);
f3=getframe(ax);
f4=getframe(fig1);
title('original')
figure('Color',[.5 .5 .5])
montage({frame2im(f1),frame2im(f2),frame2im(f3),frame2im(f4)},...
'BorderSize',[10 10],'BackgroundColor',[0.5 0.5 0.5])
title('ax grabs with margins of 26 (top left), 25 (top right), 0 (lower left) and fig grab (lower right)')

回答(1 个)

Dheeraj
Dheeraj 2023-9-6
Hi,
I understand you’re encountering a problem with added margins while stitching the frames back after making modifications because of how you’re using the “getframe” function. The default behaviour of “getframe” is to capture the entire figure, including any additional margins introduced by the axes.
To get frames without margins and the same size as the original image, you can adjust the position of the axes and then use getframe.
Here’s the modified code snippet with “getframe’ applied to a single frame.
clear; close all; clc
% Create a figure
fig1 = figure;
imshow('peppers.png')
hold on
plot(0:512, 192 + 20 * sin((0:512) / 10), 'y')
drawnow
hold off
% Get the axes and adjust its position
ax = gca;
ax.Units = 'normalized'; % Use normalized units
ax.Position = [0, 0, 1, 1]; % Set the axes position to fill the entire figure
% Set the figure size to match the axes
fig1.PaperUnits = 'inches';
fig1.PaperPosition = [0, 0, ax.Position(3), ax.Position(4)];
% Capture frames without margins
f1 = getframe(fig1);
close(fig1); % Close the figure
% Create a montage of the captured frames
montage({frame2im(f1)}, 'BorderSize', [0 0], 'BackgroundColor', [.5 .5 .5])
title('Frame captured without margins')
In this code, the figure and axes properties are set to ensure they fill the entire figure without margins. Figure's size is adjusted to match the axes' size. This way, when you capture frames using getframe, you will get frames how you intended to have them.
You can refer to the below MATLAB’s documentation to have a better understanding of “getframe” function and its capabilities.
Hope this helps!

类别

Help CenterFile Exchange 中查找有关 Animation 的更多信息

产品


版本

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by