<jupyter_start><jupyter_text>ZEN blue is using a **UNet** for its pre-trained cell nucleus detetctor.- It is based on **TensorFlow 2** and accepts only tiles with **1024x1024** pixel- Normally, when used from within ZEN, the built-in Tiling & Image Fusion client chunks the images into "diggestable" pieces before calling the Segmentation Servive via REST-API calls- Therefore for this notebook we either need to pad or tile the images before segmenting it via the UNet from ZEN blue.More details how this works can be found here: [ZEN - Data Flow](https://github.com/zeiss-microscopy/OAD/tree/f47a5970fb710ba8066444b8c71f5781755fca64/Machine_Learningintellesis---data-flow)<jupyter_code>if use_method == 'zentf':

    # define tile overlap factor for MightyMosaic
    # overlapping_factor of X, meaning that the stride, between each tile is only tile_shape/X
    overlapfactor = 2 # 1 = no overlap

    # Define the model  folder Load the model
    #MODEL_FOLDER = 'model_folder'
    MODEL_FOLDER = 'zen_nucseg3_model'
    
    # class label for the nuclei
    classlabel_zenunet = 1
    
    # get the required tile size from the model metadata
    model, tile_height, tile_width = sgt.load_tfmodel(modelfolder=MODEL_FOLDER)
    print('ZEN TF Model Tile Dimension : ', tile_height, tile_width)
# get the metadata from the czi file
md, additional_mdczi = imf.get_metadata(filename)

# show some metainformation
print('------------------   Show Metainformation ------------------')

# shape and dimension entry from CZI file as returned by czifile.py
# be aware of the difference bewteen czifile.py and AICSImageIO
print('Array Shape (czifile)          : ', md['Shape_czifile'])
print('Dimension Entry (czifile)      : ', md['Axes_czifile'])
print('Array Shape (aicsimageio)      : ', md['Shape_aics'])
print('Dimension Entry (aicsimageio)  : ', md['Axes_aics'])
print('------------------------------------------------------------')
print('SizeS : ', md['SizeS'])
print('SizeT : ', md['SizeT'])
print('SizeZ : ', md['SizeZ'])
print('SizeC : ', md['SizeC'])
print('SizeX (czifile) : ', md['SizeX'])
print('SizeY (czifile) : ', md['SizeY'])
print('SizeY (aicsimageio) : ', md['SizeX_aics'])
print('SizeY (aicsimageio) : ', md['SizeY_aics'])
print('XScale : ', md['XScale'])
print('Yscale : ', md['YScale'])
print('Zscale : ', md['ZScale'])
### show complete metadata

# convert metadata dictionary to a pandas dataframe
mdframe = imf.md2dataframe(md)

# and display it nicely as a HTML inside the jupyter notebook
display(HTML(mdframe.to_html()))
# define columns names for dataframe for the measure objects
# every row will contain the plane indicies
cols = ['S', 'T', 'Z', 'C', 'Number']
objects = pd.DataFrame(columns=cols)

# set image counter to zero and create empty dataframe for the measured objects parameters
image_counter = 0
results = pd.DataFrame()
# for this norebook AICSImageIO is used to read the CZI files
# because it allows to read "only" wnat you want to analyze, which can be very beneficial
# for bigger datasets with multiple dimension such as 384 scenes from a wellplate

# get AICSImageIO object using the python wrapper for libCZI
img = AICSImage(filename)
# loop over every scene, timepoint and zplane incl progressbar for scenes
for s in progressbar.progressbar(range(md['SizeS']), redirect_stdout=True):
    for t in range(md['SizeT']):
        for z in range(md['SizeZ']):

            # get the current plane indicies and store them
            values = {'S': s, 'T': t, 'Z': z, 'C': chindex, 'Number': 0}

            if verbose:
                print('Analyzing S-T-Z-C: ', s, t, z, chindex)
            
            # read out a single 2D image planed using AICSImageIO
            image2d = img.get_image_data("YX", S=s, T=t, Z=z, C=chindex)

            # use the cellpose package to segemnt the nuclei
            if use_method == 'cellpose':
                # get the mask for the current image
                mask = sgt.segment_nuclei_cellpose(image2d, model,
                                                   rescale=None,
                                                   channels=channels,
                                                   diameter=diameter)
            
            # use scikit-image tools to segment the nuclei
            if use_method == 'scikit':
                mask = sgt.segment_threshold(image2d,
                                             filtermethod=filtermethod,
                                             filtersize=filtersize,
                                             threshold=threshold,
                                             split_ws=use_ws,
                                             min_distance=min_distance,
                                             ws_method=ws_method,
                                             radius=radius_dilation)
            
            # use the trained U-Net from ZEN blue 3.2 using TensorFlow 2 to segment the nuclei
            if use_method == 'zentf':

                # check if tiling is required if image2d is "too big" for the network
                if image2d.shape[0] > tile_height or image2d.shape[1] > tile_width:
                    binary = sgt.segment_zentf_tiling(image2d, model,
                                                      tilesize=tile_height,
                                                      classlabel=classlabel_zenunet,
                                                      overlap_factor=overlapfactor)

                # directly segment image if the size fits exactly
                elif image2d.shape[0] == tile_height and image2d.shape[1] == tile_width:
                    binary = sgt.segment_zentf(image2d, model,
                                               classlabel=classlabel_zenunet)

                # use padding if the image size is "too small" for the network
                elif image2d.shape[0] < tile_height or image2d.shape[1] < tile_width:

                    # do padding
                    image2d_padded, pad = sgt.add_padding(image2d,
                                                          input_height=tile_height,
                                                          input_width=tile_width)

                    # run prediction on padded image
                    binary_padded = sgt.segment_zentf(image2d_padded, model,
                                                      classlabel=classlabel_zenunet)

                    # remove padding from result
                    binary = binary_padded[pad[0]:tile_height - pad[1], pad[2]:tile_width - pad[3]]

                # apply watershed when specified
                if use_ws:
                    if ws_method == 'ws':
                        mask = sgt.apply_watershed(binary,
                                                   min_distance=min_distance)
                    if ws_method == 'ws_adv':
                        mask = sgt.apply_watershed_adv(image2d, binary,
                                                       min_distance=min_distance,
                                                       radius=radius_dilation)
                if not use_ws:
                    # label the objects
                    mask, num_features = ndimage.label(binary)
                    mask = mask.astype(np.int)
                    
            if use_method == 'stardist2d':

                mask = sgt.segment_nuclei_stardist(image2d, sdmodel,
                                                   prob_thresh=stardist_prob_thresh,
                                                   overlap_thresh=stardist_overlap_thresh,
                                                   norm=stardist_norm,
                                                   norm_pmin=stardist_norm_pmin,
                                                   norm_pmax=stardist_norm_pmax,
                                                   norm_clip=stardist_norm_clip)

            # clear the border by removing "touching" objects
            mask = segmentation.clear_border(mask)
            
            # define region properties to be measured
            to_measure = ('label',
                          'area',
                          'centroid',
                          'max_intensity',
                          'mean_intensity',
                          'min_intensity',
                          'bbox')

            # measure the specified parameters store in dataframe
            props = pd.DataFrame(
                measure.regionprops_table(
                    mask,
                    intensity_image=image2d,
                    properties=to_measure
                )
            ).set_index('label')

            # filter objects by size
            props = props[(props['area'] >= minsize) & (props['area'] <= maxsize)]

            # add well information for CZI metadata
            props['WellId'] = md['Well_ArrayNames'][s]
            props['Well_ColId'] = md['Well_ColId'][s]
            props['Well_RowId'] = md['Well_RowId'][s]

            # add plane indices
            props['S'] = s
            props['T'] = t
            props['Z'] = z
            props['C'] = chindex

            # count the number of objects
            values['Number'] = props.shape[0]
            # values['Number'] = len(regions) - 1
            if verbose:
                print('Well:', props['WellId'].iloc[0], 'Objects: ', values['Number'])

            # update dataframe containing the number of objects
            objects = objects.append(pd.DataFrame(values, index=[0]), ignore_index=True)
            results = results.append(props, ignore_index=True)

            image_counter += 1
            # optional display of results
            if image_counter - 1 in show_image:
                print('Well:', props['WellId'].iloc[0],
                      'Index S-T-Z-C:', s, t, z, chindex,
                      'Objects:', values['Number'])
                
                ax = vt.plot_segresults(image2d, mask, props, add_bbox=True)

# reorder dataframe with single objects
new_order = list(results.columns[-7:]) + list(results.columns[:-7])
results = results.reindex(columns=new_order)
# display objects for every analyzed scene
display(HTML(objects.to_html()))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0946024941543258, 'fraction_numerical': 0.008768511301636788, 'mean_word_length': 1.6026876267748478, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 52, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '397278', 'license': 'MIT', 'n_tokens_mistral': 2682, 'n_tokens_neox': 2553, 'n_words': 742, 'path': 'compare_nucleus_segmentation.ipynb', 'repo_name': 'sebi06/czi_demos', 'size': '10264'}