계층적 군집화를 이용한 이미지 분할

Beginner

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

소개

이 실습에서는 계층적 군집화를 사용하여 2 차원 이미지를 분할하는 방법을 배웁니다. 계층적 군집화는 유사한 데이터 포인트를 함께 그룹화하는 군집화 알고리즘입니다. 이미지 분할의 맥락에서 계층적 군집화는 유사한 색상 강도를 가진 픽셀을 함께 그룹화하여 이미지에서 독특한 영역이나 객체를 식별하는 데 유용할 수 있습니다.

파이썬의 scikit-learn 라이브러리를 사용하여 동전 이미지에 대한 계층적 군집화를 수행할 것입니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근합니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사는 자동화될 수 없습니다.

학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

데이터 생성

데이터 생성부터 시작하겠습니다. scikit-image 의 coins 데이터셋을 사용할 것입니다. 이 데이터셋은 동전의 2 차원 회색조 이미지입니다. 처리 속도를 높이기 위해 이미지 크기를 원본 크기의 20% 로 줄일 것입니다.

from skimage.data import coins
import numpy as np
from scipy.ndimage import gaussian_filter
from skimage.transform import rescale

orig_coins = coins()

## 처리 속도를 높이기 위해 원본 크기의 20% 로 크기를 조정합니다.
## 다운스케일 전에 가우시안 필터를 적용하여 부드럽게 하면
## 앨리어싱 아티팩트를 줄일 수 있습니다.

smoothened_coins = gaussian_filter(orig_coins, sigma=2)
rescaled_coins = rescale(
    smoothened_coins,
    0.2,
    mode="reflect",
    anti_aliasing=False,
)

X = np.reshape(rescaled_coins, (-1, 1))

데이터 구조 정의

이미지의 픽셀은 인접 픽셀들과 연결되어 있습니다. 이미지에 대한 계층적 군집화를 수행하기 위해서는 데이터의 구조를 정의해야 합니다. scikit-learn 의 grid_to_graph 함수를 사용하여 데이터 구조를 정의하는 연결성 행렬을 생성할 수 있습니다.

from sklearn.feature_extraction.image import grid_to_graph

connectivity = grid_to_graph(*rescaled_coins.shape)

군집화 계산

데이터와 연결성 행렬이 정의되었으므로 이제 계층적 군집화를 수행할 수 있습니다. scikit-learn 의 AgglomerativeClustering 클래스를 사용하여 군집화를 수행할 것입니다. 이미지 내 동전 개수인 27 개의 클러스터를 설정할 것입니다. "ward" 연결 방법을 사용할 것입니다. 이 방법은 병합되는 클러스터 간 거리의 분산을 최소화합니다. 또한 2 단계에서 만든 연결성 행렬을 전달할 것입니다.

from sklearn.cluster import AgglomerativeClustering
import time as time

print("구조화된 계층적 군집화 계산...")
st = time.time()
n_clusters = 27  ## 영역 개수
ward = AgglomerativeClustering(
    n_clusters=n_clusters, linkage="ward", connectivity=connectivity
)
ward.fit(X)
label = np.reshape(ward.labels_, rescaled_coins.shape)
print(f"경과 시간: {time.time() - st:.3f}초")
print(f"픽셀 개수: {label.size}")
print(f"클러스터 개수: {np.unique(label).size}")

결과 플롯

마지막으로, 이미지에 결과를 플롯할 수 있습니다. Matplotlib 을 사용하여 재조정된 이미지와 클러스터의 윤곽선을 플롯할 것입니다. 각 클러스터를 반복하여 해당 클러스터의 픽셀 윤곽선을 플롯할 것입니다.

import matplotlib.pyplot as plt

plt.figure(figsize=(5, 5))
plt.imshow(rescaled_coins, cmap=plt.cm.gray)
for l in range(n_clusters):
    plt.contour(
        label == l,
        colors=[
            plt.cm.nipy_spectral(l / float(n_clusters)),
        ],
    )
plt.axis("off")
plt.show()

요약

이 실험에서는 계층적 군집화를 사용하여 2 차원 이미지를 분할하는 방법을 배웠습니다. 데이터를 생성하고, 데이터 구조를 정의하고, 계층적 군집화를 수행하며, 이미지에 결과를 플롯했습니다. 이 기술은 이미지에서 독특한 영역이나 객체를 식별하는 데 유용할 수 있습니다.