1. 레이블링
- 이진화, 모폴로지를 수행하면 객체와 배경 영역을 구분할 수 있게됨
- 객체 단위 분석을 통해 각 객체를 분할하여 특징을 분석하고 객체의 위치, 크기 정보, 모양 분석, ROI 추출등이 가능함
- 서로 연결되어 이쓴 객체 픽셀에 고유번호를 할당하여 영역 기반 모양분석, 레이블맵, 바운딩 박스 픽셀 개수, 무게 중심, 좌표 등을 반환할 수 있게 함
◼ 레이블링
cv2.connectedComponents(영상, 레이블맵) 레이블맵: 픽셀 연결 관계(4방향 연결, 8방향 연결) return: 객체 객수, 레이블 맵 행렬 |
◼ 예제: 문자 잡아내기
import cv2
img = cv2.imread('./keyboard.bmp', cv2.IMREAD_GRAYSCALE)
# 이진화(thresholding) 처리
# cv2.threshold() 함수를 사용하여 Otsu의 이진화 방법으로 이진 이미지를 생성합니다.
_, img_bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 회색조 이미지를 BGRA 포맷으로 변환
# 이 단계는 나중에 각 성분을 다른 색상으로 표시하기 위해 수행됩니다.
dst = cv2.cvtColor(img, cv2.COLOR_GRAY2BGRA)
# 연결된 성분 분석
# cv2.connectedComponentsWithStats() 함수는 이진 이미지에서 연결된 성분을 분석하여
# 그 개수(cnt), 레이블(labels), 통계(stats), 중심점(centroids)을 반환합니다.
cnt, labels, stats, centroids = cv2.connectedComponentsWithStats(img_bin)
print(cnt)
print(labels)
print(stats)
print(centroids)
# 면적이 30보다 작은 성분은 무시
for i in range(1, cnt):
(x, y, w, h, area) = stats[i]
if area < 30:
continue
# 성분을 둘러싸는 사각형 그리기 (색상: 노란색, 두께: 1픽셀)
cv2.rectangle(dst, (x,y,w,h),(0, 255,255))
cv2.imshow('img', img)
cv2.imshow('img_bin', img_bin)
cv2.imshow('dst', dst)
cv2.waitKey()
|
![]() ![]() ![]() ![]() |
2. 객체의 외곽선 검출
◼ 객체의 외곽선 검출
cv2.findContours(영상, 검출모드, 외각선 죄표 근사화 방법) * 검출모드 RETR_EXRETNAL: 객체 외부 외곽선만 검출 RETR_LIST : 객체 외부, 내부 외곽선 모두 검출 RETR_CCOMP : 모든 외곽선 검출, 2단계 계층 구조를 구성 RETR_TREE : 모든 외곽선 검출, 전체 계층 구조를 구선 |
- 레이블링과 함께 영상에서 객체의 정보를 검출하는 방법중 하나 - 이진화 된 영상에서 검출되며, 배경 영역과 닿아 있는 픽셀을 찾아 외곽선으로 인식 - 외곽선은 객체 외부 뿐 아니라 내부에서도 생길 수 있음 |
◼ 외곽선 좌표 근사화 방법
cv2.drawContours(영상, 외곽선 좌표 정보, 외곽선 인덱스, 색상, 두께) 외곽선 인덱스: -1을 지정하면 모든 외곽선을 그림 |
외곽선 점들의 저장 방식과 정확도를 정의 |
◼ 외곽선 길이 구하기
cv2.arcLength(외곽선 좌표, 페곡선 여부) |
◼ 면적 구하기
cv2.contourArea(외곽선 좌표, False) |
◼ 바운딩 박스 구하기
cv2.boundingRect(외곽선 좌표) |
◼ 예제: 외곽선을 찾고, 무작위 색상으로 외곽선을 그리기
import cv2
import random
img = cv2.imread('./contours.bmp', cv2.IMREAD_GRAYSCALE)
# 외곽선 찾기
# cv2.findContours() 함수는 이진화된 이미지에서 외곽선을 찾아 반환합니다.
# cv2.RETR_CCOMP: 외곽선을 계층 구조로 반환합니다.
# cv2.CHAIN_APPROX_NONE: 모든 외곽선 점을 반환합니다.
contours, _ = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
# 회색조 이미지를 BGR 포맷으로 변환
dst = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
# 무작위 색상 생성
# random.randint() 함수를 사용하여 0부터 255 사이의 임의의 값을 생성하여 색상을 만듭니다.
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
# 외곽선 그리기
# cv2.drawContours() 함수는 외곽선을 그립니다.
# dst: 외곽선을 그릴 이미지.
# contours: 외곽선 정보.
# -1: 모든 외곽선을 그립니다.
# color: 외곽선을 그릴 색상.
# 3: 외곽선의 두께.
cv2.drawContours(dst, contours, -1, color, 3)
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey()
|
![]() |
◼ 예제: 이진화 후, 외곽선을 검출하여 외곽선을 표기하기
# milkdrop.bmp 영상을 이용하여 이진화를 시키고, 외곽선을 검출하여 외곽선을 랜덤한 색상으로 표기
import numpy as np
img = cv2.imread('./milkdrop.bmp', cv2.IMREAD_GRAYSCALE)
_, img_bin = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours, _ = cv2.findContours(img_bin, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
h, w = img.shape[:2]
dst = np.zeros((h, w, 3), np.uint8)
for i in range(len(contours)):
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
cv2.drawContours(dst, contours, i, color, 2)
cv2.imshow('img', img)
cv2.imshow('img_bin', img_bin)
cv2.imshow('dst', dst)
cv2.waitKey()
|
3. 외곽선의 근사화
검출한 외곽선 정보를 분석하여 정점수가 적은 외곽선 또는 다각형으로 표현할 수 있게 만드는 것
◼ 외곽선 근사화
cv2.drawContours(영상, 외곽선 좌표 정보, 외곽건 인덱스, 색상, 두께) 외곽선 인덱스: -1을 지정하면 모든 외곽선을 그림 |
근사화 정밀도 조절: 입력 외곽선과 근사화된 외곽선 사이의 최대거리, 값이 작을수록 다각형이 정확해지고, 꼭지점 수가 늘어남 |
◼ 블록부분이 있는지 여부
cv2.arcLength(외곽선 좌표, 페곡선 여부) |
contour에 오목한 부분이 있는지 체크(있으면 true, 없으면 False) |
◼ 블록외피를 계산
cv2.contourArea(외곽선 좌표, False) |
contour에 있는 오복한 부분을 제거 |
◼ 예제: 다각형의 종류를 식별해서 표기하기
import cv2
import math
def setLevel(img, pts, label):
"""
주어진 다각형의 바운딩 박스를 그린 후 레이블을 추가하는 함수.
img: 원본 이미지.
pts: 다각형의 외곽선 좌표.
label: 다각형의 레이블 (TRI, RECT, CIR, NONAME).
"""
# 다각형의 바운딩 박스 계산
(x, y, w, h) = cv2.boundingRect(pts)
pt1 = (x, y)
pt2 = (x + w, y + h)
# 바운딩 박스 그리기
cv2.rectangle(img, pt1, pt2, (0, 0, 255), 2)
# 레이블 추가
cv2.putText(img, label, pt1, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255))
img = cv2.imread('./polygon.bmp')
gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
# 이진화 처리 (배경은 흰색, 다각형은 검은색으로 반전)
_, img_bin = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
# 외곽선 찾기 (가장 바깥쪽 외곽선만 찾음)
contours, _ = cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# 각 외곽선에 대해 반복
for pts in contours:
# 작은 영역은 무시
if cv2.contourArea(pts) < 200:
continue
# 외곽선을 근사화하여 꼭짓점 개수 계산
approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True) * 0.02, True)
vtc = len(approx)
# 다각형의 종류에 따라 레이블 지정
if vtc == 3:
setLevel(img, pts, 'TRI')
elif vtc == 4:
setLevel(img, pts, 'RECT')
else:
# 원인지 확인 (형상 비율 계산)
length = cv2.arcLength(pts, True)
area = cv2.contourArea(pts)
ratio = 4. * math.pi * area / (length * length)
if ratio > 0.70:
setLevel(img, pts, 'CIR')
else:
setLevel(img, pts, 'NONAME')
cv2.imshow('img', img)
cv2.waitKey()
|
![]() - cv2.THRESH_BINARY: 도형이 검정색 ![]() - cv2.THRESH_BINARY_INV: 도형이 흰색 ![]() |
'AI > 컴퓨터 비전' 카테고리의 다른 글
12. VGG19 | 분류 (1) | 2024.07.24 |
---|---|
11. OCR (1) | 2024.07.23 |
09. 모폴로지 변환 (0) | 2024.07.23 |
08. 필터링, 블러링 (0) | 2024.07.22 |
07. 이미지 유사도, 영상의 변환 (0) | 2024.07.18 |