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

12장. Contour Detection 과 객체 분석

점 줄이기: CHAIN_APPROX_NONE 과 SIMPLE

친구에게 공원 산책길을 알려 준다고 해 봅시다. "한 걸음, 한 걸음, 한 걸음…" 하고 걸음마다 알려 줄 수도 있지만, "정문에서 분수대까지 곧장, 거기서 왼쪽으로 벤치까지 곧장"이라고 꺾이는 곳만 알려 줘도 길은 똑같이 전해집니다. 곧은 길에서는 가운데 걸음을 빼도 됩니다.

점을 모두 담는 CHAIN_APPROX_NONE 과 곧은 줄의 양 끝만 남기는 CHAIN_APPROX_SIMPLE 을 견준 비교 그림

초록 상자의 CHAIN_APPROX_NONE 은 테두리의 칸을 하나도 빼지 않고 모두 담습니다. 다홍 상자의 CHAIN_APPROX_SIMPLE 은 가로, 세로, 대각선으로 곧게 이어지는 칸은 양 끝만 남기고 가운데를 뺍니다. 여기서 걸음마다 알려 주기가 NONE, 꺾이는 곳만 알려 주기가 SIMPLE 입니다.

도형 판의 네모와 원에서 NONE 과 SIMPLE 이 담은 점을 다홍 점으로 찍어 견준 그림

왼쪽 NONE 은 네모와 원의 테두리가 다홍 점으로 빽빽합니다. 오른쪽 SIMPLE 은 네모에 꼭짓점 4개만 남았고, 원은 계단처럼 꺾이는 곳마다 점이 남아 절반 남짓으로 줄었습니다.

두 방식 견주기

견줄 것CHAIN_APPROX_NONECHAIN_APPROX_SIMPLE
담는 점테두리 칸 모두곧은 줄의 양 끝
80×50 네모256점4점
반지름 35 원196점100점
면적·둘레같다같다
쓰는 곳테두리 칸 하나하나가 필요할 때대부분(메모리를 아낀다)

짧은 예시

Python
import cv2

shapes = cv2.imread("ch12_shapes.png", cv2.IMREAD_GRAYSCALE)
full, _ = cv2.findContours(shapes, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
short, _ = cv2.findContours(shapes, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print("NONE   전체 점 수:", sum(len(c) for c in full))
print("SIMPLE 전체 점 수:", sum(len(c) for c in short))
# 점을 줄여도 면적은 그대로인지 마지막 윤곽선(네모)으로 확인한다
print("네모의 면적:", cv2.contourArea(full[-1]), "/", cv2.contourArea(short[-1]))

교안 PC 에서는 NONE 이 1,291점, SIMPLE 이 620점으로 절반 아래로 줄었고, 네모의 면적은 두 방식 모두 3871.0 입니다. 빠진 점은 곧은 줄 위에 있던 점이라 점을 이은 도형이 바뀌지 않기 때문입니다.

주의할 점

  • SIMPLE 이 줄이는 것은 가로, 세로, 45도 대각선으로 곧은 줄뿐입니다. 비스듬한 선은 계단 모양이라 점이 많이 남습니다.
  • 꼭짓점 몇 개로 모양을 어림하는 일(다각형 근사, cv2.approxPolyDP)은 SIMPLE 과 다른 일입니다. 13장에서 배웁니다.
← 이전 절12장 · 찾는 방식과 계층 구조다음 절 →12장 · 윤곽선 그리기