C# OpenCV 강좌 : 제 16강 - 윤곽선 검출
윤곽선 검출(Contours Detection)
가장자리 검출(Edge Detection)
함수는 입력 이미지에서 가장자리를 검출해 이미지로 반환했습니다.
하지만, 가장자리 검출 알고리즘은 검출된 객체들의 세그먼트(Segment)
구성 요소가 구분돼 있지 않아 어떤 형태인지 알 수 없었습니다.
윤곽선 검출(Contour Detection)
알고리즘은 전처리가 진행된 이미지에서 가장자리로 검출된 픽셀을 대상으로 세그먼테이션(Segmentation)
작업을 진행합니다.
그러므로, 윤곽선 검출 알고리즘은 검출된 객체들을 값(Value)
으로 반환해 사용할 수 있습니다.
검출된 윤곽선은 형상의 분석과 물체 감지 및 인식에 가장 효과적인 방법 중 하나입니다.
-
Tip :
세그먼트(Segment)
란 서로 다른 두 점을 연결하는 가장 짧은 선을 의미합니다. -
Tip :
세그먼테이션(Segmentation)
이란 이미지에서 각각의 픽셀들을 분류해 그룹화하는 것을 의미합니다.
메인 코드
세부 코드
new Mat
을 사용해 이미지를 src
에 할당합니다.
전처리 결과를 저장할 yellow
를 선언합니다.
연산 결과를 저장할 dst
를 선언합니다.
윤곽선 검출 알고리즘은 윤곽선의 실제 값이 저장될 contours
와 그 윤곽선들의 계층 구조를 저장할 hierarchy
를 선언합니다.
contours
는 Point
형식의 2차원 배열이며, hierarchy
는 HierarchyIndex
형식의 1차원 배열입니다.
contours
의 차원 구조는 점 좌표(x, y)의 묶음과, 그 좌표들을 한 번 더 묶는 구조입니다.
좌표를 저장하기 위해서 Point
형식이며, 좌표들을 하나로 묶어 윤곽선을 구성하기 위해 Point[]
가 됩니다.
이후, 윤곽선은 n
개 이상 발생할 수 있으므로, Point[]
를 묶는 Point[][]
가 됩니다.
hierarchy
에는 현재 노드(Node)
의 정보가 담겨있습니다.
다음 윤곽선, 이전 윤곽선, 자식 노드, 부모 노드가 담겨있습니다.
이 정보를 담기 위해 1차원 배열이 됩니다.
-
Tip :
자식 노드
란 자기 자신 안쪽에 있는 윤곽선을 지칭합니다. -
Tip :
부모 노드
란 자기 자신 바깥쪽에 있는 윤곽선을 지칭합니다.
연산량을 줄이고 정확성을 높이기 위해 간단한 전처리(배열 요소의 범위 설정 함수)
를 적용합니다.
윤곽선 검출 함수(Cv2.FindContours)
는 객체의 구조를 판단하는 데 가장 많이 사용되는 알고리즘입니다.
Cv2.FindContours(원본 배열, 검출된 윤곽선, 계층 구조, 검색 방법, 근사 방법, 오프셋)
로 윤곽선 검출을 적용합니다.
검출된 윤곽선
은 out 키워드를 활용해 함수에서 검출된 윤곽선을 저장합니다.
계층 구조
는 out 키워드를 활용해 함수에서 검출된 계층구조를 저장합니다.
검색 방법
은 윤곽선을 검출해 어떤 계층 구조의 형태를 사용할지 설정합니다.
근사 방법
은 윤곽점의 근사법을 설정합니다. 근사 방법에 따라 검출된 윤곽선(contours)에 포함될 좌표의 수나 정교함의 수준이 달라집니다.
오프셋
은 반환된 윤곽점들의 좌푯값에 이동할 값을 설정합니다. 일반적으로 잘 사용하지 않습니다.
간단하게 불필요한 윤곽선을 제거하기 위해, List
형식의 Point[]
배열을 선언합니다.
List
를 사용하기 위해 네임스페이스에 using System.Collections.Generic;
를 추가합니다.
new_contours
변수에 일정 조건 이상의 윤곽선만 포함시키도록 하겠습니다.
반복문(foreach)
를 활용해 검출된 윤곽선(contours)
의 값을 검사합니다.
윤곽선 길이 함수(Cv2.ArcLength)
를 활용해 length가 100 이상의 값만 new_contours
에 추가합니다.
불필요한 윤곽선이 제거된 새로운 윤곽선 배열을 그립니다.
윤곽선 그리기 함수(Cv2.DrawContours)
는 윤곽선을 간단하게 그려볼 수 있습니다.
Cv2.FindContours(결과 배열, 검출된 윤곽선, 윤곽선 번호, 색상, 두께, 선형 타입, 계층 구조, 계층 구조 최대 레벨)
로 윤곽선 검출을 적용합니다.
윤곽선 번호
는 지정된 윤곽선만 그릴 수 있습니다. 윤곽선 번호의 값을 -1로 사용할 경우, 모든 윤곽선을 그립니다.
계층 구조
는 윤곽선 검출 함수에서 반환된 계층 구조를 의미합니다.
계층 구조 최대 레벨
은 그려질 계층 구조의 깊이를 설정합니다. 계층 구조 최대 레벨을 0
으로 설정할 경우 최상위 레벨만 그려집니다.
현재 새로운 윤곽선을 구성하였으므로, 계층 구조가 맞지 않으니 계층 구조
를 null로 사용합니다.
계층 구조가 존재하지 않으므로 계층 구조 최대 레벨
을 0의 이상의 값으로 사용합니다.
만약, 기본 윤곽선을 사용한다면 다음과 같이 그릴 수 있습니다.
새로운 윤곽선을 저장할 때, HierarchyIndex
도 새롭게 저장한다면, 위의 구조와 동일하게 구현이 가능합니다.
검색 방법 플래그 종류
속성 | 의미 |
---|---|
RetrievalModes.External | 최외곽 윤곽선만 검색 |
RetrievalModes.List | 모든 윤곽선을 검출하며, 계층 구조를 형성하지 않음(모든 윤곽선을 동일 레벨로 간주) |
RetrievalModes.CComp | 모든 윤곽선을 검색해서 2단계 계층 구조로 구성(최상위 레벨은 외곽, 두 번째 레벨은 내곽(홀)) |
RetrievalModes.Tree | 모든 윤곽선을 검출하고 트리 구조로 구성 |
근사 방법 플래그 종류
속성 | 의미 |
---|---|
ContourApproximationModes.ApproxNone | 검출된 모든 윤곽점을 반환 |
ContourApproximationModes.ApproxSimple | 수평, 수직, 대각선 부분을 압축해서 끝점만 반환 |
ContourApproximationModes.ApproxTC89L1 | Teh-Chin 체인 근사 알고리즘을 적용 |
ContourApproximationModes.ApproxTC89KCOS | Teh-Chin 체인 근사 알고리즘을 적용 |
댓글 남기기