MATLAB plot image margin removal and aspect ratio keeping

12 visualizaciones (últimos 30 días)
Nick Tsui
Nick Tsui el 17 de Nov. de 2022
Editada: Nick Tsui el 21 de Nov. de 2022
I have following code which basically trying to create a video based on a series images of size 256 X 256 X 3, where 3 is the RGB channls:
close all
clc
%% creating image volum
img = phantom(256);
img = repmat(img, [1,1,3]);
figure(1)
vidfile = VideoWriter('testVideo.mp4','MPEG-4');
open(vidfile);
%% loop to ceate images with different colors
for n = 1:120
a = n/120;
img(:,:,1) = img(:,:,2)*a;
img(:,:,3) = img(:,:,2)*(1-a);
imagesc(img), axis off
set(gca, 'Position', [0 0 1 1])
drawnow
videoFrame(n) = getframe(gcf);
writeVideo(vidfile,videoFrame(n));
end
close(vidfile)
However, although I got rid of the margin, I cannot get the image aspect ratio right. The image looks like this:
The goal is to remove the margin of the plot and maintain the aspect ratio of the images. In this case, it should be a square image with size 256 X 256 X3 that looks like this:
Any pointers? Some sample code would be very nice. Thanks
  1 comentario
DGM
DGM el 17 de Nov. de 2022
Why not save the image itself instead of saving a rescaled and padded screenshot of the image?

Iniciar sesión para comentar.

Respuesta aceptada

Nick Tsui
Nick Tsui el 21 de Nov. de 2022
Editada: Nick Tsui el 21 de Nov. de 2022
close all
clc
%% creating image volum
img = phantom(256);
img = repmat(img, [1,1,3]);
figure(1)
vidfile = VideoWriter('testVideo.mp4','MPEG-4');
open(vidfile);
%% loop to ceate images with different colors
for n = 1:120
a = n/120;
img(:,:,1) = img(:,:,2)*a;
img(:,:,3) = img(:,:,2)*(1-a);
imagesc(img), axis off
set(gca, 'Position', [0 0 1 1])
truesize(gcf,[256,256]) % adding this line here to make the image show true aspect ratio
drawnow
videoFrame(n) = getframe(gcf);
writeVideo(vidfile,videoFrame(n));
end
close(vidfile)

Más respuestas (2)

Walter Roberson
Walter Roberson el 17 de Nov. de 2022
nonblack = any(img,3);
horzprofile = any(nonblack, 1);
firstcol = find(horzprofile,1,'first');
lastcol = find(horzprofile,1,'last');
occupied_col = lastcol - firstcol + 1;
vertprofile = any(nonblack, 2);
firstrow = find(vertprofile,1,'first');
lastrow = find(vertprofile,1,'last');
occupied_row = lastrow - firstrow + 1;
occupied_space = max(occupied_row, occupied_col);
leftpad = floor((occupied_space - occupied_col)/2);
rightpad = occupied_space - occupied_col - leftpad;
uppad = floor((occupied_space - occupied_row)/2);
downpad = occupied_space - occupied_row - uppad;
padded = zeros(occupied_space, occupied_space, size(img,3), class(img));
padded(uppad+1:uppad+occupied_space, leftpad+1:leftpad+occupied_space, :) = img(firstrow:lastrow, firstcol:lastcol, :);
Now padded is a square image with no margin at all on one pair of sides and with possible margin on the other pair of sides, with the image centered.
The difference between this code and using imcrop() to crop slightly away from the occupied portion of the image, is that there is the theoretical possibility that the original occupied area was too close to an edge to extract padding evenly from both sides.
If you need the output to be a particular size, then you can imresize() it, knowing that padded is square to start with and so there will not be any aspect ratio changes if resized to a square.

DGM
DGM el 17 de Nov. de 2022
Editada: DGM el 17 de Nov. de 2022
Save the image, not a screenshot of the image. Saving things by capturing figures is a poorly controlled workflow and is often destructive to image quality.
% creating image volum
img = phantom(256);
img = repmat(img, [1,1,3]);
figure(1)
vidfile = VideoWriter('testVideo.avi'); % for some reason mp4 won't work in my version/env
open(vidfile);
% loop to ceate images with different colors
for n = 1:120
a = n/120;
img(:,:,1) = img(:,:,2)*a;
img(:,:,3) = img(:,:,2)*(1-a);
% this isn't necessary to construct the file
%imagesc(img), axis off
%set(gca, 'Position', [0 0 1 1])
%drawnow
writeVideo(vidfile,min(max(img,0),1));
end
close(vidfile)
The result (as a GIF)
  3 comentarios
DGM
DGM el 18 de Nov. de 2022
You can still just uncomment those lines to get a preview. I normally avoid displaying previews in a loop like that, since it tends to just slow everything down.
The point is that images of figures are not the original image. So long as it's the source image that's being saved, the display process is not necessary to save the image. You can still do both if you want.
Nick Tsui
Nick Tsui el 21 de Nov. de 2022
In this case I'd like to see the update of the image while generating the video. I don't really care the additional time it might take.
I think you answer it excellent, and it will be very useful when the plot is not needed to be seen.
Thank you very much.

Iniciar sesión para comentar.

Community Treasure Hunt

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

Start Hunting!

Translated by