I have computed the gradients from every pixel location of a grayscale image, both on X and Y axis and this can result in a vector representation for each pixel location. I want to obtain a plot figure similar to the one illustrated bellow:
My image has 1000 x 1002 dimensions and I have computed the gradients for each pixel on X and Y directions so I have 2 matrices, each one having 1000 x 1002 dimensions.
I am interested in obtaining a plot similar to the one illustrated in the image above, where I show basically the direction of each vector obtained from the computed gradients. I do not care about the magnitude of the vector, so basically each arrow can have the same length.
Do you know how can I obtain something similar to this?
It works in my case:
[DX,DY] = imgradient(imageIn);
%show gradient
figure;
[x,y]=meshgrid(1:1:500);
figure
quiver(x,y,DX,DY)
hold off
Related
I am trying to plot quadrilateral patches of a surface mesh of a 3d object.. I have x,y,z which are 4Xn where 4 is for each vertex of the quadrilateral and n is the number of quadrilaterals,c which is a 3Xn RGB matrix. when use patch( x, y, z,c);
I get the error
`Error using patch`
`Size of C must match sizes of X Y [Z]`
But this works for x,y,z which are 3Xn for triangular patches and c a 3Xn RGB vector. Please correct where i am going wrong.
Instead of giving a single RGB value for each patch, you'd need to give patch a value for each vertex you are drawing (due to the format of your data).
So with your data and this line:
cQuad=permute(repmat(cQuad,[1 1 4]),[3 2 1]);
patch(vertQuad.x,vertQuad.y,vertQuad.z,cQuad)
Works fine. What I do is repeat the colours 4 times using repmat and then order the dimensions in the format patch likes using permute
I need to plot a 3D figure with each data point colored with the value of a 4th variable using a colormap. Lets say I have 4 variables X,Y,Z and W where W = f(X,Y,Z). I want a 3D plot with X, Y, and Z as the three axis. The statement scatter3(X,Y,Z,'filled','b') gives me a scatter plot in 3D but I want to incorporate the value of Z in the graph by representing the points as an extra parameter (either with different areas :bigger circles for data points with high value of Z and small circles for data points with low value of Z or by plotting the data points with different colors using a colormap). However, I am a novice in MATLAB and dont really know how to proceed. Any help will be highly appreciated.
Thanks in advance!
So just use z for the size vector (4th input) as well as the color vector (5th input):
z = 10*(1:pi/50:10*pi);
y = z.*sin(z/10);
x = z.*cos(z/10);
figure(1)
scatter3(x,y,z,z,z)
view(45,10)
colorbar
The size vector needs to be greater 0, so you may need to adjust your z accordingly.
You are already nearly there... simply use
scatter3(X,Y,Z,s,W);
where s is the point size (scalar, e.g. 3) and W is a vector with your W values.
You might also want to issue an
set(gcf, 'Renderer','OpenGL');
where gcf gets your current figure you are plotting in to significantly increase responsiveness when scattering a lot of data.
I guess, I've got an colormap issue with Matlab2013. I plot a 3d surface plot with colormap hot and I would like to have in the same plot an bitmap (8bit colour image) on the x-y plane. Plotting both separately from each other works fine but as soon as I plot them in one figure the first surface plot is only black. I guess it is because the RGB image on the x-y plane uses a different colour map. Is there an option in Matlab to plot two different type of images in the same plot?
surf(X,Y,density,'FaceColor','texturemap','Edgecolor','none')
colormap hot
...
%// define the location of the bitmap
xImage = [miX maX; miX maX]; %// The y data for the image corners
yImage = [miY miY; maY maY]; %// The x data for the image corners
zImage = [zDist zDist; zDist zDist]; %// The z data for the image corners
surf(xImage,yImage,zImage,... %// Plot the surface
'CData',RGBImage,...
'FaceColor','texturemap');
Thanks!
Durin
I think this is an issue with the relative scaling of density and zImage. I can replicate this by doing the following:
1) Plot a surf where the third input is n x m which is scaled like some real data (-0.2 to +0.2, for example). This responds to changes in colormap as you'd expect.
2) After hold on, plot another surf where the third input is n x m x 3, like a RGB image, double values scaled between 0 and 1.
This causes the first image to go "dark" (or whatever the lowest color in that particular colormap is). The issue is that they share their CLim, being in the same axis, although the RGBImage doesn't, in fact, reference the colormap.
This is "fixable" by scaling/normalising the first plot (your density values) to be between 0 and 1 (in this case) - although this quick fix is going to give you issues if you then want to add a colorbar. Alternatively, first grab the "CLim" from your axis after plotting the first surf:
trueC = get(gca,'CLim');
Then set it back after you plot the image:
set(gca,'CLim',trueC)
This question entails rotating an image given as a 3D matrix where the first dimension is width, 2nd dimension is height, and 3rd dimension contains x,y,z coordinates.
Currently I am plotting a surface using the following code
Fig.sub1im=surf(ToFparam.ROI.XYZ(:,:,1),ToFparam.ROI.XYZ(:,:,2),ToFparam.ROI.XYZ(:,:,3),zeros(ToFparam.ROI.height,ToFparam.ROI.width,3));
Now, I have a 3-D matrix where it's a 100x50x3. All x data is in the first...page or layer of the 3rd dimension, y is the second layer...z the third. Now I need to apply a 3x3 rotation matrix on the x y and z data. I know how to reshape a matrix to do this I think....just put it into a 3 row by...50000 column matrix then apply the matrix.
Next I need to update my plot in a loop. I was going to then do the following, where I have also included my new matrix calculation.
ToFparam.ROI.XYZ_Vector = ToFparam.ROI.XYZ;
ToFparam.ROI.XYZ_Vector = reshape(ToFparam.ROI.XYZ, [size(ToFparam.ROI.XYZ,1)*size(ToFparam.ROI.XYZ,2),3]);
ToFparam.ROI.XYZ_Vector = ToFparam.ROI.XYZ_Vector';
ToFparam.ROI.XYZ_DICOM = inv(DICOMparam.calib.navi2dicom(1:3,1:3))*inv(Naviparam.data.Endo_RefHomMat(1:3,1:3))*ToFparam.ROI.XYZ_Vector;
%refresh plot standard cuts
set(Fig.sub1im,'CData', Color);
set(Fig.sub1im, 'XData', ToFparam.ROI.XYZ_DICOM(1,:) + DICOMPos(1)/Fig.sub2samp);
set(Fig.sub1im, 'YData', ToFparam.ROI.XYZ_DICOM(2,:) + DICOMPos(2)/Fig.sub2samp);
set(Fig.sub1im, 'ZData', ToFparam.ROI.XYZ_DICOM(3,:) + DICOMPos(3)/Fig.sub2samp);
When I update my plot, I get no errors, but it doesn't look like it's plotting it correctly. It seems like it makes a huge offset on my data and positions it somewhere I don't want it to be positioned. I wouldn't expect that a rotation matrix effects the scaling, just the orientation. Let me know if there are any faster/better ways to accomplish this surf plot, thanks!
For anyone interested, I have found the solution.
If you ever want to rotate a 3-D matrix where the x,y,z data is located in the 3rd dimension, use the following for maximum speed and efficiency.
[m,n,z]=size(inMatrix);
outMatrix=reshape((A*(reshape(double(inMatrix),[m*n 3]))')',[m n 3]);
Where inMatrix is your initial 3d matrix, outMatrix is your output 3d matrix, and A is your rotation matrix. Can be extremely useful when wanting to code rotations in images, since images will have 2 dimensions along their width and height, and the 3rd dimension will be the x, y and z coordinates. This will allow you to easily plot an initial data set, rotate it, then replot it.
I have a 2d image, I have locations where local minimas occurs.
I want to measure the width of the valleys "leading" to those minimas.
I need either the radii of the circles or ellipses fitted to these valley.
An example attached here, dark red lines on the peaks contours is what I wish to find.
Thanks.
I am partially extending the answer of #Lucas.
Given a threshold t I would consider the points P_m that are below t and closer to a certain point m of minimum of your f (given a characteristic scale length r).
(You said your data are noisy; to distinguish minima and talk about wells, you need to estimate such r. In your example it can be for instance r=4, i.e. half the distance between the minima).
Then you have to consider a metric for each well region P_m, say for example
metric(P_m) = .5 * mean{ maximum vertical diameter of P_m ,
maximum horizontal diameter of P_m}.
In your picture metric(P_m) = 2 for both wells.
On the whole, in terms of pseudo-code you may consider
M := set of local minima of f
for_each(minimum m in M){
P_m += {p : d(p,m) < r and f(r)<t} % say that += is the push operation in a Stack
}
radius_of_region_around(m) = metric(P_m); %
I would suggest making a list of points that describe the values at the edge of your ellipse, perhaps by finding all the points where it crosses a threshold.
above = data > threshold
apply a simple edge detector
edges = EdgeDetector(above)
find coordinates of edges
[row,col] = find(edges)
Then apply this ellipse fitter http://www.mathworks.com/matlabcentral/fileexchange/3215-fitellipse
I'm assuming here you have access to the x, y and z data and are not processing a given JPG (or so) image. Then, you can use the function contourc to your advantage:
% plot some example function
figure(1), clf, hold on
[x,y,z] = peaks;
surf(x,y,z+10,'edgecolor', 'none')
grid on, view(44,24)
% generate contour matrix. The last entry is a 2-element vector, the last
% element of which is to ensure the right algorithm gets called (so leave
% it untouched), and the first element is your threshold.
C = contourc(x(1,:), y(:,1), z, [-4 max(z(:))+1]);
% plot the selected points
plot(C(1,2:end), C(2,2:end), 'r.')
Then use this superfast ellipse fitting tool to fit an ellipse through those points and find all the parameters of the ellipse you desire.
I suggest you read help contourc and doc contourc to find out why the above works, and what else you can use it for.