How to show multiple images in the same figure and ensure that each image pixel is shown as a screen pixel?
7 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
I am doing some simple image processing and must dispay the resulting images without re-scaling. For example, I would like to do something like this:
in = imread('..\images\david.png');
out = dither(in);
subplot(1,2,1); imshow(in,'InitialMagnification',100); title('original')
subplot(1,2,2); imshow(out,'InitialMagnification',100); title('floyd steinberg')
Unfortunately, the 'InitialMagnification' parameter seems to be ignored when subplot is being used. If figure size is manipulated to be too small to fit both images, images are reduced in size (this is logical). If figure size is manipulated to be large enough to fit both images, images are resized to fit the window (this is very annoying). Since the size of image margins when using subplot does not seem to be documented, I can see no way of reliably generating exactly right size of the figure to ensure 100% scaling (and it does not sound like a healthy way of doing things in any case).
What would be a more robust way to display figure with multiple images shown at 100% each?
0 Commenti
Risposte (1)
DGM
il 14 Mag 2021
Modificato: DGM
il 18 Mag 2021
The 'InitialMagnification' parameter doesn't really work in any way that seems to be helpful for controlled resolution output. Instead of your 100% geometry reference being something predictable (like the image geometry) it's the axes geometry (whatever that is depending on the circumstances). This makes figure setup a bit of a chore. You need to get the parent axes geometry to match the image geometry. In this example, I did that by simply adjusting (recenter and scale) after each axes was generated.
inpict = rgb2gray(imread('sources/lena.tif'));
s = size(inpict); % 512x512 in this case
bnd = noisedither(inpict,'blue');
ord = orddither(inpict);
zfd = zfdither(inpict);
% generally, using 'bilinear' interpolation helps when scaling isn't integer
% may need to use tight borders so there's enough room for 1:1 display
options = {'interpolation','nearest','border','tight'};
h1 = subplot(1,3,1,'units','pixels');
h1.Position(1:2) = h1.Position(1:2) + h1.Position(3:4)/2 - s([2 1])/2;
h1.Position(3:4) = s([2 1]);
imshow(bnd,options{:});
h2 = subplot(1,3,2,'units','pixels');
h2.Position(1:2) = h2.Position(1:2) + h2.Position(3:4)/2 - s([2 1])/2;
h2.Position(3:4) = s([2 1]);
imshow(ord,options{:});
h3 = subplot(1,3,3,'units','pixels');
h3.Position(1:2) = h3.Position(1:2) + h3.Position(3:4)/2 - s([2 1])/2;
h3.Position(3:4) = s([2 1]);
imshow(zfd,options{:});
this gives:
right-click, view image to see that it's actually 1:1 scaling
You may have to do a lot more position wrangling to get your layout to look as you want.
2 Commenti
DGM
il 18 Mag 2021
Modificato: DGM
il 18 Mag 2021
Okay, That's totally my fault.
% test pattern to reveal interference
x = mod(1:250,2);
y = mod(1:210,2);
inpict = xor(x,y');
s = size(inpict);
set(gcf,'position',[0 0 640 480])
% generally, using 'bilinear' interpolation helps when view mag isn't integer
% may need to use tight borders so there's enough room for 1:1 display
options = {'interpolation','nearest','border','tight'};
h1 = subplot(1,2,1,'units','pixels');
h1.Position(1:2) = h1.Position(1:2) + h1.Position(3:4)/2 - s([2 1])/2;
h1.Position(3:4) = s([2 1]);
imshow(inpict,options{:});
h2 = subplot(1,2,2,'units','pixels');
h2.Position(1:2) = h2.Position(1:2) + h2.Position(3:4)/2 - s([2 1])/2;
h2.Position(3:4) = s([2 1]);
imshow(inpict,options{:});
I fell for the fact that position properties are specified [x y] and array geometry is [y x], so it would only work right if the image were square.
You might still need to adjust the position offset to get both images comfortably spaced/centered in the figure.
Vedere anche
Categorie
Scopri di più su Subplots in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!