레이블 맵 : 객체 고유의 번호가 매겨진 2차원 정수 행렬
0번 레이블 = 배경
cnt, labels = connectedComponents(src, connectivity = 8)
cnt, labels, stats, centroids = connectedComponentsWithStats(src, connectivity = 8)
stats : 각각의 레이블 영역에 대한 통계 정보
centroids : 각각의 레이블 영역의 무게 중심 좌표 정보
→ x좌표(y좌표) 모두 더한 후 픽셀 개수로 나눈 값
_, src_bin = cv2.threshold(src, 0, 255, cv2.THRESH_BINARY | 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
pt1 = (x, y)
pt2 = (x + w, y + h)
cv2.rectangle(dst, pt1, pt2, (0, 255, 255))
mode : 외곽선 검출 모드 RetrievalModes
RETR_EXTERNAL : 객체 바깥쪽 외곽선만, 계층 구조 X
RETR_LIST : 모두, 계층 구조 X
RETR_CCOMP : 모두, 2단계 계층 구조
→ 상위 외부외곽선, 하위 내부내곽선
RETR_TREE : 모두, 전체 계층 구조
계층 구조 : 감지된 객체들 간의 관계 나타내는 방법
method : 외곽선 근사화 방법 ContourApproximationModes
- CHAIN_APPROX_NONE : 모든 외곽선 점들의 좌표
- CHAIN_APPROX_SIMPLE : 외곽선 중 수평선, 수직선, 대각선 성분은 끝점만 저장
- CHAIN_APPROX_TC89_L1 : Teh & Chin L1 근사화 적용
- CHAIN_APPROX_TC89_KCOS : Teh & Chin k cos 근사화 적용
drawContours(src, contours, contourIdx, color, thickness=1, lineType=LINE_8, hierarchy, maxLevel = INT_MAX)
contours, _ = cv2.findContours(src_bin, cv2.RETR_LIST,
cv2.CHAIN_APPROX_NONE)
dst = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)
for i in range(len(contours)):
# len(contours) : 전체 외곽선 개수
c = (random.randint(0, 255), random.randint(0, 255),
random.randint(0, 255))
cv2.drawContours(dst, contours, i, c, 2)
_, src_bin = cv2.threshold(src, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(src_bin, cv2.RETR_CCOMP,
cv2.CHAIN_APPROX_SIMPLE)
dst = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)
idx = 0
while idx >= 0:
c = (random.randint(0, 255), random.randint(0, 255),
random.randint(0, 255))
cv2.drawContours(dst, contours, idx, c,
-1, cv2.LINE_8, hierarchy)
idx = hierarchy[0, idx, 0]
_, src_bin = cv2.threshold(src, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours, _ = cv2.findContours(src_bin, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
for pts in contours:
if cv2.contourArea(pts) < 400:
continue
approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True) * 0.02, True)
vtc = len(approx) # 꼭지점 개수
if vtc == 3:
setLabel(src, pts, 'TRI')
elif vtc == 4:
setLabel(src, pts, 'RECT')
else:
lenth = cv2.arcLength(pts, True)
area = cv2.contourArea(pts)
ratio = 4. * math.pi * area / (lenth * lenth)
if ratio > 0.05:
setLabel(src, pts, 'CIR')