.. 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-30 .. code-block:: default 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 31-32 We start by loading the data: an image of a human retina. .. GENERATED FROM PYTHON SOURCE LINES 32-40 .. code-block:: default 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 41-44 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 44-58 .. code-block:: default 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 59-62 Based on the observed vesselness values, we use `hysteresis thresholding ` to define the main vessels. .. GENERATED FROM PYTHON SOURCE LINES 62-71 .. code-block:: default 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 72-76 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 76-96 .. code-block:: default 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:** (1 minutes 20.792 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.22.x?filepath=notebooks/auto_examples/applications/plot_pixel_graphs.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_pixel_graphs.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_pixel_graphs.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_