우선 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의 그림 결과를 비교해 놓은 것이 있으니, 참조바란다)
'딥러닝(Deep Learning) > 컴퓨터 비전' 카테고리의 다른 글
k-mean Clustering(feat. 군집화) (1) | 2024.01.08 |
---|---|
허프 변환(Hough Transformation)(Feat. 컴퓨터 비전과 딥러닝 p131) (1) | 2024.01.04 |
cv.RETR_LIST(Feat. 컴퓨터 비전과 딥러닝 P128) (2) | 2024.01.04 |
캐니 에지(Canny Edge)(feat. false positive) (2) | 2024.01.02 |
물체 인식(Object Recongnition) vs 의미 분할(Semantic Segmentation) (0) | 2023.12.31 |