객체 단위 분석
- (흰색) 객체를 분할하여 특징을 분석
- 객체 위치 및 크기 정보, ROI 추출, 모양 분석 등
레이블링(Connected Component Labeling)
- 서로 연결되어 있는 객체 픽셀에 고유한 번호를 지정 (레이블맵)
- 영역 기반 모양 분석
- 레이블맵, 바운딩 박스, 픽셀 개수, 무게 중심 좌표를 반환
외곽선 검출(Contour Tracing)
- 각 객체의 외곽선 좌표를 모두 검출
- 외곽선 기반 모양 분석
- 다양한 외곽선 처리 함수에서 활용 가능 (근사화, 컨벡스헐 등)
레이블링(Labeling)이란?
- 동일 객체에 속한 모든 픽셀에 고유한 번호를 매기는 작업
- 일반적으로 이진 영상에서 수행
- OpenCV에서는 3.x 버전부터 최신 논문 기반의 레이블링 알고리즘 함수를 제공
- Connected component labeling
픽셀의 연결 관계
- 4-이웃 연결 관계 (4-neighbor connectivity)
- 8-이웃 연결 관계 (8-neighbor connectivity)
레이블링 알고리즘의 입력과 출력
레이블링 함수
cv2.connectedComponents(image, labels=None, connectivity=None, ltype=None) -> retval, labels
- 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개)
객체 정보를 함께 반환하는 레이블링 함수
cv2.connectedComponentsWithStats(image, labels=None, stats=None, centroids=None, connectivity=None, ltype=None) -> retval, labels, stats, centroids
- 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.
cv2.connectedComponentsWithStats() 함수 수행 결과의 예
mat = np.array([
[0, 0, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 1, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 1, 1, 1, 1, 0],
[0, 0, 1, 1, 0, 0, 1, 0],
[0, 0, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0]], np.uint8)
cnt, labels = cv2.connectedComponents(mat)
- 1번 객체에 대한 분석
(0, 0)
에 위치하는, 3 x 4
객체. 0이 아닌 수가 10
개 존재.
1.7
: 1번 객체의 0이 아닌 값들의 x좌표 위치 정보의 평균. 102+3+0+1+2+3+0+1+2+3=1.7
1.2
: 1번 객체의 0이 아닌 값들의 y좌표 위치 정보의 평균. 101+2+1+2+0+1+2+0+1+2=1.2
키보드 영상에서 문자 영역 분할 예제
src = cv2.imread('keyboard.bmp', cv2.IMREAD_GRAYSCALE)
_, 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, 0, 255))