지난번에 영상의 윤곽선을 추출하는 findContours()에 대해 자세히 알아 봤습니다.
이번에는 findContours()로 찾은 윤곽선을 영상 위에 그리는 방법에 대해 알아보겠습니다.
drawContours
drawContours()의 원형은 아래와 같습니다.
src
|
윤곽선을 그릴 영상, gray, color 영상 가능
|
contours
|
윤곽선 정보, vector<vector<Point>> 타입
|
contourIdx
|
윤곽선 인덱스, -1일 경우 전체 윤곽선을 한번에 그림
|
color
|
윤곽선 색상
|
thickness
|
윤곽선 두께, FILLED 또는 -1일 경우 내부를 채움
|
lineType
|
윤곽선 타입
|
hierarchy
|
윤곽선 계층 정보
|
maxLevel
|
윤곽선의 최대 레벨, 0이면 지정한 번호의 윤곽선만, 1 이상이면 그 이하 레벨 윤곽선 그림
|
offset
|
윤곽선 점 좌표의 이동 변위 오프셋
|
윤곽선 그리는 기본 소스는 아래와 같습니다.
color는 random 변수를 사용하여 임의의 색으로 표시를 하였습니다.
#include <iostream>
#include "opencv2/opencv.hpp"
int main()
{
cv::Mat src = cv::imread("../contour.bmp", cv::IMREAD_GRAYSCALE);
if (src.empty()) return 1;
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
int mode = cv::RETR_TREE;
int method = cv::CHAIN_APPROX_SIMPLE;
cv::findContours(src, contours, hierarchy, mode, method);
cv::Mat src_color;
cv::cvtColor(src, src_color, cv::COLOR_GRAY2BGR);
cv::RNG rng(12345);
for (int i = 0; i < contours.size(); ++i) {
cv::drawContours(src_color, contours, i, cv::Scalar(rng.uniform(0, 256),
rng.uniform(0, 256), rng.uniform(0, 256)), 2);
}
return 0;
}
그림 결과는 아래와 같습니다.
for문을 이용할 경우 특정 index만 그림을 그릴 수 있고, 전체를 그리고 싶다면 contourIndex에 -1을 넣으시면 됩니다. 하지만 이럴 경우, 한가지 색상으로만 그림이 그려질 수 밖에 없어요.
만약 contour 내부를 채우고 싶다면, 아래와 같이 thickness에 -1 또는 cv::FILLED를 넣으시면 됩니다.
결과는 아래와 같습니다.
drawContours() 함수는 반드시 findContours() 에서 나온 결과값만 그려주는 것이 아닙니다.
아래와 같이 임의의 값을 넣어 그림을 그릴 수 있습니다. 이는 polygon 형태의 roi를 그릴 때에도 사용이 가능합니다.
#include <iostream>
#include "opencv2/opencv.hpp"
int main()
{
cv::Mat src = cv::Mat::zeros(100, 100, CV_8UC1);
std::vector<cv::Point> vecData{ cv::Point(1,1),
cv::Point(10, 10),
cv::Point(10, 30),
cv::Point(80, 80),
cv::Point(80, 1) };
std::vector<std::vector<cv::Point>> vvecData{ vecData };
cv::drawContours(src, vvecData, -1, cv::Scalar(255));
return 0;
}
결과는 아래와 같습니다.
다음에는 이러한 외곽선 정보를 이용하여 처리할 수 있는 함수들에 대해 알아보겠습니다.