Resize axes to fit image - matlab

How can I resize my axes on a matlab GUI to fit exactly with the size of the image I just resized?
I have this:
I = imread('honolulu.png');
I = imresize(im2double(I), [600, 700]);
After that I am drawing a grid on the pictures, but because the axes size is different the grid does not look good. However, if I create a figure and I do it on a figure outside the GUI it looks perfect.
Full code:
%Load map
I = imread('honolulu.png');
%Resize image to be multiple of 50 in each axis.
I = imresize(im2double(I), [600, 700]);
%Draw grid of 50x50 pixels.
I(50:50:end, :, :) = 255;
I(:, 50:50:end, :) = 255;
axes(handles.axes1);
h = handles.axes1;imshow(I);
while (ishandle(h))
try
[x, y] = ginput(1);
catch me
%break loop in case image is closed.
break;
end
%Compute top left coordinate of block clicked.
x0 = floor((x-1)/50)*50;
y0 = floor((y-1)/50)*50;
%Set block RGB to random color.
I(y0+1:y0+50-1, x0+1:x0+50-1, 1) = rand();
I(y0+1:y0+50-1, x0+1:x0+50-1, 2) = rand();
I(y0+1:y0+50-1, x0+1:x0+50-1, 3) = rand();
imshow(I);
end
% Choose default command line output for city_planning
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
How it looks vs how it is supposed to look

The lines are disappearing as the plot window changes size - something of an aliasing/rendering issue I guess. Elsewhere other people have asked similar questions without a great answer.
The best I've found is setting the initial magnification to 100% and then preventing resizing. Here's a similar example:
close all;
clear all;
clc;
I = imread('peppers.png');
I = imresize(im2double(I), [600, 700]);
%Draw grid of 50x50 pixels.
I(50:50:end, :, :) = 1;
I(:, 50:50:end, :) = 1;
h = imshow(I,'initialMagnification',100);
set(gcf,'Resize','off')
%%
while (ishandle(h))
try
[x, y] = ginput(1);
catch me
%break loop in case image is closed.
break;
end
%Compute top left coordinate of block clicked.
x0 = floor((x-1)/50)*50;
y0 = floor((y-1)/50)*50;
%Set block RGB to random color.
I(y0+1:y0+50-1, x0+1:x0+50-1, 1) = rand();
I(y0+1:y0+50-1, x0+1:x0+50-1, 2) = rand();
I(y0+1:y0+50-1, x0+1:x0+50-1, 3) = rand();
h = imshow(I);
end

Related

How to answer this Matlab image processing homework?

I'm stuck here, I tried many times but unable to get my final answer.
Code:
I = imread('C:\Users\Ahsan\Desktop\pears.png');
H = fspecial('average', [3 3]);
J = imfilter(I, H);
figure, imshow(I);
figure, imshow(J);
Try this one:
(Maybe you have to change the threshold);
threshold = 126;
image = imread('C:\Users\Ahsan\Desktop\pears.png');
% Apply the filder
filterImage = conv2(image, ones(3)/9, 'same');
% Check which pixels are equal or greater than the threshold
masked = filterImage >= threshold;
% Replace all pixels of the filteredImage which are below the threshold
% with the original pixels.
filterImage(~masked) = image(~masked);
% Display result
figure(1);
subplot(1,2,1);
imshow(image, []);
subplot(1,2,2);
imshow(filterImage, []);

How can I add subtitle for each image below figure in matlab

