Using Napari object style


Is there any way of using napari as an class/Object more?
Something like this. I am trying many things, but I’m failing to do so.

If it’s not possible, what do you recommend for me to do a processing updating loop?

Start Napari -> Do cell segmentation in a file -> Show -> do cell segmentation in another file -> Clear Napari -> Show -> and so on.

class create_napari():
    import napari
    def __init__(self):    
        import napari
        with napari.gui_qt():
            self = napari.Viewer()

    def add_data(self,result):
        from cellpose.utils import masks_to_outlines
        import napari

    #         contrast_limits=[np.min(result[1]),np.max(result[1])],
    #         ndisplay=2,
v = create_napari()

Thank you.

1 Like

Hi @jmamede

I think this is a very important workflow to support, lots of other people will probably want to do something similar!

I am a bit confused about why you feel an object oriented design. It’s possible I misunderstood your explanation of what you’re trying to achieve. The process you describe here seems very well suited to a functional design. I would probably try to approach it like the example below, is that something that might work well for you?

import napari

with napari.gui_qt():
    viewer = napari.Viewer()

    for filename in all_filenames:
        # read file
        # display in napari
        # do cell segmentation
        # clear layers from napari

That’s what I ended up doing during the day and got it to work. However my @thread_worker while doing the cuda computing did not work, maybe another post for another day.

The reason of object based is practicality, and very common style of python I guess.

I found the %gui qt to handle the event loop, but it would only work in a notebook, which is fine.
Still being able to treat everything as a class sometimes makes it easier to create different programs.

That’s great news! Yes, I’d recommend making another post with more details if/when you want to talk about CUDA on your thread worker.

This worked.
(a bit too much and defeating the purpose, but as I called each “v.add_layer” it was adding it as I was coding.
It’s handy while developing before setting the whole code and functions.

import napari
from nd2reader import ND2Reader
# from support_pla import othercolor, cell_mask, multiply, rebin
from support_pla import detect_masks

%gui qt
v = napari.Viewer(show=False)
#     layer = viewer.add_image(np.random.random((512, 512)))
def updating(result):
    [v.layers.pop(0) for la in range(len(v.layers))]    

#         ndisplay=2,

#             contrast_limits=[np.min(result[2]),np.max(result[2])],

@thread_worker(connect={'yielded': updating})
def poseri(filelist,chan_cells,chan_nuclei,model,model_nuc):

    for ficheiro in filelist:
        reader = ND2Reader(ficheiro)
        reader.bundle_axes = 'cyx'
        reader.iter_axes = 'z'
        #there is a bug, it reads each visit point as a Z.
        reader.default_coords['v'] = 0
        ncells = 0
        nnuclei = 0
        #there's a bug in my reader, here's the 'Z' is actually visit points ('v').
        for i in range(reader.sizes['z']):

            cells_masks = detect_masks(reader[i][chan_cells],model
            #                             ,size=2500
            nuclei_masks = detect_masks(reader[i][chan_nuclei],model_nuc
            #                             ,size=2500
            cell_outlines = make_outlines(cells_masks)

            text = "Image#: {0} Number of Nuclei: {1} Number of positive cells: {2} Percentage: {3}".format(i,nuclei_masks.max(),cells_masks.max(),cells_masks.max()/nuclei_masks.max())

            yield [reader[i][chan_cells],reader[i][chan_nuclei],cells_masks,nuclei_masks]

model = initializesomestuff(GPU=True,model='cells')
model_nuc = initializesomestuff(GPU=True,model='nuclei')