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

12장. Contour Detection 과 객체 분석

cv2.findContours 의 입력과 결과

운동장 둘레에 하얀 선을 긋는 사람을 떠올려 봅시다. 선 긋는 사람은 운동장 가장자리에 서서 한 발짝씩 옮기며 발자국을 남깁니다. 한 바퀴를 돌아 출발점에 오면 일이 끝납니다. 남은 것은 발자국의 좌표 목록입니다. cv2.findContours 가 흰 덩어리마다 이 일을 합니다.

흑백 사진, 이진화, 윤곽선 찾기, 윤곽선 목록의 네 단계 흐름도

그림의 네 단계가 윤곽선을 얻는 순서입니다. 흑백으로 읽고, 물체가 흰색이 되게 이진화하고, cv2.findContours 로 흰 덩어리의 테두리를 따라간 뒤, 물체마다 점 배열 하나씩을 얻습니다. 여기서 운동장이 흰 덩어리, 선 긋는 사람의 발자국이 윤곽선의 점, 한 바퀴 돈 발자국 목록이 윤곽선 하나입니다.

작은 흰 덩어리의 테두리 칸에 담긴 순서대로 번호를 붙인 격자 그림

가로 9칸, 세로 7칸짜리 작은 그림에서 찾은 윤곽선입니다. 다홍 점은 테두리 칸이고, 점 안의 번호가 배열에 담긴 순서입니다. 왼쪽 위 칸(1, 1)에서 출발해 테두리를 한 바퀴 돌고 출발점 옆에서 끝납니다. 점은 흰 덩어리 바깥이 아니라 가장자리의 흰 칸 위에 놓입니다.

인자와 돌려주는 값

구분이름뜻
인자 1image8비트 흑백 그림. 0 이 아닌 칸을 모두 흰색(물체)으로 본다
인자 2mode찾는 방식. cv2.RETR_EXTERNAL, cv2.RETR_LIST, cv2.RETR_TREE 등
인자 3method점을 담는 방식. cv2.CHAIN_APPROX_NONE, cv2.CHAIN_APPROX_SIMPLE
돌려주는 값 1contours윤곽선 목록(튜플). 윤곽선 하나는 (점 수, 1, 2) 모양의 배열
돌려주는 값 2hierarchy계층 구조. (1, 윤곽선 수, 4) 모양의 배열

윤곽선 배열의 모양 (점 수, 1, 2)

윤곽선 하나는 점 수만큼의 줄이 있고, 줄마다 [x, y] 좌표가 들어 있습니다. 가운데의 1 은 OpenCV 가 점 배열을 담는 옛 방식에서 남은 칸이라 늘 1 입니다. 좌표만 보고 싶으면 reshape(-1, 2) 로 (점 수, 2) 모양으로 펼칩니다.

모양의 자리값의 예뜻
첫째4점의 수
둘째1늘 1 (옛 방식의 흔적)
셋째2x 좌표와 y 좌표. 그림의 배열 번호 [y, x] 와 순서가 반대다

짧은 예시

Python
import cv2

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

print("contours 의 자료형:", type(contours).__name__, "/ 길이:", len(contours))
print("hierarchy 의 모양:", hierarchy.shape)
# 가장 마지막 윤곽선(곧은 네모)의 모양과 점 좌표
last = contours[-1]
print("마지막 윤곽선의 모양:", last.shape)
print("점 좌표 [x, y]:", last.reshape(-1, 2).tolist())

교안 PC 에서는 자료형이 tuple, 길이 8, hierarchy 의 모양이 (1, 8, 4) 입니다. 마지막 윤곽선은 (4, 1, 2) 모양이고 점이 [[20, 20], [20, 69], [99, 69], [99, 20]] 입니다. 그림을 그릴 때 네모의 왼쪽 위를 (20, 20), 오른쪽 아래를 (99, 69) 로 칠했으므로 꼭짓점 칸이 그대로 나왔습니다.

주의할 점

  • 입력은 흰 물체, 검은 바탕이어야 합니다. 바탕이 흰 그림을 그대로 넣으면 그림 전체가 덩어리 하나로 잡힙니다.
  • 윤곽선이 담긴 순서는 왼쪽 위부터가 아닙니다. 이 그림에서는 아래쪽 물체가 앞 번호를 받았습니다. 번호를 붙여 보고할 때는 "분석 결과를 표로 정리하기" 절처럼 위치로 다시 정렬합니다.
  • OpenCV 3.x 의 일부 판은 값을 세 개 돌려주었습니다. 이 과정의 OpenCV 5.0 은 두 개(contours, hierarchy)입니다.
← 이전 절12장 · 윤곽선이란다음 절 →12장 · 찾는 방식과 계층 구조