Displaying a quiver plot of a gradient image in MATLAB - 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)));

Related

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

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

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

How to have an image in background of plot in matlab

I have a plot from a network of lines in 3D space and I have one image from the object as well. Now I want to put the image file in the background of my plot as a fixed background and then the network should be plotted on that background. By the way, since the Network is in 3D space I can rotate it easily and it is important for me rotate the network on the my combined plot as well.
this is my code that I have written but it shows my plot separately! if I put imshow inside the figure then image will be ploted on the top of my network and I can see only one point of my network. Here is the link of Network and the background image from background
Here is my code: the first line plot the image and the rest of the code plot my network of lines:
Img1 = imshow('STP1.png');
figure('name','Distance');
hold on;
labels = cellstr( num2str([1:SIFT_Length]') );
text(SIFT_3D(:,1), SIFT_3D(:,2),SIFT_3D(:,3),labels,'FontWeight','bold','FontSize', 12,...
'VerticalAlignment','bottom','HorizontalAlignment','right')
title('Distances Network with colorized lines based on Uncertainty','FontWeight','bold');
hold on
for k = 1:Num_Line_SIFTS
plot3([SIFT_3D(Line_among_2_Sifts(k,1),1),SIFT_3D(Line_among_2_Sifts(k,2),1)],...
[SIFT_3D(Line_among_2_Sifts(k,1),2),SIFT_3D(Line_among_2_Sifts(k,2),2)],...
[SIFT_3D(Line_among_2_Sifts(k,1),3),SIFT_3D(Line_among_2_Sifts(k,2),3)],...
'o-','Color',[RGB_0_1(k,1) RGB_0_1(k,2) RGB_0_1(k,3)],'MarkerFaceColor',[RGB_0_1(k,1) RGB_0_1(k,2) RGB_0_1(k,3)],'MarkerEdgeColor',...
'k', 'LineWidth',2)
end
hold off;
Please help me how can I solve this issue.
What about this:
clear
clc
close all
%// Read image
Im=flipud(imread('STP1_low.png'));
%// Dummy surface to plot.
Z = peaks(25);
%// Prepare image position
shift = 20;
xIm=zeros(size(Z))-shift;
hold on
surface(xIm,Im,'FaceColor','texturemap','EdgeColor','none','CDataMapping','direct')
surface(Z,'FaceAlpha',0.8,'LineStyle','none','FaceColor','interp');
axis on
view(-35,45)
box on
rotate3d on
Output:
You can rotate it and the image stays as the background.
I'm not sure I understood your need, nevertheless ...
figure('name','Distance','unit','normalized');
a=axes('position',[0 0 1 1])
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% UPDATED CODE STARTS HERE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Disable zoom
h=zoom;
setAllowAxesZoom(h,a,false);
% Disable rotation
h = rotate3d;
setAllowAxesRotate(h,a,false)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%
% UPDATED CODE ENDS HERE
%%%%%%%%%%%%%%%%%%%%%%%%%%
%
hold on
imshow('Jupiter_New_Horizons.jpg','parent',a)
t=0:.01:2*pi;
z=sin(t).*cos(t)
a1=axes('position',[0.3 0.3 .5 .5])
plot3(cos(t),sin(t),z,'r','linewidth',3)
grid on
set(gca,'color','none')
This script generates the following graph:
Hope this helps.

Scatter overlay on image with MATLAB

I have an RGB image, img, and I want to produce a new image, img2, with an overlay scatter plot on it.
If X Y Z are respectively the nx1 vectors of x-coord, y-coord and "magnitude" value of my scatter what I'm doing is:
imshow(img);
hold on;
scatter(X,Y,3,Z,'fill');
hold off;
In this way I actually get an image with the scatter plotted, but the problem is that every point of the scatter has the same color (blu) instead of what normally happens when I use
figure;
scatter(X,Y,3,Z,'fill');
Any suggestions? Thanks.
Try to add figure; before imshow(), which will enables you to draw on the image with the color that what normally it should be.
figure; % add this line before imshow()
imshow(img);
hold on;
scatter(X,Y,3,Z,'fill');
hold off;
Here is an example I just tested:
figure; % add this line before imshow()
imshow(img);
hold on;
load seamount
s = sqrt(-z/2);
c = z;
scatter(x,y,s,c,'fill')
hold off;
You can see that its color shown on the image is (roughly) consistent with the color when drawing it alone.
Edit: you can always change the color to whatever you like by setting scatter's color properties, i.e. MarkerEdgeColor and MarkerFaceColor.
Ok, remapping the values of Z to 0-255 it works fine. Here is my function to do that:
function [ Aremaped ] = remap( A,lnew,hnew )
Aremaped = zeros(size(A));
lold=min(A);
hold=max(A);
for i=1:length(A)
newVal = lnew + (A(i)-lold)*(hnew-lnew)/(hold-lold);
Aremaped(i) = newVal
end
end
Hope this can help

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.