How to lock image dimensions in MATLAB - image

So I have this matrix in MATLAB, 200 deep x 600 wide. It represents an image that is 2cm deep x 6cm wide. How can I plot this image so that it is locked into proper dimensions, i.e. 2cm x 6cm? If I use the image or imagesc commands it stretches it all out of shape and shows it the wrong size. Is there a way to lock it into showing an image where the x and y axes are proportional?
Second question, I need to then set this image into a 640x480 frame (20 pixel black margin on left and right, 280 pixel black margin on bottom). Is there a way to do this?

To keep aspect ratio, you can use axis equal or axis image commands.
Quoting the documentation:
axis equal sets the aspect ratio so that the data units are the same in every direction. The aspect ratio of the x-, y-, and z-axis is adjusted automatically according to the range of data units in the x, y, and z directions.
axis image is the same as axis equal except that the plot box fits tightly around the data`
For second question:
third_dimension_size=1; %# for b&w images, use 3 for rgb
framed_image=squeeze(zeros(640,480,third_dimension_size));
framed_image(20:20+600-1,140:140+200-1)= my_600_200_image;
imagesc(framed_image'); axis image;

set(gca,'DataAspectRatio',[1 1 1])
Second question:
new_image = zeros(480,640);
new_image(20:(200+20-1),20:(600+20-1)) = old_image;

As an alternative to the other answers, you might want:
set(gca, 'Units', 'centimeters', 'Position', [1 1 6 2])
Make sure you do this after plotting the image to get the other axis properties correct.
For the second question, take care with the number of colour channels:
new_image = zeros(480,640, size(old_image));
new_image(20:(200+20-1),20:(600+20-1),:) = old_image;

Related

How do I save just figure image without any graduation and numbers on x, y axis?

I used matlab code.
img = imread('cmap3.png')
map = jet(256)
ind = rgb2ind(img,map)
colormap(map)
cm = colormap('gray)
image(ind)
Through above code, I got the .
I want to save just the gray scale image without any graduations and numbers on x,y axis.
How do I remove them and save gray scale image?
If you use imwrite, you won't save the axes' labels.
For actual plots, there exists a different solutions, eg. described here: set the axis to start at the very left bottom corner so that there is no space left for descriptions: set(gca, 'Position',[0 0 1 1]). Than you can even use print to save the image/figure.

Maintain same imrect position at different resolution

I'm using the function imrect, to crop the ROI in image for further processing. I have two images to compare (imagine they are the same but with different resolution):
Image 1: 1024x1024 pixels and Image 2: 2000x2000 pixels. The pixel value is known, so I don't want to resize images. At first I select the ROI in the image 1, using the draggable rectangle:
imshow(image1);
h=imrect(gca,[10 10 200 200]); position=wait(h);
I=imcrop(image1,position);
Then I open image2 which is the same image at different resolution. Now I need to calculate the position of imrect so it would cover the same ROI. The position of ROI in this image is different because of different resolution. So the position of the imrect should be different as well.
For image2 I want to run a code like this, but I don't know how to estimate the position variable:
imshow(image2);
I2=imcrop(image2,unknown_position);
How can I estimate the position in image2?
Maths to the rescue!
x_2 = x_1 * width_2 / width_1
y_2 = y_1 * height_2 / height_1

How to do bar plot in the same scale and dimension as an image?

I have an image, then I am projecting it on one of it's edges by some aggregation functions like mean. I am getting 1D digitized data this way. How to plot it exactly below source image in exactly the same horizontal or vertical scale?
Sample code:
% loading image
image = imread('..\..\FruitSample_small.png');
%computing gradients
dx=double(image(1:end-1,2:end,:))-double(image(1:end-1,1:end-1,:));
dy=double(image(2:end,1:end-1,:))-double(image(1:end-1,1:end-1,:));
% computing total magnitude
a=sqrt(sum(dx.^2,3)+sum(dy.^2,3));
% projection on bottom
h = mean(a,1);
% drawing
figure;
subplot(2,1,1);
imshow(image);
subplot(2,1,2);
bar(h);
axis image;
I want bar plot here to be of the same width as image above. Also I want histogram to spread exactly to the same horizontal coordinate, as image does.
The challenge here is that "axis image" enforces an aspect ratio on the image axis, which allows the display size of the image to vary from its set dimensions. My suggestion is to forget the auto-sizing capabilities that come from normalized units, and adjust the sizes based on pixel sizing. If you set the size of the image axis to exactly the size of the image in pixels, then it will have the correct aspect ratio, and you can use the same size for the bar plot.
load clown; % use a built-in demo image. Note the image is now in X
%computing gradients
dx=double(X(1:end-1,2:end,:))-double(X(1:end-1,1:end-1,:));
dy=double(X(2:end,1:end-1,:))-double(X(1:end-1,1:end-1,:));
% computing total magnitude
a=sqrt(sum(dx.^2,3)+sum(dy.^2,3));
% projection on bottom
h = mean(a,1);
% drawing
figure;
subplot(2,1,1);
imagesc(X);
size_x = size(X,2);
size_y = size(X,1);
set(gcf, 'Units', 'pixels')
fp=get(gcf, 'Position');
set(gca, 'Units', 'pixels');
set(gca, 'Position', [(fp(3)-size_x) / 2, (fp(4)-size_y) / 2 + 100, ...
size_x, size_y]);
subplot(2,1,2);
bar(h);
set(gca, 'Units', 'pixels');
set(gca, 'Position', [(fp(3)-size_x) / 2, 100, size_x, 100]);
set(gca, 'XLim', [1 size_x]);
I'm computing the offsets automatically from the figure size, to center the results on the figure. This is not resizeable. You'd have to rerun the set('Position') stuff to readjust the locations if you resize the figure itself. If you need it to be dynamically resizeable, you'd have to add a handler for a resize event, and adjust the sizes on every resize.

How can I "plot" an image on top of another image with a different colormap?

I've got two images, one 100x100 that I want to plot in grayscale and one 20x20 that I want to plot using another colormap. The latter should be superimposed on the former.
This is my current attempt:
A = randn(100);
B = ones(20);
imagesc(A);
colormap(gray);
hold on;
imagesc(B);
colormap(jet);
There are a couple of problems with this:
I can't change the offset of the smaller image. (They always share the upper-left pixel.)
They have the same colormap. (The second colormap changes the color of all pixels.)
The pixel values are normalised over the composite image, so that the first image changes if the second image introduces new extreme values. The scalings for the two images should be separate.
How can I fix this?
I want an effect similar to this, except that my coloured overlay is rectangular and not wibbly:
Just change it so that you pass in a full and proper color matrix for A (i.e. 100x100x3 matrix), rather than letting it decide:
A = rand(100); % Using rand not randn because image doesn't like numbers > 1
A = repmat(A, [1, 1, 3]);
B = rand(20); % Changed to rand to illustrate effect of colormap
imagesc(A);
hold on;
Bimg = imagesc(B);
colormap jet;
To set the position of B's image within its parent axes, you can use its XData and YData properties, which are both set to [1 20] when this code has completed. The first number specifies the coordinate of the leftmost/uppermost point in the image, and the second number the coordinate of the rightmost/lowest point in the image. It will stretch the image if it doesn't match the original size.
Example:
xpos = get(Bimg, 'XData');
xpos = xpos + 20; % shift right a bit
set(Bimg, 'XData', xpos);

imagesc() in Matlab not showing equal axis

I use the following lines of code to plot the images:
for t=1:subplotCol
subplot(subplotRow,subplotCol,t)
imagesc([1 100],[1 100],c(:,:,nStep*t));
colorbar
xlabel('X-axis')
ylabel('Y-axis')
title(['Concentration profile at t_{',num2str(nStep*t),'}'])
subplot(subplotRow,subplotCol,subplotCol+t)
hold on;
plot(distance,gamma(:,1,t),'-ob');
plot(distance,gamma(:,2,t),'-or');
plot(distance,gamma(:,3,t),'-og');
xlabel('h');ylabel('\gamma (h)');
legend(['\Theta = ',num2str(theta(1))],...
['\Theta = ',num2str(theta(2))],['\Theta = ',num2str(theta(3))]);
end
I get the following subplot with images:
As you can see the images in first row are now scaled equally on X and Y axis (Y axis is longer than the X-axis) even though the size of the image matrix is 100x100 for each image on first row.
Can someone help with how to make images in first row look like squares than rectangles which I get currently. Thanks.
Use the dataAspectRatio properties of the axes, and set it to [1 1 1]
%# create a test image
imagesc(1:10,1:10,rand(10))
%# you should use the handle returned by subplot
%# instead of gca
set(gca,'dataAspectRatio',[1 1 1])
Another method is to use the command axis equal
Regarding the size of different objects, you can set the exact position of each axes on the figure, for example for the first one use:
subplot(2,2,1); set(gca,'Position',[0.05 0.05 0.4 0.4])

Resources