OpenCV 비전 실무12장 · Contour Detection 과 객체 분석7 / 21← 이전목차다음 →MetaContents

12장. Contour Detection 과 객체 분석

윤곽선 그리기

색칠 공부 책의 테두리를 색연필로 덧그린다고 해 봅시다. 먼저 어떤 그림 위에 그릴지 고르고, 덧그릴 테두리를 고르고, 색연필의 색과 굵기를 고릅니다. 테두리 안을 꽉 칠할 수도 있습니다. cv2.drawContours 가 받는 인자도 이 순서입니다.

컬러로 바꾸기, 번호 고르기, 두께 정하기를 나란히 놓은 비교 그림

초록 상자처럼 흑백 그림에 색을 칠하려면 먼저 cv2.COLOR_GRAY2BGR 로 채널 세 개짜리 그림을 만듭니다. 다홍 상자의 번호는 -1 이면 모든 윤곽선을, 0, 1, 2 처럼 주면 그 번호 하나만 그립니다. 보라 상자의 두께는 선의 굵기이고, -1 을 주면 안을 채웁니다. 여기서 도화지가 그림, 덧그릴 테두리가 번호, 색연필이 색과 두께입니다.

번호 -1 두께 2, 번호 7 두께 2, 번호 -1 두께 -1 로 그린 세 그림을 나란히 놓은 그림

왼쪽은 모든 윤곽선을 빨간 선으로, 가운데는 7번(곧은 네모) 하나만, 오른쪽은 모든 윤곽선의 안을 초록으로 채웠습니다. 오른쪽에서 도넛의 구멍까지 채워진 것은 EXTERNAL 로 바깥 윤곽선만 찾았기 때문입니다.

인자 다섯 개

순서이름예뜻
1imagecanvas그릴 그림. 이 그림이 바로 바뀐다
2contourscontours윤곽선 목록. 하나만 그릴 때도 목록째 준다
3contourIdx-1그릴 번호. -1 이면 모두
4color(0, 0, 255)색. B, G, R 순서라 빨강
5thickness2선 두께. -1 이면 안을 채운다

짧은 예시

Python
import cv2

shapes = cv2.imread("ch12_shapes.png", cv2.IMREAD_GRAYSCALE)
contours, _ = cv2.findContours(shapes, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# GRAY2BGR: 흑백(1채널)을 같은 밝기의 컬러(3채널)로 바꾼다. 색을 칠하려면 필요하다
canvas = cv2.cvtColor(shapes, cv2.COLOR_GRAY2BGR)
cv2.drawContours(canvas, contours, -1, (0, 0, 255), 2)    # 모두, 빨강, 두께 2
print("그린 그림의 모양:", canvas.shape)

# 채운 판으로 바꾸면 윤곽선이 둘러싼 칸이 모두 255 인 마스크가 된다
mask = cv2.drawContours(shapes * 0, contours, -1, 255, -1)
print("채운 칸 수:", int((mask > 0).sum()), "/ 원래 흰 칸 수:", int((shapes > 0).sum()))

교안 PC 에서는 모양이 (240, 320, 3) 이고, 채운 칸이 21,861개, 원래 흰 칸이 20,604개입니다. 차이 1,257칸은 도넛의 구멍(반지름 20, 3.14 × 20 × 20 = 1,256)입니다. 바깥 윤곽선의 안을 채우면 구멍도 메워지기 때문입니다.

주의할 점

  • cv2.drawContours 는 넣은 그림을 바로 고칩니다. 원본을 남기려면 .copy() 나 cvtColor 로 만든 새 그림에 그립니다.
  • 윤곽선 하나만 그릴 때 cv2.drawContours(img, contours[3], ...) 처럼 배열 하나를 넣으면 점마다 윤곽선으로 보아 점만 찍힙니다. contours 와 번호 3을 주거나 [contours[3]] 처럼 목록에 넣어 줍니다.
← 이전 절12장 · 점 줄이기: CHAIN_APPROX_NONE 과 SIMPLE다음 절 →12장 · 면적과 둘레