How could I create a 3D binary matrix/image from a surface mesh in Matlab?
For instance, when I create ellipsoid using:
[x, y, z] = ellipsoid(0,0,0,5.9,3.25,3.25,30);
X, Y and X are all 2D matrix with size 31 x 31.
Edited based on suggestion of @Magla:
function Create_Mask_Basedon_Ellapsoid3()
close all
SurroundingVol = [50, 50, 20];
%DATA
[MatX,MatY,MatZ] = meshgrid(-24:1:25, -24:1:25, -9:1:10);
[mask1, x, y, z] = DrawEllipsoid([0, -10, 0], [6, 3, 3], MatX,MatY,MatZ);
[mask2, x2, y2, z2] = DrawEllipsoid([15, 14, 6], [6, 3, 3], MatX,MatY,MatZ);
mask = mask1 + mask2;
%Surface PLOT
figure('Color', 'w');
subplot(1,2,1);
%help: Ideally I would like to generate surf plot directly from combined mask= mask1 + mask2;
s = surf(x,y,z); hold on;
s2 = surf(x2,y2,z2); hold off;
title('SURFACE', 'FontSize', 16);
view(-78,22)
subplot(1,2,2);
xslice = median(MatX(:));
yslice = median(MatY(:));
zslice = median(MatZ(:));
%help: Also how do I decide correct "slice" and angles to 3D visualization.
h = slice(MatX, MatY, MatZ, double(mask), xslice, yslice, zslice)
title('BINARY MASK - SLICE VOLUME', 'FontSize', 16);
set(h, 'EdgeColor','none');
view(-78, 22)
%az = 0; el = 90;
%view(az, el);
end
function [mask, Ellipsoid_x, Ellipsoid_y, Ellipsoid_z] = DrawEllipsoid(CenterEllipsoid, SizeEllipsoid, MatX, MatY, MatZ)
[Ellipsoid_x, Ellipsoid_y, Ellipsoid_z] = ellipsoid(CenterEllipsoid(1), CenterEllipsoid(2), CenterEllipsoid(3), SizeEllipsoid(1)/2 , SizeEllipsoid(2)/2 , SizeEllipsoid(3)/2 ,30);
v = [Ellipsoid_x(:), Ellipsoid_y(:), Ellipsoid_z(:)]; %3D points
%v = [x(:), y(:), z(:)]; %3D points
tri = DelaunayTri(v); %triangulation
SI = pointLocation(tri,MatX(:),MatY(:),MatZ(:)); %index of simplex (returns NaN for all points outside the convex hull)
mask = ~isnan(SI); %binary
mask = reshape(mask,size(MatX)); %reshape the mask
end
There you go:
%// Points you want to test. Define as you need. This example uses a grid of 1e6
%// points on a cube of sides [-10,10]:
[x y z] = meshgrid(linspace(-10,10,100));
x = x(:);
y = y(:);
z = z(:); %// linearize
%// Ellipsoid data
center = [0 0 0]; %// center
semiaxes = [5 4 3]; %// semiaxes
%// Actual computation:
inner = (x-center(1)).^2/semiaxes(1).^2 ...
+ (y-center(2)).^2/semiaxes(2).^2 ...
+ (z-center(3)).^2/semiaxes(3).^2 <= 1;
For the n
-th point of the grid, whose coordinates are x(n)
, y(n)
, z(n)
, inner(n)
is 1
if the point lies in the interior of the ellipsoid and 0
otherwise.
For example: draw the interior points:
plot3(x(inner), y(inner), z(inner), '.' , 'markersize', .5)
Here is a method for creating a binary mask from an ellipsoid. It creates a corresponding volume and sets to NaN
the points outside the ellipsoid (ones
inside).
It doesn't take into consideration the formula of the ellipsoid, but uses a convex hull. Actually, it works for any volume that can be correctly described by a 3D convex hull. Here, the convexhulln
step is bypassed since the ellipsoid is already a convex hull.
All credits go to Converting convex hull to binary mask
The following plot
is produced by
%DATA
[x, y, z] = ellipsoid(0,0,0,5.9,3.25,3.25,30);
%METHOD
v = [x(:), y(:), z(:)]; %3D points
[X,Y,Z] = meshgrid(min(v(:)):0.1:max(v(:))); %volume mesh
tri = DelaunayTri(v); %triangulation
SI = pointLocation(tri,X(:),Y(:),Z(:)); %index of simplex (returns NaN for all points outside the convex hull)
mask = ~isnan(SI); %binary
mask = reshape(mask,size(X)); %reshape the mask
%PLOT
figure('Color', 'w');
subplot(1,2,1);
s = surf(x,y,z);
title('SURFACE', 'FontSize', 16);
view(-78,22)
subplot(1,2,2);
xslice = median(X(:));
yslice = median(Y(:));
zslice = median(Z(:));
h = slice(X, Y, Z, double(mask), xslice, yslice, zslice)
title('BINARY MASK - SLICE VOLUME', 'FontSize', 16);
set(h, 'EdgeColor','none');
view(-78,22)
Several ellipsoids
If you have more than one ellipsoid, one may use this masking method for each of them, and then combine the resulting masks with &
.
Choice of slices and angle
"Correct" is a matter of personal choice. You can either
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With