Using Napari object style

Hi,

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

        self.add_image(
            result,
            blending='additive',
    #         contrast_limits=[np.min(result[1]),np.max(result[1])],
    #         ndisplay=2,
            colormap='blue',
            name='nuclei'
        )   
  
        
v = create_napari()
v.add_data(somerandom_nparray)

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
sys.path.insert(0,'/home/jmamede/scripts')
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)
v.show()
#     layer = viewer.add_image(np.random.random((512, 512)))
def updating(result):
    [v.layers.pop(0) for la in range(len(v.layers))]    

    v.add_image(
        result[0],
        blending='additive',
        contrast_limits=[np.min(result[1]),np.max(result[1])],
#         ndisplay=2,
        colormap='blue',
        name='nuclei'
    )   

    
    v.add_labels(
    result[1],
    opacity=0.4,
    blending='additive',
#             contrast_limits=[np.min(result[2]),np.max(result[2])],
    name='nuclei'
    ) 



@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
                                        ,threshold=0.8,size=0,diam=50
                                       )
            nuclei_masks = detect_masks(reader[i][chan_nuclei],model_nuc
            #                             ,size=2500
                                        ,threshold=1.2,size=0,diam=25
                                       )
            
            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())
            print(ficheiro,text)

            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')


poseri(filelist,0,1,model,model_nuc)