MouseLand / cellpose

a generalist algorithm for cellular segmentation with human-in-the-loop capabilities
https://www.cellpose.org/
BSD 3-Clause "New" or "Revised" License
1.36k stars 390 forks source link

Mask output show non-connected cells having the same value #276

Closed puisheelee closed 3 years ago

puisheelee commented 3 years ago

Hi,

I realized in the mask output (both npy and tiff) some cells (not connected) share the same value, and thus resulting in incorrect extraction of the coordinates of cell centroids.

I am wondering how to fix this?

Thanks! Pui-Shee

kevinjohncutler commented 3 years ago

That's quite bad! Could you share an example?

puisheelee commented 3 years ago

Here are some examples. I extracted individual masks from npy file and save them as individual images (images shown are max-projection). I made bounding boxes around them to reduce the image size so it might seems like they are located at the edge (but they are not).

I used my own trained model and performed 3D segmentation with stitch_threshold >0.

In my samples, cells doesn't span the whole volume of the image stack. So, I am thinking this issue might probably due to the fact that values are assigned at the level of individual z-plane segmentation (before stitching), and stitch3D compare only masks in z[i] and z[i +1] if I understood correctly and thus cells could end up with the same value especially if they are located in distinct z-positions.

Maybe adding a quality control step after stitching could help? Taking into account the whole volume, check for connected components and reassign value to problematic cells?

example1 example2

puisheelee commented 3 years ago

Just to update, I found the solution to the problem. As my datasets are time-lapses, drift-correction preprocessing would sometimes results in empty first z-slice for some of the frames. This would create a problem when mmax = masks[0].max() is executed, since mmax = 0 in this case and the numbering of non-stitched cells would start from 1 again. So I added an if statement with

icount = masks[i+1].max()
istitch = np.arange(mmax+1, mmax + icount+1, 1, int)
mmax += icount
istitch = np.append(np.array(0), istitch)
masks[i+1] = istitch[masks[i+1]]

if the first z has no cells.