how to set decimal value to my matrix image index?

2 views (last 30 days)
Xinjie Cao
Xinjie Cao on 26 Apr 2022
Commented: Xinjie Cao on 28 Apr 2022
I am trying to generate an 3D image of a cylinder with 0.3 cm thickness wall using matrix based on the following code,
===================================
% Set dimensions
ds = 1; % mm
xlim = ds*150/2;
ylim = xlim;
zlim = ds*210/2;
% Forms a 41x41x51 matrix
[X,Y,Z] = meshgrid(-xlim:ds:xlim,-ylim:ds:ylim,-zlim:ds:zlim);
% Convert to cm
X = X./10;
Y = Y./10;
Z = Z./10;
% A matrix (matrix of radii)
A = sqrt(X.^2 + Y.^2);
% Set center axis to 1
A(A == 0) = 1;
% Anything outside of cylinder radius (7.8 cm) set to 0
A(abs(A) > 7.8) = 0;
A(abs(A) > 7.5 & abs(A) < 7.8) = 0.1;
% Convert all non-zeros to 1 (all pts on and inside cylinder)
A(abs(A) > 0 & abs(A) < 7.5) = 0.5;
imshow3D(A);
==================================
However the numerical index value I set was always apprixmated to 0 or 1. How can I set the index value to decimal number or bigger than 1?
Any answer will be highly appreciated!

Accepted Answer

DGM
DGM on 27 Apr 2022
Edited: DGM on 27 Apr 2022
You have some problems with your code that's causing the result to not have the number of gray levels you expect. I think imshow3D() tries to do some auto-contrast stretch that's making the bad result look binarized. You should be able to use imshow3D() with the fix below, but I'm not going to use it here on the forum.
You shouldn't be writing directly to the array of radius values. Once you do that, your new values match the subsequent tests and get filled in again. Also, in order to get your two adjacent masks to meet without pinholes, they need to be exact complements. Note the use of <= and > at the boundary of adjacent regions instead of < and >.
% Set dimensions
ro = 7.8;
th = 0.3;
ri = ro-th;
ds = 1; % mm
xlim = ds*150/2;
ylim = xlim;
zlim = ds*210/2;
% Forms a 41x41x51 matrix
[X,Y,Z] = meshgrid(-xlim:ds:xlim,-ylim:ds:ylim,-zlim:ds:zlim);
% Convert to cm
X = X./10;
Y = Y./10;
Z = Z./10;
R = sqrt(X.^2 + Y.^2);
A = zeros(size(R));
% Set center axis to 1
A(R == 0) = 1;
% Anything outside of cylinder radius (7.8 cm) set to 0
A(R > ro) = 0;
A(R > ri & R <= ro) = 0.8; % i'm using a brighter color so it's easier to see here
% Convert all non-zeros to 1 (all pts on and inside cylinder)
A(R > 0 & R <= ri) = 0.5;
%imshow3D(A);
imshow(A(:,:,10))
If you don't need to keep the X,Y and Z arrays and all you need is A, then you can save a lot of time and memory by doing:
% Set dimensions
ro = 7.8;
th = 0.3;
ri = ro-th;
ds = 1; % mm
xlim = ds*150/2;
ylim = xlim;
zlim = ds*210/2;
nz = zlim*2/ds + 1;
x = -xlim:ds:xlim; % 1D
y = (-ylim:ds:ylim).'; % 1D
R = sqrt((x/10).^2 + (y/10).^2); % 2D
A = zeros(size(R));
% Set center axis to 1
A(R == 0) = 1;
% Anything outside of cylinder radius (7.8 cm) set to 0
A(R > ro) = 0;
A(R > ri & R <= ro) = 0.8; % i'm using a brighter color so it's easier to see here
% Convert all non-zeros to 1 (all pts on and inside cylinder)
A(R > 0 & R <= ri) = 0.5;
A = repmat(A,[1 1 nz]); % this is the only 3D array
%imshow3D(A);
imshow(A(:,:,10))
... but that might not be an option if you need those for coordinates.
  3 Comments
Xinjie Cao
Xinjie Cao on 28 Apr 2022
Regarding your comment,
"I don't know if it's intended, but the cylinder walls extend past the array boundaries. If that's not supposed to happen, you might want to adjust your limits."
Yes, I forgot to adjust that when I changed my cylinder size.
Many thanks to your comments, really learned a lot!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!