I've got a 25x10 matrix that shows a fairly rough surface when i plot it.
I'd like to filter it out to create a smooth surface with more datapoints for a finer grid(but not lineary interpolated), and i need the filtered data that produces the smoothed surface as base for an open-loop. Can anyone recommend me a good approach? The result right now looks like this:
Cheers
EDIT: griddata with method 'cubic' looks more like the desired result, but it's still holding onto the data too much. The image below visualizes the result with cubic, and the desired result. The goal is to see no more clear peaks in the surface.
Use griddata to interpolate your data over a finer mesh. If x, y and z is your data, you can define a fine mesh (xq, yq) and interpolate / extrapolate your data on that extend. Since the default method is 'linear' and because you want to make your surface profile smoother, you should specify another method, like 'natural'.
[xq, yq] = meshgrid(0:20:6000, 0.2:0.01:1);
zq = griddata(x(:), y(:), z(:), xq, yq, 'natural');
surf(xq, yq, zq, 'EdgeColor', 'none')
Related
I have this data with values on the edges of the matrix and other values at evenly spaced interval within the matrix. I want to predict the values of the zero positions from the original values and make a heat map of the new data. Through suggest, I use scatteredInterpolant, ndgrid and interpolant since the data is that interp2 (matlab functions) cannot be used to interpolate the zero elements. Now, this method doe not give me a smooth figure and I am want to know if someone can offer some help. I have attached the figure from my code, the data and the code to this post.Thank you.
[knownrows, knowncolumns, knownvalues] = find(DataGrid); %get location and value of all non-zero points
interpolant = scatteredInterpolant(knownrows, knowncolumns, knownvalues,'linear'); %create interpolant from known values
[queryrows, querycolumns] = ndgrid(1:1:size(DataGrid, 1), 1:1:size(DataGrid, 2)); %create grid of query points
interpolatedj = interpolant(queryrows, querycolumns);
HeatMap(interpolatedj)
https://www.mediafire.com/?pq40x1ljxk8h996
https://www.mediafire.com/?pq40x1ljxk8h996
To plot a smoothed matrix you can use pcolor and set the shading parameter to interp
pcolor(M); %where M is your 2D matrix
shading interp %set the shading to interp
Try
image(M) or imagesc(M) where M is a matrix. pcolor(M) also works. If your matrix is huge then you need to remove edges otherwise figure just looks like blank image.
How is it possible to visualize filters the way it is presented in the following website:
http://www.robots.ox.ac.uk/~vgg/research/texclass/filters.html
For example, in Fig.1 the last four square subimages visualize four different Gaussian filters.
They're just images after all, the only trick is to use the right scale. Fortunately this is pretty easy in MATLAB.
So if your filter is G, then to visualize it you can just do
imshow(G,[])
The [ ] will set the right scale for you (min_value, max_value).
So for example, for a Gaussian of sigma 30 (that high for visualization purposes here) these lines:
G1=fspecial('gauss',[round(6*sigma), round(6*sigma)], sigma);
imshow(G1,[]);
Lead to this image:
Same principle for any image you want to display that has an unusual range (i.e. different from [0 255]).
To visualize multiple images at once you have to use subplot
This is just a little bonus, but because the filter is a 2D function, we can also map the amplitude of the function in the Z direction as well. You would basically take the intensity that is shown in imshow and just map it to the third dimension. In other words, replicating what #cifz has done, we can also define a 2D grid, then use mesh or surf to visualize it in 3D.
As such:
sigma = 30;
G1=fspecial('gauss',[round(6*sigma), round(6*sigma)], sigma);
[X,Y] = meshgrid(1:size(G1,2), 1:size(G1,1));
mesh(X, Y, G1);
xlabel('X'); ylabel('Y'); zlabel('Amplitude');
title('3D visualization of the Gaussian filter');
colorbar;
You'd get:
This is obviously not what the OP wanted, but I figured I'd add this bonus in case anyone was curious.
Suppose I have a best fit equation for a set of data.How can I plot the data with marker and the best fit curve together. I know the command to include a data marker for a curve but this will make the curve pass through all the points if I type something like this
plot(x,polyval(p,x),'kx',x,polyval(p,x))
But this is not what I want since I am plotting a best fit curve. So I would like to know how exactly I can do that. Thanks in advance for all the helps. And between how can I add a polynomial that pass through all the point and the best fit curve as well as the data point with data marker on a same figure.
Where is the data stored? lets say your datapoints are in x and y, then make a much finer xi so something like linspace(min(x), max(x), 1000) or xi = -100:0.01:100 or whatevers appropriate and then to plot
plot(x, y, 'k*', xi, polyval(p, xi))
I am trying to plot a 3d view of a very large CT dataset. My data is in a 3d matrix of 2000x2000x1000 dimension. The object is surrounded by air, which is set to NaN in my matrix.
I would like to be able to see the greyscale value of the surface of the object (no isosurface) but I cannot quite work out how to do that in Matlab. Can anyone help me please?
Given that I a dealing with a huge matrix and I am only interested in the surface of the object, does anyone know a good trick how to reduce the size of my dataset?
The function surf(X,Y,Z) allows you to plot 3d data, where (X,Y) gives the coordinates in the x-y-plane while Z gives the z-coordinate and the surface color.
By default the function does not plot anything for the NaN entries, so you should be good to go with the surf function.
To set the surf-function to use a grayscale plotting use:
surf(matrix3d);
colormap(gray);
This plots the matrix in a surface plot and sets the colormap to grayscale.
In addition, as I understand your data, you might be able to eliminate entire plane-segments in your matrix. If for instance the plane A(1,1:2000,1:1000) is NaN in all entries you could eliminate all those entries (thus the entire Y,Z-plane in entry X=1). This will however require some heavy for loops, which might be over the top. This depends on how many data matrices you have compared to how many different plot you want for each matrix.
I will try to give you some ideas. I assume lack of a direct 3D "surface detector".
Since you have a 3D matrix where XY-planes are CT scan slices and each slice is an image, I would try to find edges of each slice say with edge. This would require some preprocessing like first thresholding each slice image. Then I can either use scatter3 to display the edge data as a 3D point cloud or delaunay3 to display the edge data as a surface.
I hope this will help you achieve what you are asking for.
I managed to get it working:
function [X,Y,Z,C] = extract_surface(file_name,slice_number,voxel_size)
LT = imread(file_name);%..READ THE 2D MAP
BW = im2bw(LT,1);%..THRESHOLD TO BINARY
B = bwboundaries(BW,8,'noholes');%..FIND THE OUTLINE OF THE IMAGE
X = B{1}(:,1);%..EXTRACT X AND Y COORDINATES
Y = B{1}(:,2);
indices = sub2ind(size(LT),X,Y);%..FIND THE CORRESPONDING LINEAR INDICES
C = LT(indices);%..NOW READ THE VALUES AT THE OUTLINE POSITION
Z = ones(size(X))*slice_number;
I can then plot this with
figure
scatter3(X,Y,Z,2,C)
Now the only thing I could improve is to have all these points in the scatter plot connected with a surface. #upperBound you suggested delaunay3 for this purpose - I cannot quite figure out how to do this. Do you have a tip?
I know I can create a 3D surface plot in MATLAB by doing:
x = linspace(1,10,100);
y = linspace(10,20,100);
[X Y] = meshgrid(x,y);
Z = X * Y;
surf(X,Y,Z);
But this requires that all the nodes for the height map generated line up. I have a set of data which has arbitrary points (x,y) and a height (z). Is there a simple way to plot a graph which will generate a surface between the points in a similar fashion to surf?
Appologies, after some hunting I managed to answer my own question:
You can use the trisurf function:
tri = delaunay(x,y);
trisurf(tri,x,y,z);
If you have dense data you will want to do shading interp (or another value, check doc shading) so you don't get a black blob due to the grid.
It looks like you've found your answer by using DELAUNAY and TRISURF to generate and plot a triangulated surface.
As an alternative, you could also fit a regularly-spaced grid to your nonuniformly-spaced points in order to generate a surface that can be plotted with the SURF command. I discuss how this can be done using the TriScatteredInterp class (or the deprecated function GRIDDATA) in my answer to this other question on SO.