본문 바로가기

딥러닝(Deep Learning)/컴퓨터 비전

cv2.findContours() (Feat. 컴퓨터 비전과 딥러닝, P129)

우선 cv2.findContours()의 반환형 중 하나인 contour의 내부 정보에 대한 분석을 먼저 해보자!

contour.shape

contours 객체는 등고선 좌표를 담고 있는 리스트입니다.

각 등고선은 각각의 좌표들을 포함하는 리스트로 표현됩니다.

contours.shape 속성의 첫 번째 값(contours.shape[0])은 등고선의 개수이고,

두 번째 값(countours.shape[1])은 각 등고선에 포함된 좌표의 수

세 번째 값(contours.shape[2])은 좌표가 차원 정보이다.

이 코드에서 contours.shape(n, m, 2) 형태의 튜플이다.( 맨 마지막의 2는 contour를 이루는 좌표가 2차원 좌표라는 뜻)

예를 들어, 만약 contours에 두 개의 등고선(Edge)이 있고,

각각의 등고선이 10개의 좌표를 갖는다면, contours.shape(2, 10, 2)가 됩니다.

 

import cv2

# 이미지 읽기
image = cv2.imread('example_image.jpg', cv2.IMREAD_GRAYSCALE)

# 등고선 찾기
contours, _ = cv2.findContours(image, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)

# contours의 shape 출력
print("contours.shape:", contours.shape)

 

contour[idx].shape

contours[idx].shape는 특정 등고선(인덱스 idx에 해당하는 등고선)의 좌표 정보를 담고 있는 배열의 모양을 나타냅니다.

이 배열은 해당 등고선의 모든 좌표를 2D 형태로 표현합니다.

예를 들어, 만약 contours 리스트에서 세 번째 등고선(인덱스 2)이 있고, 해당 등고선이 15개의 좌표를 가진다면,

contours[2].shape는 (15, 1, 2) 형태의 튜플이 될 것입니다.

여기서 15는 해당 등고선의 좌표 개수(contours[2].shape[0]),

1은 각 좌표가 2차원(contours[2].shape[1])이라는 것을 나타냅니다.

이것은 등고선이 포함하는 좌표들의 구조를 나타내며, 각 좌표가 2차원인 이유는 이미지에서의 좌표가 (x, y) 형태로 2차원

으로 표현되기 때문입니다.

 

자, 그럼 이제 본론으로 들어가보자

p129의 contour[i].shape[0]이 왜 Edge의 길이라고 정의를 하는 것일까?

결론부터 말을 하자면, findContours()의 세번째 인자인 cv.CHAIN_APPROX_NONE 때문이다.

Canny 알고리즘에 의해서 p128과 같은 Edge Map이 만들어 지고, Edge에 해당 하는 픽셀을

cv.CHAIN_APPROX_SIMPLE과 같은 근사값을 이용하여 일부의 Edge 픽셀만으로 Edge를 검출하는 것이 아니라

Edge 픽셀에 해당하는 모든 픽셀을 출력함으로써, 직선으로 그려지는 것이다. 

(https://jbluke.tistory.com/519, 이 사이트에 cv.CHAIN_APPROX_NONE의 그림 결과와 cv.CHAIN_APPROX_SIMPLE의 그림 결과를 비교해 놓은 것이 있으니, 참조바란다)