How can I change figure edges of a figure created with imshow? - matlab

I'm using imshow to create this binary image. When it shows the figure I see a grey background and no edges in the figure. If I save the plot in as .png, I see the background as white and I can't see any edges on the figure. How can I add edges to this plot?
Image as shown by imshow:
Image as saved to PNG:

By default, saved figures have a white background. Ensure that the colors of the saved figure match the colors on the display by setting the InvertHardcopy property of the figure to 'off'.
Example:
A = rand(300, 300) > 0.1;
f = figure();
f.InvertHardcopy = 'off';
imshow(A);
title('Binary Image threshold 0.9');
saveas(f, 'test.png');
gives:
Alternatively, it is possible to set the visibility of the axes in the imshow and make the ticks empty:
A = rand(300, 300) > 0.1;
f = figure();
iptsetpref('ImshowAxesVisible', 'on');
imshow(A);
xticks({});
yticks({});
title('Binary Image threshold 0.9');
saveas(f, 'test.png');
that gives:
Source: Matlab Documentation

Related

Prevent Color Bar from Resizing Image in MATLAB

I am trying to add color bars to an image in MATLAB without losing the original resolution of the figure.
This link explains how to deal with the fact that adding a color bar resizes the original image. But the solution makes the original loose information by enlarging using interpolation (the set method used in the 6th line from the bottom). It is crucial to my application that this does not happen (Trying to observe Moire effects on sub-sampling)
The code I am using is appended below
%% Load images using relative paths
path1 = '../data/circles_concentric.png';
path2 = '../data/barbaraSmall.png';
img1 = imread(path1, 'png');
img2 = imread(path2, 'png');
%Shrinking factor
d1 = 2;
d2 = 3;
img1_shrunk1 = myShrinkImageByFactorD(img1, d1);
imshow(img1_shrunk1);
colorbar(gca);
img1_shrunk2 = myShrinkImageByFactorD(img1, d2);
figure, imshow(img1_shrunk2);
colorbar(gca);
I have dealt with this problem by simply putting the colorbar in a separate axis.
%Import image and colormap
[img,map]=imread('image.tif');
%Create figure and show the image on ax1
fig=figure;
ax1=axes(fig);
imshow(img,map,'Parent',ax1);
%Create ax2 and make it invisible
ax2=axes(fig,...
'Position',[ax1.Position(1)+ax1.Position(3),ax1.Position(2),0.2,0.7]);
axis off
set(ax2,'color','none');
%Apply colormap to ax2 and, colorbar and adjust CLim
colormap(map);
colorbar(ax2,'Position',...
[ax1.Position(1)+ax1.Position(3)+0.03,0.1,0.05,0.7],...
'AxisLocation','in');
ax2.CLim=[minValue,maxValue];

Separate colormap for each subplot in Octave

Matlab provides an ability to set individual colormaps for each subplot. The same functionality described by Octave docs
Namely following phrases:
Function File: cmap = colormap (hax, …)
If the first argument hax is an axes handle, then the colormap for the parent figure of hax is queried or set.
But when I try to run following code, I end up having single colormap for all subplots for some reason.
clear -all;
clc;
img = zeros(128, 128);
img(64,64) = 0.2;
rad = radon(img);
x = 1;
y = 4;
s1 = subplot(y,x,1); imagesc(img);
colormap(s1, gray);
s2 = subplot(y,x,2); imagesc(rad);
colormap(s2, hot);
colorbar;
line_img = zeros(128, 128);
line_img(64, 32:64) = 0.5;
line_img(63, 32:64) = 0.4;
line_img(63, 32:64) = 0.2;
line_rad = radon(line_img);
s3 = subplot(y,x,3); imshow(line_img);
colormap(s3, gray);
s4 = subplot(y,x,4); imagesc(line_rad);
colormap(s4, hot);
colorbar;
Any help is appreciated. I expect to have source images in grayscale and radon transform images in "hot". For some reason I'm getting first subplot somewhat like grayscale (it's actually not, since I initialize point with value 0.2 and octave gives me pure white color for it, while I'm expecting reasonably dark gray), and thee remaining images seem to have "hot" colormap being set.
If you read that line from the documentation a little close you will see that is that that if you pass an axes handle that the parent figure's colormap is changed. This is not the same as each axes having a different colormap since they're all in the same figure.
Function File: cmap = colormap (hax, …) If the first argument hax is an axes handle, then the colormap for the parent figure of hax is queried or set.
Currently, Octave does not support this functionality which was only just recently introduced in MATLAB.
The way around this is to convert your images to RGB images prior to displaying with imshow and then the figure's colormap is irrelevant. You can do this by first converting it to an indexed image (using gray2ind) and then to RGB with ind2rgb.
% To display the grayscale image
rgb = ind2rgb(gray2ind(img), gray);
imshow(rgb);
As a side note, the reason that your first grayscale image is showing up as all white is that if the input to imshow is of type double, then all values are expected to be between 0 and 1. If you want to change this behavior you can use the second input of imshow to specify that you'd like to scale the color limits to match your data
imshow(img, [])

