Raster geometry sphere not working as expected
Asked Answered
L

1

1

I'm trying to use raster geometry to make a sphere-shaped mask (found in How to generate a sphere in 3D Numpy array made by user @norok2). Code is as following:

import raster_geometry as rg
import numpy as np

sphere_mask = rg.sphere((224, 224, 160), 15,(112,112,80)) #rg.sphere takes(shape,radius,midpoint)
sphere_mask = sphere_mask.astype(np.int_) 

print(np.sum(sphere_mask))

When I print the sum of the sphere mask, it gives 0 so no sphere was created. Modifying the code to not include the midpoint however works fine:

import raster_geometry as rg
import numpy as np

sphere_mask = rg.sphere((224, 224, 160), 15) #rg.sphere takes(shape,radius,midpoint)
sphere_mask = sphere_mask.astype(np.int_) 

print(np.sum(sphere_mask))

I've adapted the midpoint to be contained well within the shape of the image. I'm not sure what's going wrong here?

Larisa answered 19/7, 2022 at 8:1 Comment(0)
L
1

The position parameter of rg.sphere() is a float or (float, float, float) which indicates the position of the center of the sphere in relative units, originating from its lowest edge.

This means that a value of 0.5 will translate into the middle of the shape. If a single value is provided, this is propagated in all dimensions, otherwise a value for each dimension must be provided.

import numpy as np
import raster_geometry as rg


m0 = rg.sphere((224, 224, 160), 15).astype(np.int_)
m1 = rg.sphere((224, 224, 160), 15, 0.5).astype(np.int_)
m2 = rg.sphere((224, 224, 160), 15, (0.5, 0.5, 0.5)).astype(np.int_)


print(np.sum(m0) > 0, np.allclose(m0, m1), np.allclose(m0, m2))
# True True True

If you provide a value outside of the (0.0, 1.0) interval, this will place the center outside of the shape, and unless the radius is large enough, it will produce an empty mask.


If you want to specify absolute values, you should use the more powerful rg.nd_superellipsoid() (which is what rg.sphere() uses internally anyway) where you can control how the position parameter is interpreted via the rel_position parameter.

Lucy answered 20/7, 2022 at 9:24 Comment(4)
Thank you so much! rg.nd_superellipsoid() works like a charm.Larisa
I am pretty confused about the package and can not find any documentation. In my case, I'd like to get a sphere mask of radius 5 for every voxel within a (100, 100, 50) array. How would I do that?Loos
@BertGayus have you checked the original question? There is much more info in thereLucy
@Lucy yes I did. Since I was not able to use your library properly, I have just used the sphere()-function you provided in your answer.Loos

© 2022 - 2025 — McMap. All rights reserved.