Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
omnipose documentation
Logo

Basics

  • Installation
  • GUI
  • Inputs
  • Settings
  • Outputs
  • Training
  • Models

Examples

  • In a notebook
    • The basics in 2D
    • Multiple channels
    • Omnipose in 3D
  • Command line

Project

  • API
    • omnipose.core
      • affinity_to_boundary
      • affinity_to_masks
      • affinity_to_masks2
      • batch_labels
      • boundary_to_affinity
      • boundary_to_masks
      • compute_masks
      • concatenate_labels
      • diameters
      • dist_to_diam
      • div_rescale
      • divergence
      • divergence_torch
      • divergence_torch_old
      • do_warp
      • fill_holes_and_remove_small_masks
      • flow_error
      • follow_flows
      • get_boundary
      • get_contour
      • get_link_matrix
      • get_links
      • get_masks
      • get_masks_cp
      • get_niter
      • labels_to_flows
      • linker_label_to_links
      • links_to_boundary
      • loss
      • masks_to_affinity
      • masks_to_flows
      • masks_to_flows_batch
      • masks_to_flows_torch
      • mode_filter
      • pill_decomposition
      • random_crop_warp
      • random_rotate_and_resize
      • remove_bad_flow_masks
      • scale_to_tenths
      • sigmoid
      • spatial_affinity
      • split_spacetime
      • step_factor
      • steps_batch
      • torch_and
      • torch_and_cpu
      • torch_and_gpu
    • omnipose.utils
      • add_poisson_noise
      • auto_chunked_quantile
      • average_tiles_ND
      • bin_counts
      • border_indices
      • clean_boundary
      • compute_density
      • compute_quantiles
      • correct_illumination
      • cubestats
      • curve_filter
      • extract_skeleton
      • find_boundaries
      • find_files
      • find_nonzero_runs
      • findbetween
      • gamma_normalize
      • generate_slices
      • get_edge_masks
      • get_flip
      • get_module
      • get_neigh_inds
      • get_neighbors
      • get_neighbors_torch
      • get_spruepoints
      • get_steps
      • get_supporting_inds
      • getname
      • hysteresis_threshold
      • is_integer
      • kernel_setup
      • load_nested_list
      • localnormalize
      • localnormalize_GPU
      • make_tiles_ND
      • mask_outline_overlay
      • mono_mask_bd
      • moving_average
      • normalize99
      • normalize99_hist
      • normalize_field
      • normalize_image
      • pnormalize
      • precompute_valid_mask
      • qnorm
      • quantile_rescale
      • ravel_index
      • rescale
      • rotate
      • safe_divide
      • save_nested_list
      • searchsorted
      • skeletonize
      • steps_to_indices
      • subsample_affinity
      • thin_skeleton
      • to_16_bit
      • to_8_bit
      • torch_norm
      • unaugment_tiles_ND
      • unravel_index
    • omnipose.plot
      • apply_ncolor
      • color_from_RGB
      • color_grid
      • color_swatches
      • colored_line
      • colored_line_segments
      • colorize
      • colorize_GPU
      • colorize_dask
      • colorize_dask_fast
      • colorize_dask_matmul
      • create_colormap
      • custom_new_gc
      • faded_segment_resample
      • figure
      • get_aspect
      • image_grid
      • imshow
      • plot_edges
      • rgb_flow
      • segmented_resample
      • set_outline
      • setup
      • split_list
      • truncate_colormap
      • vector_contours
    • cellpose_omni.models
      • BD_MODEL_NAMES
      • C1_BD_MODELS
      • C1_MODELS
      • C2_BD_MODELS
      • C2_MODELS
      • C2_MODEL_NAMES
      • CP_MODELS
      • Cellpose
      • CellposeModel
      • MODEL_DIR
      • MODEL_NAMES
      • MXNET_ENABLED
      • OMNI_INSTALLED
      • SizeModel
      • cache_model_path
      • deprecation_warning_cellprob_dist_threshold
      • model_path
      • models_logger
      • size_model_path
    • cellpose_omni.io
      • adjust_file_path
      • check_dir
      • delete_old_models
      • get_image_files
      • get_label_files
      • getname
      • imread
      • imsave
      • imwrite
      • load_links
      • load_train_test_data
      • logger_setup
      • masks_flows_to_seg
      • outlines_to_text
      • save_masks
      • save_server
      • save_to_png
      • write_links
    • cellpose_omni.plot
      • disk
      • dx_to_circ
      • image_to_rgb
      • interesting_patch
      • mask_overlay
      • mask_rgb
      • outline_view
      • show_segmentation
    • cellpose_omni.metrics
      • aggregated_jaccard_index
      • average_precision
      • boundary_scores
      • flow_error
      • mask_ious
    • cellpose_omni.dynamics
      • compute_masks
      • follow_flows
      • get_masks
      • labels_to_flows
      • map_coordinates
      • masks_to_flows
      • masks_to_flows_cpu
      • masks_to_flows_gpu
      • remove_bad_flow_masks
      • steps2D
      • steps2D_interp
      • steps3D
    • cellpose_omni.transforms
      • average_tiles
      • convert_image
      • make_tiles
      • move_axis
      • move_axis_new
      • move_min_dim
      • normalize99
      • normalize_field
      • normalize_img
      • original_random_rotate_and_resize
      • pad_image_ND
      • random_rotate_and_resize
      • reshape
      • reshape_and_normalize_data
      • reshape_train_test
      • resize_image
      • unaugment_tiles
      • update_axis
  • CLI

