과제
findContours 에 RETR_EXTERNAL 옵션을 주면 가장 외곽의 연결된 선의 좌표들을 추출하는데, 만약 그 외곽선의 일부가 약한 픽셀로 되어 있다면 결과는 봉쇄되지 않은 contour로 인해 안쪽의 contour 좌표들도 결과로 추출되게 된다.
결과적으로 가장 외곽의 contour만 추출하고자 한다.
아이디어
모든 contour의 포인터들을 하나의 벡터에 집어넣고 그 벡터를 convexHull 로 처리하면 외곽에 완만한 곡선의 결과 포인트들만 얻을 수 있다.
처리속도를 고려한다면 모든 포인트들을 전부 벡터에 넣을 필요는 없고 간격을 두고 처리하는 것도 좋은 아이디어이다.
※ convexHull 과 approxPolyDP 의 차이점은 approxPolyDP 가 모든 contour 포인트들 대상으로 심플화된 선의 포인트 집합을 리턴하는 반면 convexHull 은 가장 바깥쪽의 포인트를 따라가면서 완만한 곡선 포인트 집합을 리턴하게 된다.
cv::Mat img = cv::imread("d:\\image.png"); cv::Mat gray; cv::cvtColor(img, gray, CV_BGR2GRAY); cv::blur(gray, gray, cv::Size(3, 3)); cv::Mat thresh; cv::Canny(gray, thresh, 0, 100, 3, true); std::vector<std::vector<cv::Point>> contours; std::vector<cv::Vec4i> hierarchy; cv::findContours(thresh, contours, hierarchy, cv::RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); std::vector<cv::Point> ConvexHullPoints; std::vector<cv::Point> pts; for (size_t i = 0; i < contours.size(); i++) for (size_t j = 0; j < contours[i].size(); j++) pts.push_back(contours[i][j]); cv::convexHull(pts, ConvexHullPoints ); cv::polylines(img, ConvexHullPoints, true, cv::Scalar(0, 0, 255), 2); cv::imwrite("d:\\result1.png", img); |
'opencv' 카테고리의 다른 글
스캔 이미지 중 여러 영수증 분리하기 (0) | 2025.02.15 |
---|---|
자동차 번호판 추출하기 (1) | 2025.02.15 |
Color를 Grayscale 로 변환 (커스텀 비율) (0) | 2025.02.14 |
C# 와 C++/CLI Dll 사이의 이미지 전달 (0) | 2025.02.10 |
(opencv) 이미지위의 직선상의 픽셀위치 구하기 (0) | 2025.02.08 |