
.. 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 <sphx_glr_download_auto_examples_applications_plot_pixel_graphs.py>`
        to download the full example code.

.. 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
    import skimage as ski








.. 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 = ski.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 <skimage.filters.sato>` to better distinguish the
main vessels in the image.

.. GENERATED FROM PYTHON SOURCE LINES 45-59

.. code-block:: Python


    retina = ski.color.rgb2gray(retina_source)
    t0, t1 = ski.filters.threshold_multiotsu(retina, classes=3)
    mask = retina > t0
    vessels = ski.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 <skimage.filters.apply_hysteresis_threshold>` to
define the main vessels.

.. GENERATED FROM PYTHON SOURCE LINES 63-72

.. code-block:: Python


    thresholded = ski.filters.apply_hysteresis_threshold(vessels, 0.01, 0.03)
    labeled = ndi.label(thresholded)[0]

    _, ax = plt.subplots()
    ax.imshow(ski.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 <skimage.morphology.skeletonize>` this label
image and use that as the basis to find the
`central pixel <skimage.graph.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 = ski.morphology.skeletonize(binary)
    g, nodes = ski.graph.pixel_graph(skeleton, connectivity=2)
    px, distances = ski.graph.central_pixel(
        g, nodes=nodes, shape=skeleton.shape, partition_size=100
    )

    centroid = ski.measure.centroid(labeled > 0)

    _, ax = plt.subplots()
    ax.imshow(ski.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 40.075 seconds)


.. _sphx_glr_download_auto_examples_applications_plot_pixel_graphs.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_pixel_graphs.ipynb <plot_pixel_graphs.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_pixel_graphs.py <plot_pixel_graphs.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_pixel_graphs.zip <plot_pixel_graphs.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
