haesleinhuepf / napari-segment-blobs-and-things-with-membranes

A plugin based on scikit-image for segmenting nuclei and cells based on fluorescent microscopy images with high intensity in nuclei and/or membranes.
BSD 3-Clause "New" or "Revised" License
23 stars 8 forks source link

`StackViewNDArray` breaks downstream functions #35

Closed jo-mueller closed 1 month ago

jo-mueller commented 1 month ago

Hi @haesleinhuepf ,

I just wanted to report an issue I ran into earlier.

This does not work:

from skimage import data, measure
import napari_segment_blobs_and_things_with_membranes as nsbatwm
import pandas as pd

image = data.human_mitosis()
labels = nsbatwm.voronoi_otsu_labeling(image, spot_sigma=5)
measurements = pd.DataFrame(measure.regionprops_table(labels, intensity_image=image, properties=['label', 'area']))

---------------------------------------------------------------------------
{
    "name": "IndexError",
    "message": "tuple index out of range",
    "stack": "---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[2], line 8
      6 image = data.human_mitosis()
      7 labels = nsbatwm.voronoi_otsu_labeling(image, spot_sigma=5)
----> 8 measurements = pd.DataFrame(measure.regionprops_table(labels, intensity_image=image, properties=['label', 'area']))

File c:\\Users\\johamuel\\AppData\\Local\\mambaforge\\envs\\clusters-plotter-dev\\lib\\site-packages\\skimage\\measure\\_regionprops.py:1043, in regionprops_table(label_image, intensity_image, properties, cache, separator, extra_properties, spacing)
   1039     out_d = _props_to_dict(regions, properties=properties,
   1040                            separator=separator)
   1041     return {k: v[:0] for k, v in out_d.items()}
-> 1043 return _props_to_dict(
   1044     regions, properties=properties, separator=separator
   1045 )

File c:\\Users\\johamuel\\AppData\\Local\\mambaforge\\envs\\clusters-plotter-dev\\lib\\site-packages\\skimage\\measure\\_regionprops.py:865, in _props_to_dict(regions, properties, separator)
    861 for ind in np.ndindex(np.shape(rp)):
    862     modified_props.append(
    863         separator.join(map(str, (orig_prop,) + ind))
    864     )
--> 865     locs.append(ind if len(ind) > 1 else ind[0])
    867 # fill temporary column data_array
    868 n_columns = len(locs)

IndexError: tuple index out of range"
}

This works:

from skimage import data, measure
import napari_segment_blobs_and_things_with_membranes as nsbatwm
import pandas as pd

image = data.human_mitosis()
labels = np.asarray(nsbatwm.voronoi_otsu_labeling(image, spot_sigma=5))
measurements = pd.DataFrame(measure.regionprops_table(labels, intensity_image=image, properties=['label', 'area']))

The only difference is probably just that in the above case, nsbatwm returns a StackViewNDArray, which is probably inherited from a regular numpy array. Still, it seems to miss some properties for regionprops to throw an error.

I'm not sure whether it's a bug or a feature or whether you think that this would belong here or in the stackview repo. I can totally move it to stackview if you feel that's where it belongs.

Versions:

import skimage
skimage.__version__

>>> 0.24.0

nsbatwm.__version__
>>> 0.3.8

edit: Added traceback

haesleinhuepf commented 1 month ago

This does not work:

It would be awesome if you could expand on this. Is there an error or are the results wrong? What does not work? When reporting bugs always try to minimize efforts on the other side in order to maximize outcome. Thanks!

jo-mueller commented 1 month ago

Hi @haesleinhuepf , sorry - added the traceback above. Aside from that I'm afraid it's hard for me to guess what exactly is going wrong :/ My best guess is that regionprops/scikit-image relies on some property of numpy arrays that is somehow not handled by either the inheritance of the StackViewNDArray or the way that the resulting StackViewNDArray is initialized by nsbatwm. Hope the minimal working example helps, though.

haesleinhuepf commented 1 month ago

Awesome, thanks @jo-mueller ! Your intuition was right. The StackViewNDArray failed passing this test in some special scenario: A 1x1 label image is a scalar per definition in numpy, but was not in stackview.

This should be fixed in stackview 0.9.0, please try it out:

pip install stackview==0.9.0

And let me know if the issue is resolved on your side. Thanks for the bug report!

jo-mueller commented 1 month ago

@haesleinhuepf can confirm this works. Would it be worthwhile to update the version pin of stackview here, then?

haesleinhuepf commented 1 month ago

That makes sense. Thanks for the feedback and thanks again for reporting the issue!