How to show multiple images in the same figure and ensure that each image pixel is shown as a screen pixel?
7 ビュー (過去 30 日間)
古いコメントを表示
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 件のコメント
回答 (1 件)
DGM
2021 年 5 月 14 日
編集済み: DGM
2021 年 5 月 18 日
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 件のコメント
DGM
2021 年 5 月 18 日
編集済み: DGM
2021 年 5 月 18 日
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.
参考
カテゴリ
Help Center および File Exchange で Subplots についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!