Combining 2D slices into a 3D volume in python

This seems to be a pretty straightforward question, but it's actually not that easy without experience with image processing / processing.

I don't just want to stack 2D arrays on top of each other, but create 3D volumes by merging multiple 2D binary slices, separated by white space.

Example:
Define a 3D matrix with zeros:

A = np.zeros((100,100,100))

      

Place a rectangular area with units in the first slice A

:

A[0,25:75,25:75] = 1

      

Set a value in the middle of the last snippet A

for one:

A[99,50,50] = 1

      

How can I now merge these two slices linearly so that the result is a "pyramid" inside the 3D volume.

Thanks in advance for any suggestions.

Edit: The goal is to be able to select different volumes of interest by defining multiple 2D regions of interest in multiple slices. Imagine also, for example, defining a large circle at slice 0, a small circle at slice 50, and again a large circle at slice 100. The resulting volume of interest should be an "hourglass structure".

+3


source to share


2 answers


You should estimate the distance and angle between each point of the first cut and each point the last time, for each step, you should linearly decrease the distance with a constant angle.

A = np.zeros((100,100,100))
A[0,25:75,25:75] = 1
A[99,50,50] = 1

from math import sin, cos, atan2
dim = 100
for i99,j99 in np.swapaxes(np.where(A[dim-1]==1),0,1):
    for i0,j0 in np.swapaxes(np.where(A[0]==1),0,1):
        di = (i0-i99)
        dj = (j0-j99)
        dist = (di**2 + dj**2)**0.5
        ang = atan2(dj,di)
        for t in range(1,dim-1):
            ndist = dist * (1 - t/dim)
            pi = round(sin(ang)*ndist) + i99
            pj = round(cos(ang)*ndist) + j99
            A[t][pi][pj] = 1

      

Now we have to check our code

AT 2]:



A[96][48:53,48:53]

      

Conclusion [2]:

array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  1.,  1.,  0.],
       [ 0.,  1.,  1.,  1.,  0.],
       [ 0.,  1.,  1.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

      

0


source


I don't think you are "combining" things just by setting sequential layers A

for different values. Let's simplify the problem by working with a small 2d array. We can fill it with "watch glass" with these simple statements:

A=np.zeros((10,11),int)    
for i in range(0,5):
    j=i+1
    A[i, j:-j] = i
for i in range(5,10):
    j=10-i
    A[i, j:-j]=i

      

production:

array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0],
       [0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 6, 6, 6, 0, 0, 0, 0],
       [0, 0, 0, 7, 7, 7, 7, 7, 0, 0, 0],
       [0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0],
       [0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0]])

      



Generalizing this to 3d, and to other methods of selecting slices should be straightforward.

A=np.zeros((10,11,11),int)
for i in range(0,5):
    j=i+1
    A[i, j:-j, j:-j] = i

      

setting a circle instead of a square would require more code, but that's a different question, isn't it?

0


source







All Articles