sliding window on 3d volume matlab - matlab

I need to slide a window over a 3d volume. The sliding is only on one layer of the 3d volume, i.e for each x,y with one specific z.
This is what I want to do in a loop:
for each x,y,z, for example:
px =9; py =9; pz =12;
a = rand(50,50,50);
[x y z] = meshgrid(1:50,1:50,1:50);
r = 3;
%-------------loop starts here:
% creating a shaped window, for example sphere of radius r
inds = find((x-px).^2 + (y-py).^2 + (z-pz).^2 <= r.^2);
% getting the relevant indices, here, it is the sphere around px,py,pz
[i,j,k] = ind2sub(size(a),inds);
% adjust the center of the sphere to be at (0,0,0) instead of (px,py,pz)
adj_inds = bsxfun(#minus,[i,j,k],[px,py,pz]);
% Computing for each sphere some kind of median point
cx = sum(a(inds).*adj_inds(:,1))./sum(a(inds));
cy = sum(a(inds).*adj_inds(:,2))./sum(a(inds));
cz = sum(a(inds).*adj_inds(:,3))./sum(a(inds));
%Saving the result: the distance between the new point and the center of the sphere.
res(yc,xc) = sqrt(sum([cx,cy,cz].^2));
%-------------
Now, all of this should happen many many time, ( ~300000), loop takes ages, convolution returns 3d volume (for each x,y,z) while I need to perform this only for each (x,y) and a list of z's.
Help please...
Thanks
matlabit

Related

How to find points inside, where sphere intersects with cylinder in MATLAB?

I am trying to identify points of sphere that are inside union of both sphere and cylinder, I have generated random points in side a cylinder as below
pts = 3000;
r= 3*((rand(pts,1)).^(1/3));
theta = 2*pi*rand(pts,1);
x= r.*cos(theta);
y= r.*sin(theta);
z=50*rand(size(x));
and generated random points inside a sphere as below
radius=10;
rvals = (2)*rand(pts,1)-(1);
elevation = asin(rvals);
azimuth = 2*pi*rand(pts,1);
radii =(rand(pts,1).^(1/3))*radius;
[point_x,point_y,point_z] = sph2cart(azimuth,elevation,radii);
The result will be as below
I need to find sphere points that is in intersection with cylinder and cylinder points that are in intersection with sphere.
Is there any general method to identify points inside intersection of different volumes ??
Can anyone help me? Thanks in advance,
Manu
Apparently, you have a sphere with center at (0, 0, 0) and radius 10. To check whether points of the cylinder are in the sphere, you can use:
cylinder_in_sphere = (x.^2 + y.^2 + z.^2) < 100
Your cylinder has radius 3 and a height of 50, so to check whether points of the sphere are in the cylinder, you can use:
sphere_in_cylinder = ((points_x.^2 + points_y.^2) < 9) & (points_z >= 0) & (points_z < 50)
Note that in this particular case points_z < 50 is always satisfied, so you can remove it in this particular case.

Estimating an ellipse with a multi-variate Gaussian

In MATLAB, say I have the parameters for an ellipse:
(x,y) center
Minor axis radius
Major axis radius
Angle of rotation
Now, I want to generate random points that lie within that ellipse, approximated from a 2D gaussian.
My attempt thus far is this:
num_samps = 100;
data = [randn(num_samps, 1)+x_center randn(num_samps, 1)+y_center];
This gives me a cluster of data that's approximately centered at the center, however if I draw the ellipse over the top some of the points might still be outside.
How do I enforce the axis rules and the rotation?
Thanks.
my assumptions
x_center = h
y_center = k
Minor Axis Radius = b
Major Axis Raduis = a
rotation angle = alpha
h=0;
k=0;
b=5;
a=10;
alpha=30;
num_samps = 100;
data = [randn(num_samps, 1)+h randn(num_samps, 1)+k];
chk=(((((data(:,1)-h).*cos(alpha)+(data(:,2)-k).*sin(alpha))./a).^2) +...
(((data(:,1)-h).*sin(alpha)+(data(:,2)-k).*cos(alpha))./b).^2)<=1;
idx=find(chk==0);
if ~isempty(idx)
data(idx,:)=data(idx,:)-.5*ones(length(idx),2);
end

I need to create a 3D sphere from a bunch of 2D slices

I currently have to create a sphere from a stack of 2D slices (2D matrices in MATLAB, which represent 2D gray scale images). I have created a bunch of slices using the code below. To create the sphere I have repeatedly created slices of circles of increasing size till 100, and then of decreasing sizes. All of these slices are added to a 3D matrix.
Circle = ones(200,400,400);
for i = 1:100
[rr cc] = meshgrid(1:400);
C = sqrt((rr-200).^2+(cc-200).^2)<=i;
for j = 1:400
for k = 1:400
Circle(i,j,k) = C(j,k);
end
end
end
index = 100;
for i = 1:100
[rr cc] = meshgrid(1:400);
C = sqrt((rr-200).^2+(cc-200).^2)<=index;
for j = 1:400
for k = 1:400
Circle(i+100,j,k) = C(j,k);
end
end
index = index - 1;
end
viewer3d(Circle);
viewer3d is 3rd part library that helps you view your 3D image stacks of slices as 3d objects. Once I visualized this 'supposed' sphere, I realized that it is a diamond shape top and not a sphere.
Therefore I do not understand how to vary the size of circles till the center point of the sphere in the y plane and then decrease it with the same algorithm.
Thank you for your answers and please do not hesitate to ask me to clarify anything within this question.
Alternatively, create a sphere directly, without using loops:
Circle = zeros(200,400,400);
[x,y,z]=meshgrid(1:size(Circle,1),1:size(Circle,2),1:size(Circle,3));
radius=??; %// e.g. radius=100;
%//this sphere is centered in the middle of the image
Circle(sqrt((x-size(Circle,1)/2).^2+(y-size(Circle,2)/2).^2..
+(z-size(Circle,2)/2).^2)<radius)=1;
Yes, the radius along the Z axis is not linear but varies with cos/sin function. Using this representation:
your radius is "Radius = r sin(Theta)", with "Theta = arccos(r / z)". So "r" is the radius of your sphere, and "z" the level/slice you want to draw in. Don't forget to that "z" goes from -"r" to "r". I've tested the formulae and it works fine for an image stack (slices).

Periodic boundary condition in Matlab for random spheres in a cube model

I have random non-overlapping spheres (stationary) in a cube. I am trying to implement periodic boundary condition on the walls, so that if there are any half sphere on the edge it appears on the other side. This seems to be a well studied problem, but am not sure how should i implement it on spheres.
At the start of the code, i would have random sphere position (c, r), where c = [ x y z] inside or on the edges of cube of dimension (dims), where dims = [ l b h ].
Code for selecting a random sphere in a cube:
function [ c, r ] = randomSphere_1( dims )
% creating one sphere at random inside [0..dims(1)]x[0..dims(2)]x...
% radius and center coordinates are sampled from a uniform distribution
% over the relevant domain.
%
% output: c - center of sphere (vector cx, cy,... )
% r - radius of sphere (scalar)
r = 0.15 + ( 0.55 - 0.15) .* rand(1);% radius varies between 0.15mm - 0.55mm
c = bsxfun (#times,(dims) , rand(1,3)) + r; % to make sure sphere is placed inside or on the edge of the cube
% periodic condition
*if*
I am trying to build a code if the center co-ordinates fall on the edge or over them then there should be periodicity in spheres that is the the other half should be on the other side. I have added an image just to give an idea about what i mean by periodic boundary condition. So the spheres on the edges are exactly how i want. How should i proceed with the problem?

create cylinders in 3D volumetric data

I'm trying to create a dataset of raw volumetric data consisting of geometrical shapes. The point is to use volume ray casting to project them in 2D but first I want to create the volume manually.
The geometry is consisting of one cylinder that is in the middle of the volume, along the Z axis and 2 smaller cylinders that are around the first one, deriving from rotations around the axes.
Here is my function so far:
function cyl= createCylinders(a, b, c, rad1, h1, rad2, h2)
% a : data width
% b : data height
% c : data depth
% rad1: radius of the big center cylinder
% rad2: radius of the smaller cylinders
% h1: height of the big center cylinder
% h2: height of the smaller cylinders
[Y X Z] =meshgrid(1:a,1:b,1:c); %matlab saves in a different order so X must be Y
centerX = a/2;
centerY = b/2;
centerZ = c/2;
theta = 0; %around y
fi = pi/4; %around x
% First cylinder
cyl = zeros(a,b,c);
% create for infinite height
R = sqrt((X-centerX).^2 + (Y-centerY).^2);
startZ = ceil(c/2) - floor(h1/2);
endZ = startZ + h1 - 1;
% then trim it to height = h1
temp = zeros(a,b,h1);
temp( R(:,:,startZ:endZ)<rad1 ) = 255;
cyl(:,:,startZ:endZ) = temp;
% Second cylinder
cyl2 = zeros(a,b,c);
A = (X-centerX)*cos(theta) + (Y-centerY)*sin(theta)*sin(fi) + (Z-centerZ)*cos(fi)*sin(theta);
B = (Y-centerY)*cos(fi) - (Z-centerZ)*sin(fi);
% create again for infinite height
R2 = sqrt(A.^2+B.^2);
cyl2(R2<rad2) = 255;
%then use 2 planes to trim outside of the limits
N = [ cos(fi)*sin(theta) -sin(fi) cos(fi)*cos(theta) ];
P = (rad2).*N + [ centerX centerY centerZ];
T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);
cyl2(T<0) = 0;
P = (rad2+h2).*N + [ centerX centerY centerZ];
T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);
cyl2(T>0) = 0;
% Third cylinder
% ...
cyl = cyl + cyl2;
cyl = uint8(round(cyl));
% ...
The concept is that the first cylinder is created and then "cut" according to the z-axis value, to define its height. The other cylinder is created using the relation A2 + B 2 = R2 where A and B are rotated accordingly using the rotation matrices only around x and y axes, using Ry(θ)Rx(φ) as described here.
Until now everything seems to be working, because I have implemented code (tested that it works well) to display the projection and the cylinders seem to have correct rotation when they are not "trimmed" from infinite height.
I calculate N which is the vector [0 0 1] aka z-axis rotated in the same way as the cylinder. Then I find two points P of the same distances that I want the cylinder's edges to be and calculate the plane equations T according to that points and normal vector. Lastly, I trim according to that equality. Or at least that's what I think I'm doing, because after the trimming I usually don't get anything (every value is zero). Or, the best thing I could get when I was experimenting was cylinders trimmed, but the planes of the top and bottom where not oriented well.
I would appreciate any help or corrections at my code, because I've been looking at the geometry equations and I can't find where the mistake is.
Edit:
This is a quick screenshot of the object I'm trying to create. NOTE that the cylinders are opaque in the volume data, all the inside is considered as homogeneous material.
I think instead of:
T = (X-P(1))*N(1) + (Y-P(2))*N(2) + (Z-P(3))*N(3);
you should try the following at both places:
T = (X-P(1)) + (Y-P(2)) + (Z-P(3));
Multiplying by N is to account for the direction of the axis of the 2nd cylinder which you have already done just above that step.