From 8709115d9a34912d4ee485442d072113951467f6 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Wed, 29 May 2024 12:54:18 +0300 Subject: [PATCH] imgproc: fix contour approximation, added test --- modules/imgproc/src/contours.cpp | 2 +- modules/imgproc/src/contours_approx.cpp | 7 +++---- modules/imgproc/test/test_contours_new.cpp | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/modules/imgproc/src/contours.cpp b/modules/imgproc/src/contours.cpp index d88c6cbede..0577ca16c1 100644 --- a/modules/imgproc/src/contours.cpp +++ b/modules/imgproc/src/contours.cpp @@ -1884,7 +1884,7 @@ void cv::findContours_legacy( InputArray _image, OutputArrayOfArrays _contours, { CV_INSTRUMENT_REGION(); - findContours(_image, _contours, noArray(), mode, method, offset); + findContours_legacy(_image, _contours, noArray(), mode, method, offset); } /* End of file. */ diff --git a/modules/imgproc/src/contours_approx.cpp b/modules/imgproc/src/contours_approx.cpp index bf194933d6..f98ea190f4 100644 --- a/modules/imgproc/src/contours_approx.cpp +++ b/modules/imgproc/src/contours_approx.cpp @@ -231,7 +231,7 @@ static void pass_cleanup(vector& ares, size_t start_idx) const size_t len = ares.size(); size_t first = start_idx; - for (size_t i = start_idx, prev = i; i < len; ++i) + for (size_t i = start_idx, prev = start_idx; i < len; ++i) { ApproxItem& item = ares[i]; if (item.removed) @@ -248,10 +248,10 @@ static void pass_cleanup(vector& ares, size_t start_idx) if (s1 > s2 || (s1 == s2 && ares[prev].k <= ares[i].k)) /* remove second */ - clear_until(ares, get_next_idx(ares, prev), get_next_idx(ares, i)); + clear_until(ares, prev, get_next_idx(ares, i)); else /* remove first */ - clear_until(ares, first, i); + clear_until(ares, get_next_idx(ares, first), i); } else { @@ -259,7 +259,6 @@ static void pass_cleanup(vector& ares, size_t start_idx) clear_until(ares, first, i); } } - clear_until(ares, first, i); first = i; count = 1; } diff --git a/modules/imgproc/test/test_contours_new.cpp b/modules/imgproc/test/test_contours_new.cpp index 93afab2544..ef4ce29155 100644 --- a/modules/imgproc/test/test_contours_new.cpp +++ b/modules/imgproc/test/test_contours_new.cpp @@ -602,4 +602,23 @@ TEST(Imgproc_FindContours, link_runs) #endif } +TEST(Imgproc_FindContours, regression_25663) +{ + uint8_t data[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + Mat1b img(32,32,data); + vector> contours; + vector hierarchy; + findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_TC89_L1); +#if CHECK_OLD + vector> contours_o; + findContours_legacy(img, contours_o, RETR_EXTERNAL, CHAIN_APPROX_TC89_L1); + ASSERT_EQ(contours_o.size(), contours.size()); + for (size_t i = 0; i < contours_o.size(); ++i) + { + SCOPED_TRACE(format("contour = %zu", i)); + EXPECT_MAT_NEAR(Mat(contours_o[i]), Mat(contours[i]), 0); + } +#endif +} + }} // namespace opencv_test