I am using subplot to display multiple image in the a figure. I want to add the subtitle (a),(b),...(c) below each image as the below figure:
Could you help to write it in MATLAB? This is current code for above image. if it is possible, let me know how to control the margin between image and the sub-title. Thanks
%# read images in a cell array
imgs = cell(6,1);
for i=1:6
imgs{i} = imread( sprintf('AT3_1m4_%02d.tif',i) );
end
%# show them in subplots
figure(1)
for i=1:6
subplot(2,3,i);
h = imshow(imgs{i}, 'InitialMag',100, 'Border','tight');
title(num2str(i))
set(h, 'ButtonDownFcn',{#callback,i})
end
Updated: I also tried with subaxis lib. However, the result do not show titles
%% read images in a cell array
imgs = cell(6,1);
for i=1:6
imgs{i} = imread( sprintf('AT3_1m4_%02d.tif',i) );
end
figure(1)
spaceH=0.01;spaceV=0.1;marTop=0.3;marBot=0.0;
padding=0.0;margin=0.0;marginL=0.0;
for i=1:6
subaxis(2,3,i,'SpacingHoriz', spaceH, ...
'SpacingVert',spaceV, 'PL',padding,'PR',padding,'mt',...
marTop,'mb',marBot,'ML',marginL,'MR',margin); title('Original');
imagesc(uint8(imgs{i}),[0 255]),colormap(gray),axis off;axis equal,
xlabel(['(' char(96+1) ')']);
end
Try this. To specify a margin just set the 'margin' variable to whatever you need.
% show images with subtitles
figure(1);
margin = 0; % margin between title and image (in ex)
title_names = {'(a)','(b)','(c)','(d)','(e)','(f)'};
for i=1:6
subplot(2,3,i);
handle_image = imshow(imgs{i}, 'InitialMag',100, 'Border','tight');
handle_title = title(title_names{i});
set(handle_image, 'ButtonDownFcn',{#callback,i})
% adjust title position -- in 2 steps
% first set the title position to the bottom of the image
image_height = get(handle_image,'YData');
image_height(1) = [];
position = get(handle_title,'Position');
position(2) = image_height;
set(handle_title,'Position',position);
% then move it out of the image and apply some margin
set(handle_title,'Units','characters');
position = get(handle_title,'Position');
position(2) = position(2) - margin - 1;
set(handle_title,'Position',position);
% EDIT: this line will keep titles on their relative position
set(handle_title,'Units','normalized');
end
Note that you have to define #callback within the same namespace or it will throw an error, whenever you klick on an image.
This is an example result using 'trees.tiff' and a margin of 0.5ex.
EDIT: If you want to alter the figure size dynamicly the titles woun't adjust in x direction. To get a similar behavior then classic 'titles' add
set(handle_title,'Units','normalized');
below all other lines. This will keep the title at the same relative coordinates in the figure instead of the same fixed coordinates.
First of all, for controlling subplot margins and other properties, I highly recommend the tight_subplot function that may be found at the Mathworks File Exchange.
As for the specific question for adding labels, you can use xlabel. Example:
figure(1)
for i=1:6
subplot(2,3,i);
h = plot(1:20, randn(20,1));
xlb{i} = xlabel(['(' char(96+i) ')']);
end
You can control the location of the label by tuning the Position property of the labels, which are actually text objects. Example:
% Move all xlabels down by yoffset
yoffset = 0.3;
for ii = 1:6
xp = get(xlb{ii}, 'position');
xp(2) = xp(2) - yoffset; % update y-position
set(xlb{ii}, 'position', xp); % assign new position
end
After read solution of mikkola. I would like thank for your help. I would like to post my solution which may be helpful for other people
This is my solution
%% read images in a cell array
imgs = cell(6,1);
for i=1:6
imgs{i} = imread( sprintf('AT3_1m4_%02d.tif',i) );
end
figure(1)
spaceH=0.01;spaceV=0.06;marTop=0.3;marBot=0.08;
padding=0.0;margin=0.0;marginL=0.0;
yoffset = 12;
for i=1:6
subaxis(2,3,i,'SpacingHoriz', spaceH, ...
'SpacingVert',spaceV, 'PL',padding,'PR',padding,'mt',...
marTop,'mb',marBot,'ML',marginL,'MR',margin); title('Original');
% imagesc(uint8(imgs{i}),[0 255]),colormap(gray);axis equal,
imshow(imgs{i}, 'InitialMag',90, 'Border','tight');
xlb{i} = xlabel(['(' char(96+i) ')'],'FontSize', 16);
xp = get(xlb{i}, 'position');
xp(2) = xp(2) - yoffset; % update y-position
set(xlb{i}, 'position', xp); % assign new position
end

Circular ROI is not being drawn from input

For some reason, the following code only displays the masked image with roi at 10,10 with height and width 100,100. These are the initial values. It seems the image does not update even after the getPosition function. Could anyone explain this issue?
`I = imread('/Users/imageuser/Documents/PT300.tif');
h = imshow(I);
% define circular roi by square bounding box
x = 10;
y = 10;
d1 = 100;
d2 = 100;
e = imellipse(gca, [x y d1 d2]);
% roi can be interactively moved/adjusted
% do not close figure window before createMask is called
%%% these lines are only needed if you move or resize the roi
pos = getPosition(e);
x = pos(1);
y = pos(2);
d1 = pos(3);
d2 = pos(4);
%%%
BW = createMask(e,h);
pause;
imshow(BW);`
You need to put those lines (note I inverted their order):
pause;
BW = createMask(e,h);
before calling getPosition, otherwise the new position is not updated.
Whole code:
clear
clc
close all
I = imread('coins.png');
h = imshow(I);
% define circular roi by square bounding box
x = 10;
y = 10;
d1 = 100;
d2 = 100;
e = imellipse(gca, [x y d1 d2]);
pause;
BW = createMask(e,h);
% roi can be interactively moved/adjusted
% do not close figure window before createMask is called
%%% these lines are only needed if you move or resize the roi
pos = getPosition(e)
x = pos(1);
y = pos(2);
d1 = pos(3);
d2 = pos(4);
%%%
figure
imshow(BW);
sample output after dragging the ROI:
Yay!
Note: As mentioned by juicestain, instead of using pause to halt execution of the program while the user is done creating the GUI, you can use wait to wait until the user double-clicks on the ROI object instead of having to press a key as with the pause command.
Therefore, you could replace the call to pause with a call to wait(e).

MATLAB adding slider on a figure

I have a 576x576x150 matrix. Each 576x576 set represents an image. When I want to plot one frame I do it by using the plot command:
figure(1);
imshow(B(:,:,45),[]) % plots frame 45
title('45') % tells frame number
However I would like to add a slider to the plot, so I can move from 1-150 frame within the figure.I've seen examples of people using uicontrol but I don't know how to code it. In addition to that, I would like to have a title on top of the figure telling me the frame number.
Here is how I do it. I like to keep a single function that does the plotting so you don't recycle commands elsewhere. You could replace the first two lines by function test(B) to use you own B matrix. This code is pretty easy to extend. You will also want to play with the layout to suit your purpose.
function test
B=rand(576,576,150);
fig=figure(100);
set(fig,'Name','Image','Toolbar','figure',...
'NumberTitle','off')
% Create an axes to plot in
axes('Position',[.15 .05 .7 .9]);
% sliders for epsilon and lambda
slider1_handle=uicontrol(fig,'Style','slider','Max',150,'Min',1,...
'Value',2,'SliderStep',[1/(150-1) 10/(150-1)],...
'Units','normalized','Position',[.02 .02 .14 .05]);
uicontrol(fig,'Style','text','Units','normalized','Position',[.02 .07 .14 .04],...
'String','Choose frame');
% Set up callbacks
vars=struct('slider1_handle',slider1_handle,'B',B);
set(slider1_handle,'Callback',{#slider1_callback,vars});
plotterfcn(vars)
% End of main file
% Callback subfunctions to support UI actions
function slider1_callback(~,~,vars)
% Run slider1 which controls value of epsilon
plotterfcn(vars)
function plotterfcn(vars)
% Plots the image
imshow(vars.B(:,:,get(vars.slider1_handle,'Value')));
title(num2str(get(vars.slider1_handle,'Value')));
The idea is to use uicontrol() to enable sliding/scrolling.
The following code is for scrolling (created by Evan Brooks, you can modify it to sliding):
function scrollfigdemo
% create new figure window
f = figure;
set(f,'doublebuffer', 'on', 'resize', 'off')
% set columns of plots
cols = 2;
% create 5 data sets to plot
x=0:1e-2:2*pi;
y{1}=sin(x);
y{2}=cos(x);
y{3}=tan(x);
y{4}=x.^2;
y{5}=x.^3;
% determine required rows of plots
rows = ceil(length(y)/cols);
% increase figure width for additional axes
fpos = get(gcf, 'position');
scrnsz = get(0, 'screensize');
fwidth = min([fpos(3)*cols, scrnsz(3)-20]);
fheight = fwidth/cols*.75; % maintain aspect ratio
set(gcf, 'position', [10 fpos(2) fwidth fheight])
% setup all axes
buf = .15/cols; % buffer between axes & between left edge of figure and axes
awidth = (1-buf*cols-.08/cols)/cols; % width of all axes
aidx = 1;
rowidx = 0;
while aidx <= length(y)
for i = 0:cols-1
if aidx+i <= length(y)
start = buf + buf*i + awidth*i;
apos{aidx+i} = [start 1-rowidx-.92 awidth .85];
a{aidx+i} = axes('position', apos{aidx+i});
end
end
rowidx = rowidx + 1; % increment row
aidx = aidx + cols; % increment index of axes
end
% make plots
axes(a{1}), plot(x,y{1}), title('sine'), xlabel('x'), ylabel('sin(x)')
axes(a{2}), plot(x,y{2}), title('cosine'), xlabel('x'), ylabel('cos(x)')
axes(a{3}), plot(x,y{3}), title('tangent'), xlabel('x'), ylabel('tan(x)')
axes(a{4}), plot(x,y{4}), title('x^2'), xlabel('x'), ylabel('x^2')
axes(a{5}), plot(x,y{5}), title('x^3'), xlabel('x'), ylabel('x^3')
% determine the position of the scrollbar & its limits
swidth = max([.03/cols, 16/scrnsz(3)]);
ypos = [1-swidth 0 swidth 1];
ymax = 0;
ymin = -1*(rows-1);
% build the callback that will be executed on scrolling
clbk = '';
for i = 1:length(a)
line = ['set(',num2str(a{i},'%.13f'),',''position'',[', ...
num2str(apos{i}(1)),' ',num2str(apos{i}(2)),'-get(gcbo,''value'') ', num2str(apos{i}(3)), ...
' ', num2str(apos{i}(4)),'])'];
if i ~= length(a)
line = [line,','];
end
clbk = [clbk,line];
end
% create the slider
uicontrol('style','slider', ...
'units','normalized','position',ypos, ...
'callback',clbk,'min',ymin,'max',ymax,'value',0);

How to set axis for multiple subplots of pictures in Matlab

clear all; close all; clc;
A = im2double(imread('cameraman.jpg'));
figure(1)
imshow(A)
C = chunking(A,400,400) % separates picture;
[m n] = size(C);
k = 1;
figure(1)
for i = 1:m
for j = 1:n
subplot(m,n,k)
imshow(C{i,j})
axis off;
k = k + 1;
end
end
So In the above code, I am trying to separate a picture into 400x400 pixel chunks. Since the image is not a multiple of 400x400, it will have unequal sections on the border and bottom right corner (still a square image). However, when I use subplot, it resizes the last chunk to be the same size. I tried playing around with get and set position but it gives that the width and height for each subplot is the same?![enter image description here][1]
http://imgur.com/2VUYZr1
You want to resize the axes if you have less than 400 pixels to display. You should store the handle to each subplot and then resize it if it needs to be smaller.
Your call to subplot should look like this:
h = subplot(m,n,k);
num_rows = size(C{i,j}, 1);
num_cols = size(C{i,j}, 2);
set(h, 'units', 'pixels')
old_axes_pos = get(h, 'position');
new_axes_pos = old_axes_pos;
if num_cols < 400
new_axes_pos(3) = num_cols; % Make this axes narrower
end
% If the figure cannot be full height
if num_rows < 400
new_axes_pos(4) = num_rows; % Make this axes shorter
new_axes_pos(2) = old_axes_pos(2) + (400 - num_rows); % Move the bottom up
end
set(h, 'position', new_axes_pos) % Change the size of the figure