객체 단위 분석
객체 단위 분석은 객체를 분할하여 특징을 분석하는 것을 의미한다.
영상이 입력되었을 때 객체와 배경이 분리될 수 있다고 가정하며 이진화를 통해 객체와 배경을 분리한다.
각각의 객체의 모양과 크기를 분석해서 내가 원하는 객체가 어디에 이쓰지 확인하고 싶을 때 객체단위 분석이 필요하다.
객체 위치 및 크기 정보, ROI 추출, 모양 분석 등을 할 수 있다.
객체 단위 분석 방법은 레이블링과 외곽선 검출이 있다.
레이블링 - Labeling
레이블링은 객체 구역을 영역 단위로 분석하는 것이다.
서로 연결되어 있는 객체 픽셀에 고유한 번호를 지정하는 작업(레이블맵)
일반적으로 이진 영상에서 수행한다.
레이블링 속도가 외곽선 검출보다 빨라서 더 효율적이다.
4-이웃 연결 관계(4-neighbor connectivity)
4-이웃 연결 관계는 어떤 객체가 연결되어 있을 때 두 개 픽셀이 상하좌우 관계로 연결되었을 때를 의미한다.
8-이웃 연결 관계(8-neighbor connectivity)
8-이웃 연결 관계는 상하좌우에 대각선도 포함하여 연결되어 있을 때를 의미한다. OpenCV는 보통 8-이웃 연결 관계를 사용한다.
레이블링 알고리즘의 입력과 출력
0은 배경 1이상은 객체로 판단한다. 객체들이 서로 연결되어 있으면 같은 번호를 지정한다.
같은 객체에 번호가 지정된 것을 레이블 맵이라고 한다. 레이블 맵은 정수형 행렬이다.
✔︎ 레이블링 함수 - cv2.connectedComponents
retval, labels = cv2.connectedComponents(image, labels=None, connectivity=None, ltype=None)
- image : 8비트 1채널 영상
- labels : 레이블 맵 행렬. 입력 영상과 같은 크기. numpy.ndarray.
- connectivity : 4 또는 8. 기본값은 8.
- ltype : labels 타입. cv2.CV_32S 또는 cv2.CV_16S.
기본값은 cv2.CV_32S. - retval : 객체 개수. N을 반환하면 [0, N-1]의 레이블이 존재하며, 0은 배경을 의미.
(실제 흰색 객체 개수는 N-1개)
retval은 객체 갯수 + 1 (배경 포함)을 반환하고, labels는 레이블맵 행렬을 반환한다.
✔︎ 객체 정보를 함께 반환하는 레이블링 함수 - cv2.connectedComponentsWithStats
retval, labels, stats, centroids = cv2.connectedComponentsWithStats(
image, labels=None, stats=None, centroids=None, connectivity=None, ltype=None)
- image : 8비트 1채널 영상
- labels : 레이블 맵 행렬. 입력 영상과 같은 크기. numpy.ndarray.
- stats : 각 객체의 바운딩 박스, 픽셀 개수 정보를 담은 행렬 numpy.ndarray.
shape=(N, 5), dtype=numpy.int32. - centroids : 각 객체의 무게 중심 위치 정보를 담은 행렬 numpy.ndarray.
shape=(N, 2), dtype=numpy.float64. - ltype : labels 행렬 타입.
cv2.CV_32S 또는 cv2.CV_16S. 기본값은 cv2.CV_32S.
- retval : 객체 수 + 1 (배경 포함)
- labels : 객체에 번호가 지정된 레이블 맵
- stats : N행 5열, N은 객체 수 + 1이며 각각의 행은 번호가 지정된 객체를 의미, 5열에는 x, y, width, height, area 순으로 정보가 담겨 있다. x,y 는 좌측 상단 좌표를 의미하며 area는 면적, 픽셀의 수를 의미한다.
- centroids : N행 2열, 2열에는 x,y 무게 중심 좌표가 입력되어 있다. 무게 중심 좌표는 픽셀의 x 좌표를 다 더해서 갯수로 나눈 값이다. y좌표도 동일하다
💬 키보드 영상에서 문자 영역 분할 예제
import sys
import numpy as np
import cv2
src = cv2.imread('keyboard.bmp', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
_, src_bin = cv2.threshold(src, 0, 255, cv2.THRESH_OTSU)
cnt, labels, stats, centroids = cv2.connectedComponentsWithStats(src_bin)
dst = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)
for i in range(1, cnt):
(x, y, w, h, area) = stats[i]
if area < 20:
continue
cv2.rectangle(dst, (x, y, w, h), (0, 255, 255))
cv2.imshow('src', src)
cv2.imshow('src_bin', src_bin)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
'OpenCV' 카테고리의 다른 글
[OpenCV with Python] 이진 영상 처리 : 다양한 외곽선 함수 (0) | 2022.02.04 |
---|---|
[OpenCV with Python] 이진 영상 처리 : 외곽선 검출 (0) | 2022.02.04 |
[OpenCV with Python] 이진 영상 처리 : 모폴로지(Morphology) - 열기와 닫기 (0) | 2022.02.04 |
[OpenCV with Python] 이진 영상 처리 : 모폴로지(Morphology) - 침식과 팽창 (0) | 2022.02.04 |
[OpenCV with Python] 이진 영상 처리 : 지역 이진화 - cv2.adaptiveThreshold (0) | 2022.02.04 |