.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/applications/plot_pixel_graphs.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_applications_plot_pixel_graphs.py: ==================================================== Use pixel graphs to find an object's geodesic center ==================================================== In various image analysis situations, it is useful to think of the pixels of an image, or of a region of an image, as a network or graph, in which each pixel is connected to its neighbors (with or without diagonals). One such situation is finding the *geodesic center* of an object, which is the point closest to all other points *if you are only allowed to travel on the pixels of the object*, rather than in a straight line. This point is the one with maximal *closeness centrality* [1]_ in the network. In this example, we create such a *pixel graph* of a skeleton and find the central pixel of that skeleton. This demonstrates its utility in contrast with the centroid (also known as the center of mass) which may actually fall outside the object. References ---------- .. [1] Linton C. Freeman: Centrality in networks: I. Conceptual clarification. Social Networks 1:215-239, 1979. :DOI:`10.1016/0378-8733(78)90021-7` .. GENERATED FROM PYTHON SOURCE LINES 25-31 .. code-block:: Python import matplotlib.pyplot as plt import numpy as np from scipy import ndimage as ndi from skimage import color, data, filters, graph, measure, morphology .. GENERATED FROM PYTHON SOURCE LINES 32-33 We start by loading the data: an image of a human retina. .. GENERATED FROM PYTHON SOURCE LINES 33-41 .. code-block:: Python retina_source = data.retina() _, ax = plt.subplots() ax.imshow(retina_source) ax.set_axis_off() _ = ax.set_title('Human retina') .. image-sg:: /auto_examples/applications/images/sphx_glr_plot_pixel_graphs_001.png :alt: Human retina :srcset: /auto_examples/applications/images/sphx_glr_plot_pixel_graphs_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 42-45 We convert the image to grayscale, then use the `Sato vesselness filter ` to better distinguish the main vessels in the image. .. GENERATED FROM PYTHON SOURCE LINES 45-59 .. code-block:: Python retina = color.rgb2gray(retina_source) t0, t1 = filters.threshold_multiotsu(retina, classes=3) mask = retina > t0 vessels = filters.sato(retina, sigmas=range(1, 10)) * mask _, axes = plt.subplots(nrows=1, ncols=2) axes[0].imshow(retina, cmap='gray') axes[0].set_axis_off() axes[0].set_title('grayscale') axes[1].imshow(vessels, cmap='magma') axes[1].set_axis_off() _ = axes[1].set_title('Sato vesselness') .. image-sg:: /auto_examples/applications/images/sphx_glr_plot_pixel_graphs_002.png :alt: grayscale, Sato vesselness :srcset: /auto_examples/applications/images/sphx_glr_plot_pixel_graphs_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 60-63 Based on the observed vesselness values, we use `hysteresis thresholding ` to define the main vessels. .. GENERATED FROM PYTHON SOURCE LINES 63-72 .. code-block:: Python thresholded = filters.apply_hysteresis_threshold(vessels, 0.01, 0.03) labeled = ndi.label(thresholded)[0] _, ax = plt.subplots() ax.imshow(color.label2rgb(labeled, retina)) ax.set_axis_off() _ = ax.set_title('Thresholded vesselness') .. image-sg:: /auto_examples/applications/images/sphx_glr_plot_pixel_graphs_003.png :alt: Thresholded vesselness :srcset: /auto_examples/applications/images/sphx_glr_plot_pixel_graphs_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 73-77 Finally, we can `skeletonize ` this label image and use that as the basis to find the `central pixel ` in that skeleton. Compare that to the position of the centroid! .. GENERATED FROM PYTHON SOURCE LINES 77-97 .. code-block:: Python largest_nonzero_label = np.argmax(np.bincount(labeled[labeled > 0])) binary = labeled == largest_nonzero_label skeleton = morphology.skeletonize(binary) g, nodes = graph.pixel_graph(skeleton, connectivity=2) px, distances = graph.central_pixel( g, nodes=nodes, shape=skeleton.shape, partition_size=100 ) centroid = measure.centroid(labeled > 0) _, ax = plt.subplots() ax.imshow(color.label2rgb(skeleton, retina)) ax.scatter(px[1], px[0], label='graph center') ax.scatter(centroid[1], centroid[0], label='centroid') ax.legend() ax.set_axis_off() ax.set_title('Vessel graph center vs centroid') plt.show() .. image-sg:: /auto_examples/applications/images/sphx_glr_plot_pixel_graphs_004.png :alt: Vessel graph center vs centroid :srcset: /auto_examples/applications/images/sphx_glr_plot_pixel_graphs_004.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 36.325 seconds) .. _sphx_glr_download_auto_examples_applications_plot_pixel_graphs.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/scikit-image/scikit-image/v0.24.0?filepath=notebooks/auto_examples/applications/plot_pixel_graphs.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_pixel_graphs.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_pixel_graphs.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_pixel_graphs.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_