컨투어(contour)는 지도 상에서 같은 값을 가지는 점을 선으로 이은 등치선을 말하는데 이미지 처리에서는 외곽선 검출을 의미합니다. 검은색 배경 안에 있는 흰색 객체 영역에서 가장 외곽 픽셀을 찾아 외곽선으로 이어주면 이미지에서 모양을 쉽게 인식할 수 있습니다.
findContours
함수를 이용하여 흑백 이미지 또는 이진화 이미지에서 내부 객체의 외곽선을 찾아낼 수 있으며 이미지의 컨투어 정보, 컨투어의 상하구조(hierachy) 정보를 출력합니다.
images, contours, hierachy = cv2.findContours(image, mode, method)
- image: 흑백이미지 또는 이진화된 이미지
- mode : 외곽선 검출 모드
- method : 외곽선 근사화 방법
mode : 외곽선 검출 모드
RetrievalModes | 설명 |
---|---|
cv2.RETR_EXTERNAL | 가장 바깥쪽의 외곽선만 검색. 상하구조(hierachy) 미생성 |
cv2.RETR_LIST | 모든 컨투어(외곽/내곽) 라인 검색. 상하구조(hierachy) 미생성 |
cv2.RETR_CCOMP | 모든 컨투어 라인 검색. 2단계 상하 구조 구성 |
cv2.RETR_TREE | 모든 컨투어 라인 검색. 모든 상하 구조 구성 |
method : 외곽선 근사화 방법
ContourApproximationModes | 설명 |
---|---|
cv2.CHAIN_APPROX_NONE | 모든 외곽선 포인트(좌표) 반환 |
cv2.CHAIN_APPROX_SIMPLE | 외곽선 중 수평선/수직선/대각선 성분의 끝점만 저장. 라인 그릴 수 있는 포인트 반환 |
cv2.CHAIN_APPROX_TC89_L1 | Teh & Chin L1 근사화 적용. 컨투어 포인트 줄여줌 |
cv2.CHAIN_APPROX_TC89_KCOS | Teh & Chin KCOS 근사화 적용. 컨투어 포인트 줄여줌 |
drawContours
함수를 이용하여 검출한 외곽선 정보 바탕으로 이미지 위에 외곽선을 그릴 수 있습니다.
drawContours(image, contours, contourIdx, color)
- image: 원본 이미지
- contours: 컨투어 라인 정보
- contourIdx: 컨투어 라인 번호
- color: 색상
import cv2
import matplotlib.pyplot as plt
import numpy as np
image = cv2.imread('./images/callme.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
gray = cv2.threshold(gray, 75, 210, cv2.THRESH_BINARY+cv2.THRESH_OTSU )[1]
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
img = gray.copy()
contours, hierachy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
for contour in contours:
contour_image = cv2.drawContours(img, contour, -1, (255, 0, 0), 2)
images = [image, contour_image]
title = ['image' ,'contour']
plt.figure(figsize=(16, 10))
for i in range(2):
plt.subplot(1, 2, i+1)
plt.imshow(images[i], cmap='gray')
plt.title(title[i])
plt.xticks([]), plt.yticks([])
plt.show()
[출력]
boundingRect
함수를 이용하여 검출한 외곽선 점을 감싸는 가장 작은 크기의 사각형(바운딩 박스)를 구할 수 있습니다.
cv2.boundingRect(array)
- array: 외곽선 좌표. numpy.ndarray. shape=(K, 1, 2)
- retval: 사각형 정보. (x, y, w, h) 튜플.
approxPolyDP
함수를 이용하여 주어진 곡선의 형태를 단순화하여 적은 수의 점으로 구성된 곡선을 생성합니다.
cv2.approxPolyDP(curve, epsilon, closed, approxCurve=None)
- curve: 입력 곡선 좌표. numpy.ndarray. shape=(K, 1, 2)
- epsilon: 근사화 정밀도 조절. 입력 곡선과 근사화 곡선 간의 최대 거리
- closed: True를 전달하면 폐곡선으로 인식
- approxCurve: 근사화된 곡선 좌표. numpy.ndarray. shape=(K', 1, 2)
arcLength
함수를 이용하여 입력 곡선의 길이를 계산하며, 두번째 인자 closed 값이 True 이면, 시작점과 끝점이 이어져 있는 폐곡선이라고 간주하고 계산합니다.
cv2.arcLength(curve, closed)
- curve: 외곽선 좌표. numpy.ndarray. shape=(K, 1, 2)
- closed: True이면 폐곡선으로 간주
countArea
함수를 이용하여 외곽선이 감싸는 영역의 면적을 계산합니다.
cv2.contourArea(contour, oriented=None)
- contour: 외곽선 좌표. numpy.ndarray. shape=(K, 1, 2)
- oriented: True이면 외곽선 진행 방향에 따라 부호 있는 면적을 반환. 기본값은 False.