From 1612db5f91bebb759aa731a88bc1b742c94c96a9 Mon Sep 17 00:00:00 2001 From: Gil Shotan Date: Fri, 11 Sep 2020 02:47:53 +0300 Subject: [PATCH] Fix signed integer overflow in connected components --- modules/imgproc/src/connectedcomponents.cpp | 21 ++++++++++++------- .../imgproc/test/test_connectedcomponents.cpp | 14 +++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/modules/imgproc/src/connectedcomponents.cpp b/modules/imgproc/src/connectedcomponents.cpp index 2e06be4f98..c3a3f6f75b 100644 --- a/modules/imgproc/src/connectedcomponents.cpp +++ b/modules/imgproc/src/connectedcomponents.cpp @@ -145,14 +145,21 @@ namespace cv{ void finish(){ for (int l = 0; l < statsv.rows; ++l){ int *row =& statsv.at(l, 0); - row[CC_STAT_WIDTH] = row[CC_STAT_WIDTH] - row[CC_STAT_LEFT] + 1; - row[CC_STAT_HEIGHT] = row[CC_STAT_HEIGHT] - row[CC_STAT_TOP] + 1; - - Point2ui64& integral = integrals[l]; - double *centroid = ¢roidsv.at(l, 0); double area = ((unsigned*)row)[CC_STAT_AREA]; - centroid[0] = double(integral.x) / area; - centroid[1] = double(integral.y) / area; + double *centroid = ¢roidsv.at(l, 0); + if (area > 0){ + row[CC_STAT_WIDTH] = row[CC_STAT_WIDTH] - row[CC_STAT_LEFT] + 1; + row[CC_STAT_HEIGHT] = row[CC_STAT_HEIGHT] - row[CC_STAT_TOP] + 1; + Point2ui64& integral = integrals[l]; + centroid[0] = double(integral.x) / area; + centroid[1] = double(integral.y) / area; + } else { + row[CC_STAT_WIDTH] = 0; + row[CC_STAT_HEIGHT] = 0; + row[CC_STAT_LEFT] = -1; + centroid[0] = std::numeric_limits::quiet_NaN(); + centroid[1] = std::numeric_limits::quiet_NaN(); + } } } diff --git a/modules/imgproc/test/test_connectedcomponents.cpp b/modules/imgproc/test/test_connectedcomponents.cpp index 5952577691..bc5c9f0a23 100644 --- a/modules/imgproc/test/test_connectedcomponents.cpp +++ b/modules/imgproc/test/test_connectedcomponents.cpp @@ -225,5 +225,19 @@ TEST(Imgproc_ConnectedComponents, parallel_wu_labels) EXPECT_EQ(nbPixels, area); } +TEST(Imgproc_ConnectedComponents, missing_background_pixels) +{ + cv::Mat m = Mat::ones(10, 10, CV_8U); + cv::Mat labels; + cv::Mat stats; + cv::Mat centroids; + EXPECT_NO_THROW(cv::connectedComponentsWithStats(m, labels, stats, centroids, 8, CV_32S, cv::CCL_WU) ); + EXPECT_EQ(stats.at(0, cv::CC_STAT_WIDTH), 0); + EXPECT_EQ(stats.at(0, cv::CC_STAT_HEIGHT), 0); + EXPECT_EQ(stats.at(0, cv::CC_STAT_LEFT), -1); + EXPECT_TRUE(std::isnan(centroids.at(0, 0))); + EXPECT_TRUE(std::isnan(centroids.at(0, 1))); +} + }} // namespace