Triangulated surface into 2D matrix - MATLAB - matlab

I have a 3D reconstruction that is of the format: vertices and faces.
It was read in by an STL, or an OBJ file, and I believe the terminology of this surface format is triangulated.
This is nice to visualise using trisurf, however I need the representation of my surface to be a 2D matrix.
Specifically: I have a 3 column matrix named vertices, and another 3 column matrix named faces. They do not have the same number of rows. I want a 2D matrix, where every cell in the matrix is the height of the surface.
Is this possible? How can this be done?

Related

Embedding 2d plot into a 3d plot in matlab?

I have a set of data vectors z that has this 2d plot
How would I go about embed this set of data into a 3d plot like this in matlab? I'm asking for advice and suggestions. The theory I'm trying to employ is "for each data vector~zj, “copies” the data vector intothe first two entries of a 3D data vector~yjand then computes the squared length of~zj as the third entry of~yj. " or kernel trick.
Your 2d data will somehow be in the form, that you have x-coordinates and y-coordinates. Let's say you have a vector x and a vector y for simplification.
As you found out the plot3-function proivdes functionality to plot arbitrary points in 3d without the need of generating a mesh. What you need additionally is a third vector z with data for the 3rd dimension.
So what else can you do? The thing I am thinking about is rotating the plane you are plotting you "2d" data:
Rotational matrices can be seen here:
https://en.wikipedia.org/wiki/Rotation_matrix

MATLAB: converting 3d plane into 3d matrix pixel locations

I am trying to get a slice of an elongated object in a 3d matrix (227x297x187 binary) that is orthogonal to its orientation..i.e. output image would be a 2d cross-section.
I was thinking the best way to do this would be to find a vector giving the orientation at some point on the object (so for a cross-section at the 40th slice I get the location of centroids at the 30th and 50th slices and find the vector between them), then get a list of pixels corresponding to a plane orthogonal to that vector at the desired slice (along centroid of object at 40th slice), and then retrieve the values in the matrix corresponding to those locations. Assuming the code I have attached finds the plane, I can plot it with surf() but don't know how to translate that into pixel locations in the matrix to generate the values for the 2d cross-section.
startslice=30;
endslice=50;
startnums=bwconncomp(binMATRIX(:,:,startslice));
startnums=regionprops(startnums,'Centroid');
endnums=bwconncomp(binMATRIX(:,:,endslice));
endnums=regionprops(endnums2,'Centroid');
midnums3=bwconncomp(binMATRIX(:,:,(startslice+(endslice-startslice)/2)));
midnums3=regionprops(midnums,'Centroid');
startstuff=[startslice, startnums.Centroid];
endstuff=[endslice, endnums.Centroid];
midstuff=[(startslice+(endslice-startslice)/2), midnums.Centroid];
nullstuff=null(endstuff-startstuff);
A=nullstuff(:,1);
B=nullstuff(:,2);
[x,y]=meshgrid(A,B);
z=1-x-y;
surf(x+midstuff(1),y+midstuff(2),z+midstuff(3))

what does the output of 3D delaunay triangulation represent?

I want to know what does the ConnectivityList in Delaunay triangulation in Matlab represent? Why does it have 4 columns?
Looking at Matlab's delaunayTriangulation class documentation,
the ConnectivityList is a triangulation connectivity list represented as a matrix.
Each row of the matrix corresponds to a tetrahedron (for 3D), or a triangle (for 2D).
Each element in the row is one of 4 vertex IDs of the tetrahedron (or for 2D, one of 3 vertex IDs of the triangle), a vertex ID being the row number of one of the points you provided to delaunayTriangulation().

How to make a video from a 3d matrix in matlab

I have a whole bunch of 2D matrices in matlab (they're suppose to make up a 3D matrix where the 3rd dimension is time), and I'm trying to make a video from the image data.
I know that I can use surf() to make a surface plot using one of the 2D matrices, but I'm not sure which command to invoke to take all my 2D matrices and convert them into a video of the surface plot.
Can anyone help?
The built-in function immovie(X,map) is one option for what you want. This function expects a m-by-n-by-1-by-k 4D matrix, where the 4th dimension is the frames of the movie. Since you're starting with a 3D matrix, use permute first:
Orig; % 3D matrix
X = permute(Orig,[1 2 4 3]); % 4D matrix
movie = immovie(X,map); % map is the colormap you want to use
implay(movie);

Matlab 3d plot of indexed data

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?