Displaying a quiver plot of a gradient image in MATLAB

I have an image. I want to display a quiver plot of the gradient image that I get using gradient function in MATLAB, preferably superimposed on the gradient image.
I = imread('image.png');
[gx,gy] = gradient(double(rgb2gray(I)));
g = abs(gx) + abs(gy);
figure;
imshow(g, []);
hold on;
quiver(abs(gx),abs(gy));
This is what I tried, and all I get is a completely blue display.
I think all you see is the arrows, but they're too close together.
If you plot the two graphs (imshow(g) and quiver) separately, they show up normal. The imshow only shows the pixels without any scaling, if you fix that (make it scale) the quiver arrows also will have more space between them and become visible.
You can do just that by adding the 'InitialMagnification','fit' option to imshow:
imshow(g,'InitialMagnification','fit')
Or you can show less quiver arrows:
figure;
imshow(g, []); % [] to display image properly
hold on;
[Nx, Ny] = size(g);
xidx = 1:10:Nx;
yidx = 1:10:Ny;
[X,Y] = meshgrid(xidx,yidx);
quiver(Y',X',abs(gx(xidx,yidx)),abs(gy(xidx,yidx)));

How to get image matrix from axes content

Is there a way to get the content of a contourf plot as an image matrix? I want rasterize only the content, not the axes, labels and the empty space of the entire figure.
My goal is to overlay a transparent, colored contour plot over a grayscale image and I don't see another way, since MATLAB has only one colormap per figure.
Try getframe and frame2im
Example from the frame2im documentation:
Create and capture an image using getframe and frame2im:
peaks %Make figure
f = getframe; %Capture screen shot
[im,map] = frame2im(f); %Return associated image data
if isempty(map) %Truecolor system
rgb = im;
else %Indexed system
rgb = ind2rgb(im,map); %Convert image data
end
Not a direct answer to the question, but this is how I think you could achieve your goal:
%# load in grayscale image
gray_im = rgb2gray(imread('peppers.png'));
%# converting n x m grey image to n x m x 3 rgb gray image
rgb_gray_im = cat( 3, gray_im, gray_im, gray_im );
%# displaying this image
imshow( rgb_gray_im );
%# plotting contourf on top with arbitrary colourmap
hold on
h = axes('position', [0.5, 0.5, 0.2, 0.2]);
z = peaks;
contourf(h, z, [min(z(:)), -6 : 8]);
Which gives the result:
The figure's colourmap is being used for the contourf plot. The background image is not relying on a colourmap, and is instead being displayed in truecolour - i.e. each pixel is being displayed as an RGB value defined in rgb_gray_im.
There are also other ways of getting around the MATLAB colourmap restrictions: see for example this blog post or these answers.

How can I save an altered image in MATLAB?

