SciPy 레이블링과 객체 분석 (SciPy.ndimage)
이미지 처리에서 중요한 작업 중 하나는 이미지 내의 특정 객체를 식별하고 분석하는 것입니다. 특히 이진 이미지에서 특정 형태를 가진 객체를 분리하고 개별적으로 분석하는 과정은 많은 이미지 처리 응용 프로그램에서 필요합니다. Python의 SciPy 라이브러리 중 scipy.ndimage
모듈은 이러한 작업을 효과적으로 수행할 수 있도록 다양한 기능을 제공합니다. 그중에서도 레이블링(Labeling)과 객체 분석(Object Analysis)은 이미지 내의 객체를 식별하고 속성을 추출하는 데 유용한 도구입니다.
이 글에서는 SciPy의 ndimage
모듈을 활용해 이진 이미지에서 객체를 레이블링하고, 각 객체의 특징을 분석하는 방법에 대해 상세히 알아보겠습니다.
1. 레이블링(Labeling)이란?
레이블링(Labeling)은 이진 이미지에서 연결된 영역(Connected Components)을 식별하고, 각 영역에 고유한 레이블을 부여하는 과정입니다. 예를 들어, 흑백 이미지에서 흰색 픽셀로 구성된 서로 다른 두 개의 객체가 있을 때, 각 객체를 다른 레이블로 구분하는 것입니다.
SciPy에서는 scipy.ndimage.label
함수를 사용하여 레이블링을 수행할 수 있습니다. 이 함수는 다음과 같은 결과를 반환합니다:
- labeled_array: 각 객체에 고유 번호가 부여된 배열
- num_features: 식별된 객체의 수
예제: 간단한 이진 이미지에서 레이블링 수행
아래는 작은 이진 이미지에서 레이블링을 수행하는 예제입니다.
import numpy as np
from scipy.ndimage import label
# 샘플 이진 이미지
binary_image = np.array([[0, 0, 1, 1, 0, 0],
[0, 1, 1, 1, 0, 0],
[0, 0, 0, 1, 0, 1],
[1, 1, 0, 0, 0, 1],
[0, 1, 1, 0, 0, 0]])
# 레이블링 수행
labeled_array, num_features = label(binary_image)
print("레이블 배열:\n", labeled_array)
print("객체 수:", num_features)
출력 결과
레이블 배열:
[[0 0 1 1 0 0]
[0 1 1 1 0 0]
[0 0 0 1 0 2]
[3 3 0 0 0 2]
[0 3 3 0 0 0]]
객체 수: 3
위 결과에서, 총 3개의 서로 다른 객체가 식별되었으며, 각 객체는 1, 2, 3의 레이블로 표시되었습니다.
2. 연결성(Connectivity)
레이블링을 수행할 때, 객체의 연결성을 정의하는 것이 중요합니다. 연결성은 픽셀이 서로 연결되었다고 판단하는 기준을 의미하며, 일반적으로 4-연결성(4-connected)과 8-연결성(8-connected)을 사용합니다.
- 4-연결성: 상하좌우 방향으로 연결된 픽셀만을 연결된 영역으로 간주합니다.
- 8-연결성: 대각선을 포함해 주변 8개 방향의 픽셀을 연결된 영역으로 간주합니다.
scipy.ndimage.label
함수에서는 structure
매개변수를 사용하여 연결성을 정의할 수 있습니다.
예제: 8-연결성 레이블링 수행
# 8-연결성을 위한 구조 요소 정의
structure = np.array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
# 8-연결성을 기준으로 레이블링 수행
labeled_array, num_features = label(binary_image, structure=structure)
print("8-연결성 레이블 배열:\n", labeled_array)
print("객체 수:", num_features)
3. 객체 속성 분석
레이블링이 완료된 후에는 각 객체의 속성을 분석할 수 있습니다. scipy.ndimage
모듈의 다양한 함수를 활용하면 다음과 같은 정보를 쉽게 얻을 수 있습니다.
- 객체의 크기:
ndimage.sum
- 중심 좌표:
ndimage.center_of_mass
- 바운딩 박스:
ndimage.find_objects
예제: 객체 속성 분석
아래는 레이블링된 이미지에서 각 객체의 크기와 중심 좌표를 구하는 예제입니다.
from scipy.ndimage import sum as nd_sum, center_of_mass
# 객체의 크기
object_sizes = nd_sum(binary_image, labeled_array, range(1, num_features + 1))
print("각 객체의 크기:", object_sizes)
# 객체의 중심 좌표
object_centroids = center_of_mass(binary_image, labeled_array, range(1, num_features + 1))
print("각 객체의 중심 좌표:", object_centroids)
출력 결과
각 객체의 크기: [5.0, 2.0, 4.0]
각 객체의 중심 좌표: [(1.2, 2.4), (2.5, 5.0), (3.25, 0.75)]
이와 같이, 객체의 크기와 중심 좌표를 쉽게 확인할 수 있습니다.
4. 실제 이미지에 적용하기
이번에는 실제 이미지를 사용하여 객체를 레이블링하고 분석하는 방법을 살펴보겠습니다. OpenCV와 SciPy를 함께 사용해 이진 이미지를 처리하고 분석하는 과정을 수행합니다.
예제: 이미지에서 객체 레이블링
import cv2
import matplotlib.pyplot as plt
# 이미지 불러오기
image = cv2.imread("sample_image.png", cv2.IMREAD_GRAYSCALE)
# 이진화 수행
_, binary_image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)
# 레이블링 수행
labeled_array, num_features = label(binary_image)
# 결과 시각화
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.title("이진 이미지")
plt.imshow(binary_image, cmap="gray")
plt.axis("off")
plt.subplot(1, 2, 2)
plt.title("레이블링 결과")
plt.imshow(labeled_array, cmap="nipy_spectral")
plt.axis("off")
plt.show()
이 방법을 통해 실제 이미지에서도 레이블링과 객체 분석을 효과적으로 수행할 수 있습니다.
5. 결론
SciPy의 ndimage
모듈을 활용하면 이미지 내의 객체를 효과적으로 식별하고 분석할 수 있습니다. 레이블링은 개별 객체를 구분하고, 크기, 위치, 형태 등 다양한 속성을 분석하는 데 중요한 역할을 합니다.
본 글에서 다룬 주요 내용은 다음과 같습니다:
- 레이블링:
scipy.ndimage.label
을 사용해 이진 이미지 내의 객체를 식별하는 방법 - 연결성: 4-연결성과 8-연결성을 정의하는 방법
- 객체 분석: 크기, 중심 좌표 등 다양한 속성을 분석하는 방법
- 실제 이미지 적용: OpenCV와 함께 실제 이미지에서 레이블링 수행
이러한 방법을 활용하면 다양한 이미지 처리 작업에서 객체 분석을 보다 쉽게 수행할 수 있습니다.
'Python SciPy' 카테고리의 다른 글
SciPy를 활용한 신호 처리와 시계열 데이터 분석 (0) | 2025.04.01 |
---|---|
SciPy 최적화와 통계를 결합한 데이터 분석 (0) | 2025.03.31 |
SciPy 엣지 검출과 히스토그램 분석: SciPy.ndimage를 활용한 이미지 처리 (0) | 2025.03.29 |
SciPy 이미지 필터링과 변형 (0) | 2025.03.28 |
SciPy 델로니 삼각 분할과 보로노이 다이어그램 (0) | 2025.03.27 |