Processor

【OpenCV】 윤곽선(Contour)

작성자 임베디드코리아 작성일26-04-16 21:54 조회86회 댓글0건
< *  윤곽선(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의 값을 갖고 있으므로 외곽 윤곽선은 존재하지 않는다.