<jupyter_start><jupyter_text>Image Segmentation from membrane imagesCell segmentation from images showing membranes can be challenging, e.g. as some markers do not mark membranes continously. Thus, some pre-processing needs to be done in order to retrieve optimal segmentation results.To demonstrate the workflow, we're using single slices derived from 3D image data from the [Broad Bio Image Challenge](https://bbbc.broadinstitute.org/BBBC034), Thirstrup et al. 2018, available from the Broad Bioimage Benchmark Collection, Ljosa V, Sokolnicki KL, Carpenter AE (2012). Annotated high-throughput microscopy image sets for validation. Nature Methods 9(7):637 / doi. PMID: 22743765 PMCID: PMC3627348. Available at http://dx.doi.org/10.1038/nmeth.2083We start by opening an example image and configuring an intersting sub-region.<jupyter_code>from skimage.io import imread, imshow
import matplotlib.pyplot as plt
import numpy as np

input_image = imread("BBBC034_v1_dataset/AICS_12_134_C=0.tif")<jupyter_output><empty_output><jupyter_text>Next, we initialize the GPU<jupyter_code>import pyclesperanto_prototype as cle

# select a specific OpenCL / GPU device and see which one was chosen
cle.select_device('RTX')<jupyter_output><empty_output><jupyter_text>Initially, we push the image to GPU memory and segment it using thresholding to see how good it can be done right away.<jupyter_code>input_gpu = cle.push(input_image)

binary = cle.binary_not(cle.threshold_otsu(input_gpu))

labels = cle.voronoi_labeling(binary)

fig, axs = plt.subplots(1, 3, figsize=(15, 15))
cle.imshow(input_gpu, plot=axs[0])
cle.imshow(binary, plot=axs[1])
cle.imshow(labels, plot=axs[2], labels=True)<jupyter_output><empty_output><jupyter_text>Alternatively, with some intermediate correction, e.g. binary opening, we can improve segmentation quality in the binary image before labeling individual objects.<jupyter_code>binary = cle.binary_not(cle.threshold_otsu(input_gpu))

# binary opening, a.k.a. binary erosion followed by binary dilation:
corrected_binary = cle.maximum_box(cle.minimum_box(binary, radius_x=2, radius_y=2), radius_x=2, radius_y=2)

labels = cle.voronoi_labeling(corrected_binary)

fig, axs = plt.subplots(1, 3, figsize=(15, 15))
cle.imshow(input_gpu, plot=axs[0])
cle.imshow(binary, plot=axs[1])
cle.imshow(labels, plot=axs[2], labels=True)<jupyter_output><empty_output><jupyter_text>Alternatively, we can improve segmentation quality by making the membranes virtualy thicker in the original image before thresholding:<jupyter_code># grey value dilation, a.k.a. a maximum-filter
thicker_membranes = cle.maximum_sphere(input_image, radius_x=10, radius_y=10)

binary = cle.binary_not(cle.threshold_otsu(thicker_membranes))

labels = cle.voronoi_labeling(binary)

fig, axs = plt.subplots(1, 3, figsize=(15, 15))
cle.imshow(thicker_membranes, plot=axs[0])
cle.imshow(binary, plot=axs[1])
cle.imshow(labels, plot=axs[2], labels=True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09949238578680203, 'fraction_numerical': 0.029441624365482234, 'mean_word_length': 7.05449591280654, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '406165', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1063, 'n_tokens_neox': 966, 'n_words': 270, 'path': 'demo/segmentation/segmentation_2d_membranes.ipynb', 'repo_name': 'tlambert-forks/pyclesperanto_prototype', 'size': '2955'}