객체의 외곽선은 객체 영역 픽셀 중에서 배경 영역과 인접한 일련의 픽셀을 의미한다. 보통 검은색 배경 안에 있는 흰색 객체 영역에서 가장 최외곽에 있는 픽셀을 찾아 외곽선으로 정의한다. 만약 흰색 객체 영역 안에 검은색 배경영역인 홀이 존재하면 홀을 둘러싼 객체 픽셀 들도 외곽선으로 검출한다.
객체 하나의 외곽선 정보는 vector<Point>
타입으로 저장할 수 있다. 하나의 영상에는 여러 객체가 존재할 수 있으므로 영상 하나에서 추출된 전체 객체의 외곽선 정보는 vector<vector<Point>>
타입으로 표현할 수 있다.
void findcontours(InputArray image, OutputArrayOfArrays contours,
OutputArray hierarchy, int mode,
int method, Point offset = Point());
void findContours(InputArray image, OutputArrayOfArrays contours,
int mode, int method, Point offset = Point());
image : 입력영상
contours : 검출된 외곽선 정보
hierarchy : 외곽선 계층 정보
mode : 외곽선 검출 모드
method : 외곽선 근사화 방법
offset : 외곽선 점 좌표의 오프셋(이동 변위)
mode
method
0번 외곽선은 1,2,3번 외곽선의 부모 외곽선,
1,2,3번 외곽선은 0번 외곽선의 자식 외곽선
0번과 4번 외곽선은 서로 포함 관계가 없이 대등하므로 이전 외곽선 또는 다음 외곽선의 관계를 가진다.
findContours() 함수에서 외곽선 검출 모드를 어떻게 지정하는지에 따라 검출되는 외곽선과 계층 구조가 달라진다.
findContours()함수로 검출한 외곽선 정보를 이용하여 영상 위에 외곽선을 그리려면 drawContours()함수를 사용할 수 있다.
void drawContours(InputOutputArray image, InputArrayOfArrays contours,
int contourIdx, const Scalar& color,
int thickness = 1, int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX, Point offset = Point());
image : 외곽선을 그릴 영상
contours : findContours()함수로 구한 전체 외곽선 정보 vector<vector<Point>>
contourIdx : 외곽선 번호
color : 외곽선 색상
thickness : 외곽선 두께
lineType : 외곽선 타입
hierarchy : 외곽선 계층 정보
maxLevel : 그릴 외곽선의 최대 레벨
offset : 추가적으로 지정할 외곽선 점 좌표의 오프셋
void contours_basic() {
Mat src = imread("contours.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return;
}
vector<vector<Point>> contours;
findContours(src, contours, RETR_LIST, CHAIN_APPROX_NONE);
Mat dst;
cvtColor(src, dst, COLOR_GRAY2BGR);
for (int i = 0; i < contours.size(); i++) {
Scalar c(rand() & 255, rand() & 255, rand() & 255);
drawContours(dst, contours, i, c, 2);
}
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
}