More

  • Affinity segmentation
  • Cell contours
  • N-color
  • Cell diameter
  • Gamma
  • Logo
Back to top
View this page

Logo¶

This is a little cute: Omnipose can "segment" text using the bact_phase_omni model. Semantic segmentation of uniform, disjoint shapes on a uniform background is absolutely no feat, but it is amusing that a neural network trained purely on phase contrast images of bacteria gives such reasonable output on something so different from the training set. Also, the over-segmentation at cusps hints that the network has learned to pick up on local morphology.

To make the Omnipose logo/title/favicon, I first generate some rasterized text images with roughly the same mean diameter as the bacteria in my training set:

Show code cell source Hide code cell source
 1# Make some text images
 2
 3from PIL import Image, ImageDraw, ImageFont
 4import numpy as np
 5import matplotlib.pyplot as plt
 6plt.style.use('dark_background')
 7import matplotlib as mpl
 8%matplotlib inline
 9mpl.rcParams['figure.dpi'] = 300
10
11from omnipose.measure import bbox_to_slice
12
13tsizes = [60]
14texts = ["Omnipose","O"]
15imgs = []
16for textsize in tsizes:
17    fonts = [ImageFont.truetype(f, textsize) for f in ["SFNSRounded.ttf"]]
18    # fonts = [ImageFont.truetype(f, textsize) for f in ["Arial.ttf"]]
19    for text in texts:
20        for font in fonts:
21            size = np.array([textsize*len(text)*2, textsize*2])
22            im = Image.new("RGB", tuple(size), "white")
23            d = ImageDraw.Draw(im)
24            center = size/2
25            anchor = "mm"
26            d.text(center, text, fill="black", anchor=anchor, font=font)
27            bbox = d.textbbox(center, text, anchor=anchor, font=font)
28            bbox = [bbox[1],bbox[0],bbox[3],bbox[2]] # reverse x, y
29            im = np.array(im)
30            shape = im.shape[:2]
31            slc = bbox_to_slice(bbox,shape,pad = 3)
32            im = im[slc]
33            imgs.append(im)
34        
35
36            fig = plt.figure(figsize=(1,1))
37            fig.patch.set_facecolor([0]*4)
38            
39            
40            plt.imshow(im)
41            plt.axis('off')
42            plt.show()
_images/42433300904d524ba81813563f388d7b9d28adcdb0857ba2191dfc4a53a10164.png _images/16051a00ab12ef6a7242e3ec7ed4324f11f84c82bbca803c38b799be1215fa00.png

