Random walker segmentationΒΆ

The random walker algorithm [1] determines the segmentation of an image from a set of markers labeling several phases (2 or more). An anisotropic diffusion equation is solved with tracers initiated at the markers’ position. The local diffusivity coefficient is greater if neighboring pixels have similar values, so that diffusion is difficult across high gradients. The label of each unknown pixel is attributed to the label of the known marker that has the highest probability to be reached first during this diffusion process.

In this example, two phases are clearly visible, but the data are too noisy to perform the segmentation from the histogram only. We determine markers of the two phases from the extreme tails of the histogram of gray values, and use the random walker for the segmentation.

[1]Random walks for image segmentation, Leo Grady, IEEE Trans. Pattern Anal. Mach. Intell. 2006 Nov; 28(11):1768-83
../_images/plot_random_walker_segmentation_1.png

import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt

from skimage.segmentation import random_walker


def microstructure(l=256):
    """
    Synthetic binary data: binary microstructure with blobs.

    Parameters
    ----------

    l: int, optional
        linear size of the returned image
    """
    n = 5
    x, y = np.ogrid[0:l, 0:l]
    mask = np.zeros((l, l))
    generator = np.random.RandomState(1)
    points = l * generator.rand(2, n ** 2)
    mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
    mask = ndimage.gaussian_filter(mask, sigma=l / (4. * n))
    return (mask > mask.mean()).astype(np.float)


# Generate noisy synthetic data
data = microstructure(l=128)
data += 0.35 * np.random.randn(*data.shape)
markers = np.zeros(data.shape, dtype=np.uint)
markers[data < -0.3] = 1
markers[data > 1.3] = 2

# Run random walker algorithm
labels = random_walker(data, markers, beta=10, mode='bf')

# Plot results
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 3.2))
ax1.imshow(data, cmap='gray', interpolation='nearest')
ax1.axis('off')
ax1.set_title('Noisy data')
ax2.imshow(markers, cmap='hot', interpolation='nearest')
ax2.axis('off')
ax2.set_title('Markers')
ax3.imshow(labels, cmap='gray', interpolation='nearest')
ax3.axis('off')
ax3.set_title('Segmentation')

fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0,
                    right=1)
plt.show()

STDOUT


        

STDERR


        

Python source code: download (generated using skimage 0.11dev)

IPython Notebook: download (generated using skimage 0.11dev)

aW1wb3J0IG51bXB5IGFzIG5wCmZyb20gc2NpcHkgaW1wb3J0IG5kaW1hZ2UKaW1wb3J0IG1hdHBsb3RsaWIucHlwbG90IGFzIHBsdAoKZnJvbSBza2ltYWdlLnNlZ21lbnRhdGlvbiBpbXBvcnQgcmFuZG9tX3dhbGtlcgoKCmRlZiBtaWNyb3N0cnVjdHVyZShsPTI1Nik6CiAgICAiIiIKICAgIFN5bnRoZXRpYyBiaW5hcnkgZGF0YTogYmluYXJ5IG1pY3Jvc3RydWN0dXJlIHdpdGggYmxvYnMuCgogICAgUGFyYW1ldGVycwogICAgLS0tLS0tLS0tLQoKICAgIGw6IGludCwgb3B0aW9uYWwKICAgICAgICBsaW5lYXIgc2l6ZSBvZiB0aGUgcmV0dXJuZWQgaW1hZ2UKICAgICIiIgogICAgbiA9IDUKICAgIHgsIHkgPSBucC5vZ3JpZFswOmwsIDA6bF0KICAgIG1hc2sgPSBucC56ZXJvcygobCwgbCkpCiAgICBnZW5lcmF0b3IgPSBucC5yYW5kb20uUmFuZG9tU3RhdGUoMSkKICAgIHBvaW50cyA9IGwgKiBnZW5lcmF0b3IucmFuZCgyLCBuICoqIDIpCiAgICBtYXNrWyhwb2ludHNbMF0pLmFzdHlwZShucC5pbnQpLCAocG9pbnRzWzFdKS5hc3R5cGUobnAuaW50KV0gPSAxCiAgICBtYXNrID0gbmRpbWFnZS5nYXVzc2lhbl9maWx0ZXIobWFzaywgc2lnbWE9bCAvICg0LiAqIG4pKQogICAgcmV0dXJuIChtYXNrID4gbWFzay5tZWFuKCkpLmFzdHlwZShucC5mbG9hdCkKCgojIEdlbmVyYXRlIG5vaXN5IHN5bnRoZXRpYyBkYXRhCmRhdGEgPSBtaWNyb3N0cnVjdHVyZShsPTEyOCkKZGF0YSArPSAwLjM1ICogbnAucmFuZG9tLnJhbmRuKCpkYXRhLnNoYXBlKQptYXJrZXJzID0gbnAuemVyb3MoZGF0YS5zaGFwZSwgZHR5cGU9bnAudWludCkKbWFya2Vyc1tkYXRhIDwgLTAuM10gPSAxCm1hcmtlcnNbZGF0YSA+IDEuM10gPSAyCgojIFJ1biByYW5kb20gd2Fsa2VyIGFsZ29yaXRobQpsYWJlbHMgPSByYW5kb21fd2Fsa2VyKGRhdGEsIG1hcmtlcnMsIGJldGE9MTAsIG1vZGU9J2JmJykKCiMgUGxvdCByZXN1bHRzCmZpZywgKGF4MSwgYXgyLCBheDMpID0gcGx0LnN1YnBsb3RzKDEsIDMsIGZpZ3NpemU9KDgsIDMuMikpCmF4MS5pbXNob3coZGF0YSwgY21hcD0nZ3JheScsIGludGVycG9sYXRpb249J25lYXJlc3QnKQpheDEuYXhpcygnb2ZmJykKYXgxLnNldF90aXRsZSgnTm9pc3kgZGF0YScpCmF4Mi5pbXNob3cobWFya2VycywgY21hcD0naG90JywgaW50ZXJwb2xhdGlvbj0nbmVhcmVzdCcpCmF4Mi5heGlzKCdvZmYnKQpheDIuc2V0X3RpdGxlKCdNYXJrZXJzJykKYXgzLmltc2hvdyhsYWJlbHMsIGNtYXA9J2dyYXknLCBpbnRlcnBvbGF0aW9uPSduZWFyZXN0JykKYXgzLmF4aXMoJ29mZicpCmF4My5zZXRfdGl0bGUoJ1NlZ21lbnRhdGlvbicpCgpmaWcuc3VicGxvdHNfYWRqdXN0KGhzcGFjZT0wLjAxLCB3c3BhY2U9MC4wMSwgdG9wPTEsIGJvdHRvbT0wLCBsZWZ0PTAsCiAgICAgICAgICAgICAgICAgICAgcmlnaHQ9MSkKcGx0LnNob3coKQ==