Keep subplot in square while having (1,3) tiledlayout [duplicate] - matlab

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 multiply the xticks and yticks with constant and have it displayed in the figure in Matlab 2019?

I've got a picture (a matrix of intensities for every pixel). When plotting this with matlab's imagesc the x-,y-axis are obviously in pixels. I know that 1 pixel corresponds to 0.6250 millimeter in both x- and y-direction.
How can I change only the scale in axis in the figure to show millimeters instead of pixels, i.e how do I multiply the xticks and yticks with 0.6250 and have it displayed in the figure?
I have tried:
new_x = xticks*pixel_spacing(2);
set(gca,'xticklabels', new_x)
but this results in the error
"Unable to use a value of type 'matlab.graphics.axis.Axes' as an index."
imagesc has a syntax where you can specify the scaling of the pixels (see the documentation).
x = [1,size(img,2)] * pixel_spacing;
y = [1,size(img,1)] * pixel_spacing;
imagesc(x,y,img);
(assuming img is your image to display)
The advantage over changing the tick labels is that other things plotted on top of the image will use the same coordinates, as will retrieving mouse cursor location and so forth. This might or might not be relevant, but it’s good to know.
I figured it out.
xticklabels(xticks*pixel_spacing(2))
yticklabels(yticks*pixel_spacing(1))

Matlab: Position of X, Y, width and length to pixel images

I was given some data that I would like to convert to a pixelized image. From what I understood, the original data was plotted by using the function 'rectangle' in Matlab. However, a 2D image is now required.
This data has four columns and ~1000 rows. The first to fourth columns correspond to //
Matrice = [Left corner X, Left corner Y, Width, Height]
So for instance, the first row is [2,3,5,6], meaning that there is a rectangle with lower left corner position of (2,3), width of 5 and height of 6.
I've been trying to find a method to use this data and turn it into an image of any dimensions with any pixel size. Either there is a function out there that I've been missing, or I am missing an easy method. Everything I've tried so far is overly complicated.
This will create filled black rectangles at the specified positions. Experiment with the optional arguments of rectangle to get different visuals.
Assuming your matrix is named A:
figure
for ii = 1:size(A, 1)
rectangle('Position', A[ii, :], 'FaceColor', 'k')
hold on
end
hold off
axis equal % makes the pixels square

Odd bounding box coordinates in Matlab

I'm using regionprops(img,'BoundingBox'); to generate bounding boxes around some objects in an image. The coordinates of the bounding boxes (x, y, width, height) are always by 0.5 off from Integer-values.
Why is that the case?
For me, it is causing two problems:
When using these coordinates for accessing an image array, I get the warning: Warning: Integer operands are required for colon operator when used as index. I can live with that, respectively remove it with floor or ceil, BUT ...
... when these coordinates are close to image borders, they cause
errors since the values 0.5 and 1024.5 don't match with the image
borders 1 and 1024. I get Subscripted assignment dimension mismatch. or Index exceed matrix dimensions., which is plausible.
So can someone explain to me:
Why is it doing this?
How am I supposed to work with it when using the coordinates to crop and replace image regions. I want to replace exactly what was cropped by imcrop and rounding is a bit circumstancial (simply using floor or ceil won't work, I would have to check for the image borders which is not a problem but seems a bit tedious for a rather simple task and certainly questionable whether it is supposed to be used like this...).
Below are some code snippets with which I produced the errors for a 1024x1024 image.
bb_coords = [124.5 979.5 27 45]; % example for bounding box generated by regionprops
subregion = imcrop(img, bb_coords); % works fine with imcrop
% but when I want to use these coordinates for accessing the img array,
% I generally get a warning and in this case an error.
img( bb_coords(2):(bb_coords(2)+bb_coords(4)), ...
bb_coords(1):(bb_coords(1)+bb_coords(3))) = subregion;
Functions in MATLAB that handle image display or processing treat the center of the pixel as lining up with the corresponding coordinate grid points. In other words, for a given dimension of an image, the first pixel center is at 1, the second pixel center is at 2, etc., and the area of each pixel will span +-0.5 on either side of the coordinate. You can see this when you plot an image, turn the axes display on, and zoom in around one of the corners:
img = imread('cameraman.tif'); % Load a sample image
imshow(img); % Display it
set(gca, 'Visible', 'on'); % Make the axes visible
axis([0 5 252 257]); % Zoom in on the bottom left corner
The documentation for regionprops illustrates that the 'BoundingBox' will enclose the entire pixel area, thus leading to a bounding box that appears a full pixel wider (0.5 pixels wider on each side) than the range of center coordinates:
For the 5-by-5 sample image above, the nonzero pixels cover an area that spans the top 4 rows (row coordinates of the pixel centers from 1 to 4) and right 4 columns (column coordinates of the pixel centers from 2 to 5). The bounding box (in green) therefore spans from 0.5 to 4.5 (height of 4) across the rows and 1.5 to 5.5 (width of 4) across the columns.
In short, if you want to use the bounding box values in bb_coords to generate indices into the image, you need to add 0.5 to each corner coordinate and subtract 1 from each width:
ind_coords = bb_coords + [0.5 0.5 -1 -1];
img(ind_coords(2):(ind_coords(2)+ind_coords(4)), ...
ind_coords(1):(ind_coords(1)+ind_coords(3))) = subregion;

fit axes to contain the image EXACTLY using MATLAB

i have an axes named "axes1" and an image named "im"
How to make image dimensions equal to axes dimensions?
I mean I want to fit axes to contain the image EXACTLY (don't image stretching or image compression)?
Use the command axis image after displaying the image.
I interpret your question you want 1 pixel of your image to be one pixel in the axis.
You will need to do some calculating for that.
I would do it like this:
imagesc(magic(64)) % example image
set(gca,'Units','pixel') % set units to pixel
pos_in_px=get(gca,'Position')
set(gca,'XLim',[1,pos_in_px(3)-pos_in_px(1)]) % set xaxis to the pixel range
set(gca,'YLim',[1,pos_in_px(4)-pos_in_px(2)]) % set yaxis to the pixel range
of course this is a fragile solution - as you zoom or resize the window things may change.
I assume you want to display a color image. Try this (copy-paste in Matlab CLI) :
RGB = imread('ngc6543a.jpg');
[m,n,~] = size(RGB);
figure('Units', 'pixels', 'Position', [40 40 n m]);
image(RGB);
set(gca, 'Position', [0 0 1 1]);
axis equal;
'ngc6543a.jpg' is a standard image provided by Matlab.

matlab: figure size, same axis size

I have a figure with fixed size, like that:
hFig = figure(1);
set(hFig, 'Position', [200 200 500 500])
But the thing is, that I want to have my AXIS with fixed size (i want them to be a square), not (necessary) the whole figure... - see image attached, Y axis is a bit longer than X axis (of course longer in a meaning of display... X and Y axis range is set to the same value). How to adjust it?
Thanks!
Use axis equal to set the spacing of the axis to be the same.