MATLAB Answers

How to remove subplot grey space between images

224 ビュー (過去 30 日間)
Francisco Rogel
Francisco Rogel 2016 年 12 月 8 日
コメント済み: jiro 2016 年 12 月 8 日
I am trying to remove the space between and cannot figure it out. I have tried many ways and nothing is working. Is there a way to remove the space between or maybe a different way to approach this problem. The goal is to have the images touching in a grid like way
This is what prints:
theImage = imread('BarackObama.jpg');
%theImage = imread(image);
grayScaleImage = rgb2gray(theImage);
theGrayImage = grayScaleImage > 100;
[height, width, dim] = size(theImage);
numRecsAcross = 4;
numRecsDown = 4;
xmin = 1;
ymin = 1;
width = (width/numRecsAcross);
height = (height/numRecsDown);
xmin = uint16(xmin);
ymin = uint16(ymin);
width = uint16(width);
height = uint16(height);
s = 1;
for i = 1: numRecsDown
for j = 1: numRecsAcross
block = theImage(ymin+i-i:height*i, xmin+j-j:width*j, :);
color = uint8(mean(mean(block)));
rr = color(:,:,1);
gg = color(:,:,2);
bb = color(:,:,3);
RedChannel = 255 * uint8(theGrayImage);
BlueChannel = 255 * uint8(theGrayImage);
GreenChannel = 255 * uint8(theGrayImage);
r = ((double(rr))/255) * RedChannel;
g = ((double(gg))/255) * GreenChannel;
b = ((double(bb))/255) * BlueChannel;
rgbImage = cat(3, r, g, b);
subplot(numRecsAcross,numRecsAcross,s);
imshow(rgbImage);
s = s+1;
end
end

  0 件のコメント

サインイン to comment.

採用された回答

jiro
jiro 2016 年 12 月 8 日
編集済み: jiro 2016 年 12 月 8 日
One way is to use subplot or axes to manually specify a tight region. In your code, change the subplot line to
subplot('Position',[(j-1)*1/numRecsAcross (numRecsDown-i)*1/numRecsDown 1/numRecsAcross 1/numRecsDown])
This simply calculates and sets the coordinates ([left bottom width height]) of each set of axes.
Another way is if you have Image Processing Toolbox, you can use the montage function. Remove your call to subplot and imshow. Instead, build a MxNx3xK array of images inside your loop.
allImage(:,:,:,s) = rgbImage;
Then outside of the loop, plot using montage.
montage(allImage,'Size',[numRecsDown numRecsAcross])

  3 件のコメント

Francisco Rogel
Francisco Rogel 2016 年 12 月 8 日
thank you so much. It solved part of the problem I was having. It connected the images vertically. Is there a way to do this so they are connected horizontally as well?
jiro
jiro 2016 年 12 月 8 日
I assume you are seeing gaps in one direction because the aspect ratio of the image does not match up with that of the figure window. If you don't care about having 1:1 aspect ratio, you can change imshow with image.
jiro
jiro 2016 年 12 月 8 日
If maintaining the aspect ratio is important, you're better off using montage or doing what Chaya is recommending.

サインイン to comment.

その他の回答 (2 件)

Iddo Weiner
Iddo Weiner 2016 年 12 月 8 日
Try the following trick - instead of specifying the "real" exact number of subplots you need, specify a greater number and then for the 3rd input of subplot() specify a range instead of a number.
Example - say I want to plot 4 panels, and want smaller margins between panels. So instead of going:
subplot(2,2,1)
...
subplot(2,2,4)
I'll define: subplot(M,N,Xi) - where M,N are the dimensions of the plot (and I will suggest setting them to an integer larger than 2), and Xi is a vector defining the location of subplot i. Here's an example in which M=N=4 (data is random):
figure
subplot(4,4,[1,2,5,6])
bar(normrnd(0,1,100,1))
subplot(4,4,[3,4,7,8])
histogram(normrnd(0,1,100,1))
subplot(4,4,[9,10,13,14])
bar(normrnd(0,1,100,1))
subplot(4,4,[11,12,15,16])
histogram(normrnd(0,1,100,1))
Now, you can play around with M and N (don't forget to adjust the range accordingly). This won't actually change the absolute dimensions of the whole figure but it will get rid of the margin space between panels. Of course - the bigger M,N are - the less margin you'll have..
Hope this helps

  3 件のコメント

Francisco Rogel
Francisco Rogel 2016 年 12 月 8 日
I sorry but I am not understanding. What is the vector doing in this case?
Iddo Weiner
Iddo Weiner 2016 年 12 月 8 日
Really straightforward - it's the same way this works for any array in matlab: (1,1) is 1, (1,2) is 2 and so on.. If you specify a range, the subplot will stretch on all values in that range, thus minimizing the grey fraction between panels.
Run the example I posted for visual clarification
jiro
jiro 2016 年 12 月 8 日
There's also a similar example in the documentation:

サインイン to comment.


Chaya N
Chaya N 2016 年 12 月 8 日
編集済み: Chaya N 2016 年 12 月 8 日
The best (and possibly only) way to do that would be to create a new, larger image where you combine all your smaller subplots in the order that you need. For example, say you had four images A,B,C and D all of size m-by-n and you wanted them in a grid, then you would create a new image X of size 2m-by-2n and pass values as:
X(1:m, 1:n) = A;
X(1:m, n+1 : 2*n) = B;
X(m+1 : 2*m, 1:n) = C;
X(m+1 : 2*m, n+1 : 2*n) = D;
and then plot X.

  4 件のコメント

表示 1 件の古いコメント
Chaya N
Chaya N 2016 年 12 月 8 日
You would need to know how many subplots you have and their individual sizes (I am assuming here that they are all the same size). Then you can go in and create a bigger image as in my example above.
Image Analyst
Image Analyst 2016 年 12 月 8 日
Francisco, Chaya is stitching the images together, to create a much bigger image, and displaying them in one axes, not multiple ones with subplots. The line he left off was this
imshow(X)
You could also do
bigImage = [A,B;C,D]
imshow(bigImage);
which is essentially what he did.
jiro
jiro 2016 年 12 月 8 日
In your code you can do the following. I'm just including code at the end.
rgbImage = cat(3, r, g, b);
acrossImages{j} = rgbImage;
s = s+1;
end
downImages{i} = cat(2,acrossImages{:});
end
bigImage = cat(1,downImages{:});
imshow(bigImage)

サインイン to comment.

サインイン してこの質問に回答します。

タグ


Translated by