반응형
Labeling
배경과 객체를 구분 한 후 Lableing을 이용하여 객체 간 구분
- 연결 구성 요소 Labeling(CCL, Connected Component Labeling)
- 객체 인식을 위한 전처리 과정으로 사용.
- 이진화 영상에서 수행(배경 : 검은색, 객체 : 흰색)
- 연결성 정의에 따라 결과가 달라질 수 있다.
▶ 픽셀 연결 관계
이웃한 픽셀의 연결 관계는 4-방향 연결성, 8-방향 연결성으로 정의된다. 4방향은 상하좌우로만 연결되며 8방향은 대각선 인접 픽셀들도 연결되어 있다고 간주한다.
▶ 고전적 Labeling 기법
- 1966년 A. Rosenfeld의 논문에서 Equivalent table(등가 테이블)을 만들면서 영상을 두번 스캔 함으로써 레이블링을 수행
- 첫 번째 스캔에서는 레이블을 전파시키면서 등가 테이블 생성
- 두 번째 스캔에서는 등가 테이블을 참조하여 각 픽셀에 고유의 레이블을 부여.
- 4 - 이웃 연결성 고려.임의의 위치에서 위쪽과 왼쪽 두 이웃 픽셀을 조사하여
- 두 이웃 픽셀의 레이블이 존재하지 않은 경우
- 새로운 레이블을 지정.
- 자신의 레이블을 가리키는 새 등가 테이블 항목을 생성.
- 두 이웃 픽셀 중 하나에만 레이블이 존재하는 경우
- 이웃 픽셀과 동일한 레이블을 지정.
- 두 이웃 픽셀 모두에 레이블이 존재하며, 서로 동일한 레이블인 경우.
- 이웃 픽셀과 동일한 레이블을 지정.
- 두 이웃 픽셀 모두에 레이블이 존재하며, 서로 다른 레이블인 경우
- 두 레이블 중 작은 번호의 레이블을 지정.
- 두 레이블 중 큰 번호의 레이블이 작은 번호의 레이블을 가리키도록 등가 테이블을 조정.
- 두 이웃 픽셀의 레이블이 존재하지 않은 경우
Labeling Function
▶ cv2.connectedComponents(src, connectivity, ltype) → retbal, labels
- src : 8비트 1채널 영상
- connectivity : 4 or 8, 기본값 8
- ltype : labes 타입, 기본값은 cv2.CV_32S (32bit signed integer)
- retval : 객체 개수(레이블 개수) N 반환, 카운팅을 0부터 하지만 0은 배경객체이므로 실제 객체 개수는 N-1
- labels : 레이블 맵 행렬
▶ cv2.connectedComponentsWithStats(src, connectivity, ltype) → retval, labels, stats, centroids
- 기본적인 파라미터, 입/출력 데이터 타입은 connectedComponecnts()와 동일
- stats : 추출된 객체의 위치, 가로세로 길이, 면적 등의 정보 행렬
- 각행의 N번째 객체의 정보를 담고있다.
- [객체를 감싸는 바운딩 박스의 x좌표 시작점, 객체를 감싸는 바운딩 박스의 y좌표 시작점, 객체 가로 크기, 객체 세로 크기, 객체의 총 픽셀 개수]
- centroids : 객체들의 무게 중심 정보
- 각 행이 N번째 객체의 무게 중심 좌표(x,y)를 담고 있다.
- 무게 중심은 객체의 모든 픽셀의 x좌표를 더한 값을 픽셀 개수로 나눈 값과 y좌표를 더한 값을 픽셀 개수로 나눈 값으로 구한다.
▶ 3개의 원으로 Labeling 실습
In [4]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/circles.jpg', 0)
# flip = 255-src # 흑백 반전
# ret, dst = cv2.threshold(flip, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) #영상 이진화
ret, dst = cv2.threshold(src, 128, 255, cv2.THRESH_BINARY_INV) #흑백 반전, 영상 이진화
cnt, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)
print("cnt : ", cnt, "\n")
print('labels :', np.unique(labels), "\n")
print('stats : \n', stats, "\n")
print('centroids: \n', centroids, "\n")
flip2 = 255-dst # 흑백 반전
dst2 = cv2.cvtColor(flip2, cv2.COLOR_GRAY2BGR) #BGR화
for i in range(1, cnt):
x, y, width, height, area = stats[i]
cv2.rectangle(dst2, (x,y), (width+x, height+y), (0,0,255), 2) # 각 객체의 박스 생성
cx = x + (width//2)
cy = y + (width//2)
cv2.circle(dst2,(cx, cy), 4, (0,0,255), 8) #각 객체의 중심원 생성
# 문자 출력
fontFace = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(dst2, f"label={i}", (x, y-5), fontFace, 0.6, (255,0,0), 2)
cv2.rectangle(dst2, (0,0) ,(stats[0][2],stats[0][3]), (255,0,0), 5) # 전체 사각형 생성
cv2.circle(dst2, (stats[0][2]//2 ,stats[0][3]//2), 2, (0,255,0), 8) # 중심 원 생성
plt.style.use("grayscale")
plt.figure(figsize=(15,30)) #width, height
ax1 = plt.subplot(4,2,1)
ax2 = plt.subplot(4,2,2)
ax3 = plt.subplot(4,2,3)
ax1.imshow(src)
ax2.imshow(dst)
ax3.imshow(dst2)
ax1.axis('off')
ax2.axis('off')
ax3.axis('off')
ax1.set_title("")
ax2.set_title("")
ax3.set_title("")
# cv2.imshow('dst', src)
# cv2.imshow('dst', dst)
# cv2.imshow('dst2', dst2)
# cv2.waitKey()
# cv2.destroyAllWindows()
# cv2.waitKey(1)
cnt : 4
labels : [0 1 2 3]
stats :
[[ 0 0 512 512 227637]
[ 340 110 121 121 11289]
[ 180 180 141 141 15373]
[ 300 350 101 101 7845]]
centroids:
[[245.44863972 255.13168773]
[400. 170. ]
[250. 250. ]
[350. 400. ]]
Out[4]:
Text(0.5, 1.0, '')
반응형
'Python' 카테고리의 다른 글
[Python] openCV : Corner Detect (0) | 2022.11.17 |
---|---|
[Python] openCV : Canny Edge Detection (0) | 2022.11.17 |
[Python] openCV : Morphology (0) | 2022.11.17 |
[Python] openCV : Filltering (0) | 2022.11.17 |
[Python] openCV : Histogram (0) | 2022.11.10 |