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

12장. Contour Detection 과 객체 분석

면적과 둘레

울타리를 치고 그 안에 잔디를 까는 일을 떠올려 봅시다. 울타리가 몇 미터인지는 둘레이고, 잔디가 몇 장 드는지는 넓이입니다. 같은 윤곽선에서 이 두 가지를 잽니다. 넓이는 cv2.contourArea, 둘레는 cv2.arcLength 입니다.

contourArea 와 arcLength 두 함수를 나란히 놓은 비교 그림

초록 상자의 cv2.contourArea 는 윤곽선의 점을 이어 만든 도형의 넓이를 칸의 넓이 단위로 돌려줍니다. 다홍 상자의 cv2.arcLength 는 점을 이은 선의 길이를 칸 단위로 돌려줍니다. 여기서 울타리가 윤곽선, 울타리 길이가 둘레, 잔디 장수가 면적입니다.

가로 4칸 세로 3칸의 흰 덩어리 위에 윤곽선 점과 그 점이 감싼 넓이를 보라로 칠한 격자 그림

가로 4칸, 세로 3칸의 흰 덩어리는 흰 칸이 12개입니다. 그런데 윤곽선의 점(다홍)은 테두리 칸의 가운데에 놓이므로, 점을 이은 도형(보라)은 가로 3, 세로 2 로 넓이가 6 입니다. 칸의 바깥쪽 절반씩이 넓이에서 빠집니다. 비유와 다른 점은 이것입니다. 울타리는 잔디 바깥에 치지만, 윤곽선은 잔디의 가장자리 칸 한가운데를 지나갑니다.

손으로 계산해 보기

도형 판의 곧은 네모는 가로 80칸, 세로 50칸으로 칠했고, 원은 반지름 35 로 칠했습니다.

도형흰 칸의 수손계산contourAreaarcLength
네모 80×5080 × 50 = 4,000점 사이는 79 × 49 = 3,8713871.02 × (79 + 49) = 256
원 반지름 353,8533.14 × 35 × 35 = 3,846.53754.02 × 3.14 × 35 = 219.8 보다 길게 230.8

네모의 contourArea 는 점 사이의 거리(79, 49)로 계산한 3,871 과 꼭 같습니다. 원은 흰 칸이 3,853 개로 πr²(3,848.5)와 거의 같지만, contourArea 는 가장자리 칸의 바깥 절반이 빠져 3,754 로 조금 작습니다. 둘레는 원의 테두리가 계단 모양이라 대각선 걸음이 섞여 손계산보다 조금 길게 나옵니다.

짧은 예시

Python
import cv2

shapes = cv2.imread("ch12_shapes.png", cv2.IMREAD_GRAYSCALE)
contours, _ = cv2.findContours(shapes, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
rect = contours[-1]                                   # 곧은 네모(그린 차례에서 마지막)
# contourArea: 점을 이은 도형의 넓이
print("네모 면적:", cv2.contourArea(rect))
# arcLength(윤곽선, closed): True 면 마지막 점과 첫 점을 이어 닫힌 둘레를 잰다
print("닫힌 둘레:", cv2.arcLength(rect, True))
print("열린 길이:", cv2.arcLength(rect, False))

교안 PC 에서는 면적 3871.0, 닫힌 둘레 256.0, 열린 길이 177.0 입니다. 열린 길이는 마지막 점 (99, 20) 에서 첫 점 (20, 20) 으로 돌아오는 한 변(79)을 빼고 49 + 79 + 49 만 잽니다. 윤곽선의 둘레를 잴 때는 늘 True 를 줍니다.

주의할 점

  • 크기가 작은 덩어리일수록 contourArea 와 흰 칸 수의 차이가 커집니다. 반지름 2 짜리 점은 흰 칸 13개인데 contourArea 는 8 입니다. 아주 작은 물체를 견줄 때는 흰 칸 수를 쓰는 "개수 세기와 잡티 걸러 내기" 절의 방법도 함께 봅니다.
  • 면적과 둘레의 단위는 칸입니다. 실제 크기(mm)로 바꾸려면 자처럼 크기를 아는 물체를 함께 찍어 "한 칸이 몇 mm" 인지 알아야 합니다.
  • RETR_EXTERNAL 로 찾은 도넛의 면적에는 구멍이 들어 있습니다. 구멍을 뺀 넓이는 TREE 로 구멍의 윤곽선을 찾아 그 면적을 빼서 구합니다(실습 2).
← 이전 절12장 · 윤곽선 그리기다음 절 →12장 · 무게중심과 모멘트