Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save cell center points in _seg.py #496

Open
FrickTobias opened this issue Apr 13, 2022 · 7 comments
Open

Save cell center points in _seg.py #496

FrickTobias opened this issue Apr 13, 2022 · 7 comments
Assignees
Labels
enhancement New feature or request

Comments

@FrickTobias
Copy link
Contributor

FrickTobias commented Apr 13, 2022

I was wondering if it would be possible to save more metadata about cells.

I am in need of cell center points for downstream computation and they are already calculated as far as I can understand.

Current workaround

Right now I am trying to do something based on a modification of masks_to_flows_cpu()

# From CellPose docs
dat = np.load('_seg.npy', allow_pickle=True).item()

# Assuming (hoping) this loads the correct information
masks = dat['masks']
centers = calculate_centers(masks)

# Modified from masks_to_flow_cpu()
def calculate_centers(masks):
    slices = scipy.ndimage.find_objects(masks)
    # Initiate centers in appropriate format
    for i,si in enumerate(slices):
        if si is not None:
            sr,sc = si
            y,x = np.nonzero(masks[sr, sc] == (i+1))
            y = y.astype(np.int32) + 1
            x = x.astype(np.int32) + 1
            ymed = np.median(y)
            xmed = np.median(x)
            center = (ymed, xmed)
            # Append center to centers
    return centers

Actual question

Would it be possible to save this in the output _seg.py files and load it into dat['centers']? Or possibly include a function for like calculate_centers()?

@FrickTobias
Copy link
Contributor Author

FrickTobias commented Apr 13, 2022

Update: Current (working) workaround for recalculating center points to plots, although I am not sure this will be correct always since it isn't calculated in the same way as in CellPose from what I can tell.

# Function for calculating centerpoints (again)
def calculate_centers(masks):
    slices = scipy.ndimage.find_objects(masks)
    centers = list()
    for i, si in enumerate(slices):
        if si is not None:
            sr, sc = si
            mask = masks[sr, sc]
            center = scipy.ndimage.center_of_mass(mask)
            center_rounded = (round(center[0]) + sr.start, round(center[1]) + sc.start)
            centers.append(center_rounded)
    return centers

# Load information and calculate center positions
dat = np.load('_seg.npy', allow_pickle=True).item()
masks = dat['masks']
image = dat['img']
centers = calculate_centers(masks)

# Initialize plot
plt.imshow(image)

# Add blue dots for every cell centra
for center in centers:
    y, x = center
    if xmin <= x <= xmax and ymin <= y <= ymax:
        plt.plot(x, y, marker = "o", markersize = 1, markeredgecolor = "blue", markerfacecolor = "blue")

# Show plot
plt.show()

@carsen-stringer
Copy link
Member

hey @FrickTobias I think there are several different ways to compute centers so we aren't going to support a specific function, but we could return the cell centers in the _seg.npy according to our function?

@FrickTobias
Copy link
Contributor Author

If that would be possible that would be great!

@carsen-stringer carsen-stringer added the enhancement New feature or request label Apr 30, 2022
@rocketeer1998
Copy link

Another workaround may be like this:

from scipy import ndimage

result = ndimage.center_of_mass(masks, masks, np.unique(masks)) 
resultList = list(result) 
df = pd.DataFrame(
    resultList, columns=['row', 'column'])
df.drop(0, inplace=True, axis=0)  #remove background NA
print(df)
df.to_csv("Centroid.csv")

Hope that helps.

@matrama
Copy link

matrama commented Jan 18, 2023

hi, I used a very similar workaround and used ndimage center of mass function. My problem is that even if cellpose masks are detected well - showing up in different colors on the tiff image, when masks are connected to each other - only 1 center of mass is detected. So I really would be in a favor of a ready function builder inside cellpose - to take their centers.

ANyone else had that problem - maybe I could use someones else hack?

@matrama
Copy link

matrama commented Jan 18, 2023

Hi, some update to the issue raised above:
After looking in more detail on the code of ppl above I used what rocketeer1998 posted: in the function center of mass use - your mask image poth as input and label. Those arrays should have same size, I have previously used labels function from ndimage to create label (2nd argument in center of mass function) and this resulted in an issue of some masks being treated as one big masks instead of separate masks.

@asrvsn
Copy link

asrvsn commented Mar 4, 2023

@rocketeer1998 Minor point: you may want to pass np.unique(masks)[1:] to avoid calculating a center of mass for the zero-valued pixels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants