< * 윤곽선(Contour) * >
◆ 영상이나 이미지의 윤곽선(컨투어)을 검출하기 위해 사용한다.
◆ 영상이나 이미지에서 외곽과 내곽의 윤곽선(컨투어)을 검출할 수 있다
----< 예제 : Contour.py >-------------------------------------------------------------------
import cv2
src = cv2.imread("Image/contours.png", cv2.IMREAD_COLOR)
gray = cv2.cvtColor(src, cv2.COLOR_RGB2GRAY)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary = cv2.bitwise_not(binary)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
for i in range(len(contours)):
cv2.drawContours(src, [contours[i]], 0, (0, 0, 255), 2)
cv2.putText(src, str(i), tuple(contours[i][0][0]), cv2.FONT_HERSHEY_COMPLEX, 0.8, (0, 255, 0), 1)
print(i, hierarchy[0][i])
cv2.imshow("src", src)
cv2.waitKey(0)
--------------------------------------------------------------------------------------------------------
▶ gray = cv2.cvtColor(src, cv2.COLOR_RGB2GRAY)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
binary = cv2.bitwise_not(binary)
: 윤곽선(컨투어)를 검출하는 주된 요소는 하얀색의 객체를 검출 한다.
- 배경은 검은색이며 검출하려는 물체는 하얀색의 성질을 띄게끔 변형 한다.
- 이진화 처리 후, 반전시켜 검출하려는 물체를 하얀색의 성질을 띄도록 변환 한다..
▶ contours, hierarchy = cv2.findContours(binary, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
: cv2.findContours()를 이용하여 이진화 이미지에서 윤곽선(컨투어)를 검색 한다.
- cv2.findContours(이진화 이미지, 검색 방법, 근사화 방법)을 의미한다.
- 반환값으로 윤곽선, 계층 구조를 반환한다.
- 윤곽선은 Numpy 구조의 배열로 검출된 윤곽선의 지점들이 담겨있다.
- 계층 구조는 윤곽선의 계층 구조를 의미합니다. 각 윤곽선에 해당하는 속성 정보들이 담겨있다.
_________________________________________
for i in range(len(contours)):
cv2.drawContours(src, [contours[i]], 0, (0, 0, 255), 2)
cv2.putText(src, str(i), tuple(contours[i][0][0]), cv2.FONT_HERSHEY_COMPLEX, 0.8, (0, 255, 0), 1)
print(i, hierarchy[0][i])
cv2.imshow("src", src)
cv2.waitKey(0)
--------------------------------------------------
▶ 반복문을 사용하여 검출된 윤곽선을 그리며 해당 윤곽선의 계층 구조를 표시한다.
▶ cv2.drawContours()을 이용하여 검출된 윤곽선을 그린다.
▶ cv2.drawContours(이미지, [윤곽선], 윤곽선 인덱스, (B, G, R), 두께, 선형 타입)을 의미 한다.
▶ 윤곽선은 검출된 윤곽선들이 저장된 Numpy 배열 이다.
▶ 윤곽선 인덱스는 검출된 윤곽선 배열에서 몇 번째 인덱스의 윤곽선을 그릴지를 의미 한다.
■ 검색 방법
◎ cv2.RETR_EXTERNAL : 외곽 윤곽선만 검출하며, 계층 구조를 구성하지 않는다.
◎ cv2.RETR_LIST : 모든 윤곽선을 검출하며, 계층 구조를 구성하지 않는다.
◎ cv2.RETR_CCOMP : 모든 윤곽선을 검출하며, 계층 구조는 2단계로 구성한다.
◎ cv2.RETR_TREE : 모든 윤곽선을 검출하며, 계층 구조를 모두 형성한다. (Tree 구조)
■ 근사화 방법
◎ cv2.CHAIN_APPROX_NONE : 윤곽점들의 모든 점을 반환한다.
◎ cv2.CHAIN_APPROX_SIMPLE : 윤곽점들 단순화 수평, 수직 및 대각선 요소를 압축하고 끝점만 남겨 둔다.
◎ cv2.CHAIN_APPROX_TC89_L1 : 프리먼 체인 코드에서의 윤곽선으로 적용한다.
◎ cv2.CHAIN_APPROX_TC89_KCOS : 프리먼 체인 코드에서의 윤곽선으로 적용한다.
■ 계층 구조
- 계층 구조는 윤곽선을 포함 관계의 여부를 나타낸다.
- 외곽 윤곽선, 내곽 윤곽선, 같은 계층 구조를 구별할 수 있다.
- 이 정보는 hierarchy에 담겨있다.
- hierarchy를 출력할 경우 다음과 같은 결과를 반환한다.
-----------------------------------
[[[ 2 -1 1 -1]
[-1 -1 -1 0]
[ 4 0 3 -1]
[-1 -1 -1 2]
[ 6 2 5 -1]
[-1 -1 -1 4]
[ 8 4 7 -1]
[-1 -1 -1 6]
[ 9 6 -1 -1]
[10 8 -1 -1]
[11 9 -1 -1]
[-1 10 -1 -1]]]
---------------------------------
첫 번째 계층 구조는 [ 2 -1 1 -1]의 값을 갖는다.
[다음 윤곽선, 이전 윤곽선, 내곽 윤곽선, 외곽 윤곽선]에 대한 인덱스 정보를 포함하고 있다.
인덱스 0의 윤곽선의 다음 윤곽선은 인덱스 2의 윤곽선을 의미하며 이전 윤곽선은 존재하지 않다는 것을 의미한다.
내곽 윤곽선은 인덱스 1에 해당하는 윤곽선을 자식 윤곽선으로 두고 있다는 의미한다.
인덱스 0 윤곽선 내부에 인덱스 1의 윤곽선이 포함되어 있다.
외곽 윤곽선은 -1의 값을 갖고 있으므로 외곽 윤곽선은 존재하지 않는다.