Segmentation¶

I will then segment these image with the standard settings:

Show code cell source Hide code cell source
 1%%capture --no-display 
 2from cellpose_omni import plot, models, core
 3import omnipose
 4
 5model_name = 'bact_phase_omni'
 6use_GPU = core.use_gpu()
 7model = models.CellposeModel(gpu=use_GPU, model_type=model_name)
 8
 9
10chans = [0,0] #this means segment based on first channel, no second channel 
11nimg = len(imgs)
12n = range(nimg) 
13
14# define parameters
15mask_threshold = 1
16verbose = 0 
17use_gpu = use_GPU 
18transparency = True 
19rescale=None
20omni = True 
21flow_threshold = 0 
22resample = True 
23cluster = False
24
25masks, flows, styles = model.eval([imgs[i][...,-1] for i in n],
26                                  channels=chans,
27                                  rescale=rescale,
28                                  mask_threshold=mask_threshold,
29                                  transparency=transparency,
30                                  flow_threshold=flow_threshold,
31                                  omni=omni,resample=resample,
32                                  verbose=verbose, 
33                                  cluster=cluster)
34
35
36mpl.rcParams['figure.dpi'] = 300
37plt.style.use('dark_background')
38
39for idx,i in enumerate(n):
40
41    maski = masks[idx] # get masks
42    bdi = flows[idx][-1] # get boundaries
43    flowi = flows[idx][0] # get RGB flows 
44
45    # set up the output figure to better match the resolution of the images 
46    # f = 10
47    # szX = maski.shape[-1]/mpl.rcParams['figure.dpi']*f
48    # szY = maski.shape[-2]/mpl.rcParams['figure.dpi']*f
49    szX,szY = 10,10
50    fig = plt.figure(figsize=(szY,szX*4))
51    fig.patch.set_facecolor([0]*4)
52    
53    plot.show_segmentation(fig, omnipose.utils.normalize99(imgs[i]), 
54                           maski, flowi, bdi, channels=chans, omni=True, interpolation=None)
55
56    plt.tight_layout()
57    plt.show()
2025-06-28 01:35:10,274	[INFO]     cellpose_omni/models.py                   	 line 436	>>bact_phase_omni<< model set to be used
2025-06-28 01:35:10,276	[INFO]     cellpose_omni/core.py         assi...evice()	 line  67	Using GPU.
2025-06-28 01:35:10,540	[INFO]                                   __init__....()	 line 173	u-net config: ([2, 32, 64, 128, 256], 4, 2)
_images/57f0e0b9844078e31ec9a2f1d5805ecd867b8358919acec9e4ade041ecb42090.png _images/034063689d30edf3424a1baf4e898558d027c474b135e907382890c37b249989.png

I landed on this font because it is one of Apple's system defaults (and therefore works well with the system fonts used on our website when viewed on Apple devices), and I chose this scale because it is very close to bacteria and showed a good amount of 'segmentation' in the M, N, P, and E from purely local morphology (cusps). This gives reasonable output at higher-resolution text (wider 'cells'), but it starts to hallucinate output between objects if the size gets too large.

Adjusting transparency¶

The transparency (alpha channel) is set by the flow magnitude, and the color (RGB channels) is set by the flow angle according to a shifted sinebow relation:

angles = np.arctan2(dP[1], dP[0])+np.pi
r = ((np.cos(angles)+1)/2)
g = ((np.cos(angles+2*np.pi/3)+1)/2)
b =((np.cos(angles+4*np.pi/3)+1)/2)

(a is just a constant, not alpha). The slight tinge of green comes from the fact that np.arctan2(0,0)=0 and ((np.cos(0+2*np.pi/3)+1)/2) = 1/4. I'll try two ways to remove it: first by removing any average background bias, second by adjusting the alpha channel so that the background alpha is 0 on average.

