Agrupamento Espectral para Segmentação de Imagens

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Neste laboratório, aprenderemos a realizar segmentação de imagens usando agrupamento espectral. Geraremos uma imagem com múltiplos círculos conectados e usaremos o agrupamento espectral para separar os círculos.

Dicas da Máquina Virtual

Após o arranque da VM, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante o aprendizado, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos o problema rapidamente para si.

Gerar os dados

Vamos gerar uma imagem com quatro círculos usando o numpy. Em seguida, adicionaremos algum ruído à imagem e criaremos uma máscara para limitar a imagem ao primeiro plano.

import numpy as np

l = 100
x, y = np.indices((l, l))

center1 = (28, 24)
center2 = (40, 50)
center3 = (67, 58)
center4 = (24, 70)

radius1, radius2, radius3, radius4 = 16, 14, 15, 14

circle1 = (x - center1[0]) ** 2 + (y - center1[1]) ** 2 < radius1**2
circle2 = (x - center2[0]) ** 2 + (y - center2[1]) ** 2 < radius2**2
circle3 = (x - center3[0]) ** 2 + (y - center3[1]) ** 2 < radius3**2
circle4 = (x - center4[0]) ** 2 + (y - center4[1]) ** 2 < radius4**2

img = circle1 + circle2 + circle3 + circle4

mask = img.astype(bool)

img = img.astype(float)
img += 1 + 0.2 * np.random.randn(*img.shape)

Converter a imagem em um grafo

Usaremos img_to_graph de sklearn.feature_extraction.image para converter a imagem em um grafo. O valor do gradiente nas arestas também será calculado.

from sklearn.feature_extraction import image

graph = image.img_to_graph(img, mask=mask)

Agrupamento espectral

Usaremos a função spectral_clustering de sklearn.cluster para realizar o agrupamento espectral. O parâmetro n_clusters é definido como 4 para separar os quatro círculos.

from sklearn.cluster import spectral_clustering

labels = spectral_clustering(graph, n_clusters=4, eigen_solver="arpack")

Plotar os resultados

Plotaremos a imagem original e a imagem segmentada lado a lado usando matshow de matplotlib.pyplot.

import matplotlib.pyplot as plt

label_im = np.full(mask.shape, -1.0)
label_im[mask] = labels

fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
axs[0].matshow(img)
axs[1].matshow(label_im)

plt.show()

Plotando dois círculos

Repetiremos o processo acima, mas consideraremos apenas os dois primeiros círculos gerados.

img = circle1 + circle2
mask = img.astype(bool)
img = img.astype(float)

img += 1 + 0.2 * np.random.randn(*img.shape)

graph = image.img_to_graph(img, mask=mask)
graph.data = np.exp(-graph.data / graph.data.std())

labels = spectral_clustering(graph, n_clusters=2, eigen_solver="arpack")
label_im = np.full(mask.shape, -1.0)
label_im[mask] = labels

fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
axs[0].matshow(img)
axs[1].matshow(label_im)

plt.show()

Resumo

Neste laboratório, aprendemos como realizar a segmentação de imagens usando o agrupamento espectral. Geramos uma imagem com múltiplos círculos conectados, convertemos a imagem em um gráfico, realizamos o agrupamento espectral e plotamos os resultados.