I want to read an image into MATLAB, draw a rectangle on it, and then save the image.
Also, I'm just learning MATLAB--please be gentle. It seems like it should be simple, but I can't seem to do it.
im = imread('image.tif');
imshow(im);
rectangle('Position', [100, 100, 10, 10]);
imwrite(im, 'image2.tif');
Even though I can see the rectangle on the image, the saved image does not display the rectangle. How can I save the image and have the rectangle show up?
FWIW, I've already tried saveas(), but that gives me a HUGE image. Is there a way to use saveas() and make the saved image the correct size?
The reason the rectangle doesn't show up in the saved image is because you are not modifying the variable im, which stores the image data. The rectangle is simply a plot object displayed over the plotted image. You have to modify the image data itself.
Typically, images read into MATLAB are loaded as an N-by-M-by-3 matrix (i.e. an N-by-M pixel image with RGB (red-green-blue) values for each pixel). Usually, the image data is a uint8 data type, so the RGB values range from 0 to 255. If you wanted to change the RGB value for a given pixel, you would do the following:
im = imread('test.jpg'); % Load a jpeg image
im(1,1,1) = 255; % Change the red value for the first pixel
im(1,1,2) = 0; % Change the green value for the first pixel
im(1,1,3) = 0; % Change the blue value for the first pixel
imwrite(im,'new.jpeg'); % Save modified image
There are different ways you can modify more than one pixel at a time (i.e. a rectangular area), which will require that you look into how to index into multidimensional arrays. For more detail about how different types of images are read into MATLAB (i.e. truecolor vs. indexed), I would check the documentation for imread.
to the question in the top, there is quite a simple solution provided by matlab:
% you so far
im = imread('image.tif');
imshow(im);
rectangle('Position', [100, 100, 10, 10]);
% now you use "getframe" and "frame2im"
f = getframe(gca);
im = frame2im(f);
imwrite(im,'image2.tif');
that worked great for me when i also drew a rectangle on an image and tried to save it. If you want to keep on working with it, just add
imread('image2.tif');
and keep on working with it :)
Regards, Laura
There's actually a bug at The MathWorks site about this issue. Too bad they don't spell out a real answer (as, IMHO, holding up a ruler to your monitor is not a real solution).
Using the print command, you must manually change the -r parameter until the size of the saved image matches the size of the input image. The -r parameter specifies the DPI of the saved image. Since most screens have different DPIs, there's no one-size-fits-all solution.
im = imread('image.tif');
f = figure, imshow(im, 'Border', 'tight');
rectangle('Position', [100, 100, 10, 10]);
print(f, '-r80', '-dtiff', 'image2.tif');
Use the code above, tweak the -r parameter until it looks right, and voilà!
following up to jacobko answer. Setting the figures paperposition and paperunits properties and the axis units and position properties usually gives me the desired results without having to tweak the resolution. So,
>> im = imread('image.tif');
>> f = figure, imshow(im);
>> r=rectangle('Position',[100, 100,10,10]);
>> set(r,'edgecolor','b') % change the color of the rectangle to blue
>> set(f,'units','centimeters','position',[1 1 2.5 2.5]) % set the screen size and position
>> set(f,'paperunits','centimeters','paperposition',[1 1 2.5 2.5]) % set size and position for printing
>> set(gca,'units','normalized','position',[0 0 1 1]) % make sure axis fills entire figure
>> print(f, '-r80','-dtiff','image2.tif')
The output image, image2.tif, will now be 2.5cm by 2.5cm at a resoultion of 80dpi without the border around the axis.
If you want to save im, you must first modify its value.
I am not familiar with the rectangle function,
but you can do the following (brute force):
im = imread('image.tif');
im(100:110,100)=0;
im(100:110,110)=0;
im(100,100:110)=0;
im(110,100:110)=0;
imshow(im);
imwrite(im, 'image2.tif');
Note, the code above is for gray scale image, if your image is an RGB image, you will need to do the following:
im(100:110,100,:)=0;
....
You might be able to use getframe to grab the modified image from the figure window. I think you could pass the cdata and colormap fields of the structure returned by getframe to imwrite as the image and its colormap, respectively.
[f,p] = uigetfile('*.*');
I = imread([p,f]);
imwrite(I,'img12.tif');%
Any name we can give for saving the image
Automatically it will save in your folder and you can browse any image.
close all; clear; clc;
r = 240 ; c = 320;
fig = figure('Visible', 'off');
imshow( zeros(r,c) );
hold on;
plot([c-fix(c/2),c-fix(c/2)],[r-fix(r/2),r-fix(r/2)],'r*', 'MarkerSize', 10 );
% Sets position and size of figure on the screen
set(fig, 'Units', 'pixels', 'position', [100 100 c r] );
% Sets axes to fill the figure space
set(gca, 'Units', 'pixels', 'position', [0 0 c+1 r+1 ]);
% Sets print properties; Looks like 1 pixel = (3/4)th of a point
set(fig, 'paperunits', 'points', 'papersize', [fix((c-1)*(3/4))+1 fix((r-1)*(3/4))+1]);
set(fig, 'paperunits', 'normalized', 'paperposition', [0 0 1 1]);
print( fig, sprintf('-r%d', ceil(72*(4/3))), '-dpng', 'image.png' );
im = imread( 'image.png');
figure; imshow(im);