<jupyter_start><jupyter_text>Visual labeling comparisonA first important step when comparing segmentation algorithms is to visualize the results of the individual algorithms and showing differences between them.<jupyter_code>import numpy as np
from skimage.io import imread
from pyclesperanto_prototype import imshow
import matplotlib.pyplot as plt
import pandas as pd<jupyter_output><empty_output><jupyter_text>From just visualizing the images, we can see that none pair of the four compared algorithms produce the same label image.<jupyter_code>filenames = [
    "blobs_labels_imagej.tif",
    "blobs_labels_skimage.tif",
    "blobs_labels_clesperanto_python.tif",
    "blobs_labels_clesperanto_imagej.tif"
]

for filename in filenames:
    print(filename)
    label_image = imread(filename)
    imshow(label_image, labels=True)<jupyter_output>blobs_labels_imagej.tif<jupyter_text>As corresponding objects have different colours in this visualization, we can conclude that at least the labels of the objects are differnt. We cannot conclude yet if Otsu's thresholding method delivers different results in the given implementations. Difference imagesTo see the overlap between the different images, we will produce binary images from the label images and visualize the difference between these binary images.We first compare ImageJ's result and scikit-image's result to demonstrate the procedure.<jupyter_code>binary_blobs_imagej = imread(filenames[0]) > 0
binary_blobs_skimage = imread(filenames[1]) > 0
imshow(binary_blobs_imagej)
imshow(binary_blobs_skimage)<jupyter_output><empty_output><jupyter_text>When looking at these two images carefully, one can already see that objects are a tiny bit larger in the second image.To produce the `difference` image, we will use [numpy's `logical_xor` method](https://numpy.org/doc/stable/reference/generated/numpy.logical_xor.html). It will set all pixels in the `difference` image to 1, where either of the two input binary images are `1`, but not both. It is called the [exclusive-OR operator](https://en.wikipedia.org/wiki/Exclusive_or).<jupyter_code>difference = np.logical_xor(binary_blobs_imagej, binary_blobs_skimage)

fig, axs = plt.subplots(figsize=(10,10))
axs.imshow(difference)<jupyter_output><empty_output><jupyter_text>From this binary image, we can count the number of pixels that are different between these two approaches:<jupyter_code>np.sum(difference)<jupyter_output><empty_output><jupyter_text>A matrix of difference-pixel countsWe will now program two for-loops that iterate over pairs of label images and compare them using the same approach. The result will be a 4x4 matrix with the number of pixels that are different when comparing the corresponding algorithm implementations.<jupyter_code>matrix = {"Algorithms": filenames}

for filename_A in filenames:
    image_A = imread(filename_A)
    measurements = []
    for filename_B in filenames:
        image_B = imread(filename_B)
        
        difference = np.logical_xor(image_A, image_B)
        number_of_different_pixels = np.sum(difference)
        measurements.append(number_of_different_pixels)
    
    matrix[filename_A] = measurements
pd.DataFrame(matrix)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.06619018023617154, 'fraction_numerical': 0.0037290242386575512, 'mean_word_length': 5.907725321888412, 'pattern_counts': {'":': 1, '<': 24, '<?xml version=': 0, '>': 26, 'https://': 2, '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': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '628576', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 961, 'n_tokens_neox': 921, 'n_words': 309, 'path': 'docs/21_segmentation_comparison/visual_comparison.ipynb', 'repo_name': 'rayanirban/BioImageAnalysisNotebooks', 'size': '3218'}