 # Extract 3D measurements (volume, centroid... etc) from masked stack

Hello everybody,

I am trying to compute the volumes of some nuclei I have segmented, together with other measures such as the centroid position, for example. The problem is that I have a stack and so far I can only extract 2D data from each frame using skimage.measure.regionprops(). I would like to continue the image analysis in Python, therefore the question:

How can I calculate 3D measurements starting from this stack?

I do know the pixel size in xy and z, but I am not sure that simply computing that for the number of frames is correct. I was trying therefore to use skim age.measure.marching_cubes_lewiner, which computed the 3D surface area. But again, it is the area and I do not know how to translate this in the volume and other measurements.

### Sample image and/or code

This is only one frame of the masked stack. I have just opened in Fiji and it appears that all nuclei have the same value. Actually, in the stack I have every nucleus is labeled with a unique integer value so I can recognise them through the stack… anyway, this is just to give an idea.

Please, if you know how I can solve this problem let me know!

Thanks,
Lucrezia

1 Like

@LucreziaF what makes you say “I can only extract 2D data”? Most regionprops properties (including the ones you mentioned) work with 3D arrays. `.area` will give you the volume in pixels, `.centroid` will work as you would expect. Does that solve your problem?

Mmmm maybe I am not feeding the right data, but what I have are measurements for every labelled object in the frame, like the area. The information in z is missing. So, I am trying to sum all together taking into account the z step and scale of pixels in x and y but I am not sure this is the right approach…

That’s what I wrote:

``````labeled_frames = imread(fname=filename)
properties = ['label', 'area']
tables = [regionprops_table(labeled_frames[i], properties=properties) for i in range(len(labeled_frames))]

tables = [pd.DataFrame(table) for table in tables]
``````

So in this case I get a list of data frames, each for every frame, having the area and the label for each object. Then I convert the areas from pixel to micron scale and theoretically I was thinking to multiply that by the z step value inn micron and sum up… But I am wondering if there is a specific function implemented for that.

About the marching_cubes_lewiner, I am a bit confused by the outputs and I am not sure how to use them for my purpose…

Yeah, instead of calling regionprops for each frame, call regionprops on the whole `labeled_frames` image:

``````labeled_frames = imread(fname=filename)
properties = ['label', 'area', 'centroid']
table = pd.DataFrame(regionprops_table(labeled_frames, properties=properties))
``````

This will give you the volume of each region and its centroid in 3D.

From your original question I think you only want `maching_cubes` for volume, not surface area, so you shouldn’t need to use it here I think. `.area` will give you the volume in 3D. (Yes, we know this is confusing, that’s why there’s an issue about it! )