Show code cell source Hide code cell source
 1import skimage.io
 2import os
 3from omnipose.utils import normalize99, rescale
 4from scipy.ndimage import zoom
 5from pathlib import Path
 6
 7omnidir = Path(omnipose.__file__).parent.parent.parent
 8basedir = os.path.join(omnidir,'docs','_static')
 9names = ['logo.png','icon.ico']
10ext = '.png'
11
12for idx,i in enumerate(n):
13
14    maski = masks[idx]
15    flowi = flows[idx][0]
16    dPi = flows[idx][1]
17    bias = [np.mean(d[maski==0]) for d in dPi]
18    angle = np.arctan2(bias[1], bias[0]) / np.pi
19    print('avarage bias is {}, average angle is {} pi rad.'.format(bias,angle))
20    dPi_new = np.stack([np.clip(d - b,-np.inf,np.inf) for d,b in zip(dPi,bias)])
21    flowi_new = plot.dx_to_circ(dPi_new,transparency=True)
22    
23    flowi_3 = flowi.copy()
24    alpha = flowi_3[...,-1]
25    flowi_3[...,-1] = rescale(np.clip(alpha-np.mean(alpha[maski==0]),0,np.inf))*255
26    
27    f = 30
28    szX = maski.shape[-1]/mpl.rcParams['figure.dpi']*f
29    szY = maski.shape[-2]/mpl.rcParams['figure.dpi']*f
30    fig = plt.figure(figsize=(szY,szX*4))
31    fig.patch.set_facecolor([0]*4)
32    
33    plt.imshow(np.hstack([flowi,flowi_new,flowi_3]))
34    plt.axis('off')
35    plt.show()
36    # aplha channel correction is the winner
37    # also rescale the image without interpolation so that, when displayed as favicon etc., it is not as smoothed out - we want to show real output 
38    skimage.io.imsave(os.path.join(basedir,names[idx]),zoom(flowi_3,(3,)*(flowi.ndim-1)+(1,),order=0)) 
39    
avarage bias is [0.062608756, 0.06555136], average angle is 0.25730722792217886 pi rad.
_images/a9aab432639fc065cae9da9bc0d32e1a21694edf6536df4ed8f16152f4157db8.png
avarage bias is [0.061921515, 0.06161317], average angle is 0.24920548520168206 pi rad.
_images/037248635c04bc1ac14ef61fc762417e7b00670654fdd49bc3a1a004b09cd7aa.png

Turns out that subtracting off the flow component bias introduces some over-correction in places, leading to some discoloration. So, alpha adjustment it is. It might be hard for you to see it, but I can. This level of pixel-peeping is how I made my ground-truth data ;-)

Exporting¶

Favicons need to be a particular resolution. For now I am making a multi-scale .ico, but that isn't working properly on Safari (too pixelated). Seems like multiple separate PNGs is the way to go moving forward.

 1from PIL import Image
 2filename = os.path.join(basedir,names[-1])
 3zimgs = []
 4
 5for j,sz in enumerate([(32,32), (128,128), (180,180), (192,192)]):
 6    scale = np.array(sz)/np.array(flowi_3.shape[0:2])
 7    zimg = zoom(flowi_3,tuple(scale)+(1,),order=(np.max(scale)<1)) 
 8    zimgs.append(zimg)
 9    # plt.imshow(zimg)
10    # plt.axis('off')
11    # plt.show()
12    # zimg.shape
13
14icon = Image.fromarray(zimgs[0], 'RGBA')
15icon.save(filename,append_images=[Image.fromarray(z, 'RGBA') for z in zimgs[1:]])
Previous
Gamma
Copyright © 2025, Kevin Cutler, University of Washington
Made with Furo
On this page
  • Logo
    • Segmentation
    • Adjusting transparency
    • Exporting