53 views (last 30 days)

Show older comments

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

jiro
on 8 Dec 2016

Edited: jiro
on 8 Dec 2016

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])

jiro
on 8 Dec 2016

Iddo Weiner
on 8 Dec 2016

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

Chaya N
on 8 Dec 2016

Edited: Chaya N
on 8 Dec 2016

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.

jiro
on 8 Dec 2016

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)

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

Start Hunting!