ankilab / DeepD3

Apache License 2.0
19 stars 6 forks source link

Extracting information about the 3D roi and their naming logic #6

Open PoulomiA opened 6 months ago

PoulomiA commented 6 months ago

Hello, I wanted to use DeepD3 to label spines and extract information about their size and the roi is from which z plane... I want the club all the rois for the same spine together to get their volumetric data.... Is it possible to get this information through the roi file or the name of the roi?

Any help would be appreciated!

anki-xyz commented 5 months ago

I believe the easiest way is to expert the ROI map from the GUI. Without binarization, you will get an ZxYxX tiff file, that has 0 for background and then 1 for ROI 1, 2 ROI 2, etc. A 3D ROI can span multiple planes. Some example code with help of ChatGPT:

import numpy as np
from scipy.ndimage import label, center_of_mass

# Function to create a sphere mask
def create_sphere(radius):
    diameter = 2 * radius + 1
    cube = np.zeros((diameter, diameter, diameter), dtype=np.uint8)
    center = radius
    for x in range(diameter):
        for y in range(diameter):
            for z in range(diameter):
                if (x - center) ** 2 + (y - center) ** 2 + (z - center) ** 2 <= radius ** 2:
                    cube[x, y, z] = 1
    return cube

# Function to place a sphere in the cube at a specified position
def place_sphere(cube, sphere, position):
    x, y, z = position
    x_end = min(x + sphere.shape[0], cube.shape[0])
    y_end = min(y + sphere.shape[1], cube.shape[1])
    z_end = min(z + sphere.shape[2], cube.shape[2])
    cube[x:x_end, y:y_end, z:z_end] += sphere[:x_end-x, :y_end-y, :z_end-z]
    return cube

# Create a 150x150x150 cube
cube = np.zeros((150, 150, 150), dtype=np.uint8)

# Create spheres and place them in the cube
sphere_radii = [5, 8, 10, 12]
for i, radius in enumerate(sphere_radii):
    sphere = create_sphere(radius)
    position = (20*(i+1), 20*(i+1), 20*(i+1))  # Adjust position to avoid overlap
    cube = place_sphere(cube, sphere * (i+1), position)

# Get the volume and center of mass of each sphere
### THESE ARE THE RELEVANT LINES
for i, radius in enumerate(sphere_radii):
    sphere_id = i + 1
    sphere_mask = cube == sphere_id
    volume = np.sum(sphere_mask)
    com = center_of_mass(sphere_mask)
    print(f"Sphere {sphere_id}: Volume = {volume}, Center of Mass = {com}")

The last couple of lines are the relevant ones.

Here's the output:

Sphere 1: Volume = 515, Center of Mass = (25.0, 25.0, 25.0)
Sphere 2: Volume = 2109, Center of Mass = (48.0, 48.0, 48.0)
Sphere 3: Volume = 4169, Center of Mass = (70.0, 70.0, 70.0)
Sphere 4: Volume = 7153, Center of Mass = (92.0, 92.0, 92.0)

And the image of the spheres as z-projection (some "fake" dendritic spines")

image