조금씩 꾸준히 완성을 향해

[OpenCV/Python] Labeling(라벨링) - connectedComponents, connectedComponentsWithStats 본문

Python/OpenCV

[OpenCV/Python] Labeling(라벨링) - connectedComponents, connectedComponentsWithStats

all_sound 2022. 11. 15. 09:11

Labeling

  • 배경과 객체를 구분 한 후 레이블링을 이용하여 객체 간 구분
  • 연결 구성 요소 레이블링 (CCL, Connected Component Labeling)
    • 객체 인식을 위한 전처리 과정으로 사용
    • 이진화 영상에서 수행(배경:검은색, 객체:흰색)
    • 연결성 정의에 따라 결과가 달라질 수 있음

# 고전적 레이블링 기법

  • 등가 테이블(Equibalent Table)을 만들면서 영상을 두 번 스캔함으로써 레이블링을 수행
  • 첫번째 스캔에서는 레이블을 전파시키면서 등가 테이블 생성
  • 두번째 스캔에서는 등가 테이블을 참조하여 각 픽셀에 고유의 레이블을 부여
  • 4-이웃 연결성 고려
출처 : https://www.charlezz.com/?p=45334

 

  • cv2.connectedComponents : 연결된 compoenets의 개수를 반환하고 labeling을 해준다.
  • cv2.connectedComponentsWithStats : + 중심 자표 및 범위를 알려주기 때문에 Component를 특정화 시킬 수 있다.
 
출처 : https://www.charlezz.com/?p=45334
 
 

# circle 객체 labeling 실습

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
 
src = cv2.imread('./circles.jpg') #원본을 컬러로 가져오기
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) #gray로 변경
ret, dst = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY_INV) #binary_inverse
# 배경이 흰색, circle이 검은색 -> circle 객체 추출 불가 -> 검흰 바꿔 circle을 흰색으로 세팅

# 결과 확인
cv2.imshow('src', src) 
cv2.imshow('dst', dst) 
cv2.waitKey() 
cv2.destroyAllWindows()
 
 
 
  • connectedComponents
ret, labels = cv2.connectedComponents(dst)
print('ret=', ret)
print('label:', np.unique(labels))

labels = cv2.normalize(labels, 0, 255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
print('norm labels:', np.unique(labels))
cv2.imshow('labels', labels)
cv2.waitKey() 
cv2.destroyAllWindows()

# ret= 4
# label: [0 1 2 3]
# norm labels: [  0  85 170 255]

 

  • connectedComponentsWithStats
cnt, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)
print('ret=', ret)
print('label:', np.unique(labels))
print('stats=', stats) #stats = x, y, weidth, height, area
print('centroids=', centroids)
 
dst = src.copy()

# 배경에 대한 labeling
cv2.circle(dst, (int(centroids[0][0]), int(centroids[0][1])), radius=5, color=(255,0,0), thickness=-1)
cv2.rectangle(dst, (stats[0][0], stats[0][1]), (stats[0][0]+stats[0][2], stats[0][1]+stats[0][3]), [255,0,0], 5)

# circles에 대한 labeling
for i in range(1, 4):
    cv2.circle(dst, (int(centroids[i][0]), int(centroids[i][1])), radius=3, color=(0,0,255), thickness=-1)
    cv2.rectangle(dst, (stats[i][0], stats[i][1]), (stats[i][0]+stats[i][2], stats[i][1]+stats[i][3]), [0,0,255])
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(dst, f'label={i}', (stats[i][0], stats[i][1]), font, 0.5, (255, 0, 0), 1)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()