mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
imgproc: accept CV_Bool masks in connected components
This commit is contained in:
@@ -5659,7 +5659,7 @@ namespace cv{
|
||||
const char *currentParallelFramework = cv::currentParallelFramework();
|
||||
const int nThreads = cv::getNumThreads();
|
||||
|
||||
CV_Assert(iDepth == CV_8U || iDepth == CV_8S);
|
||||
CV_Assert(iDepth == CV_8U || iDepth == CV_8S || iDepth == CV_Bool);
|
||||
|
||||
//Run parallel labeling only if the rows of the image are at least twice the number of available threads
|
||||
const bool is_parallel = currentParallelFramework != NULL && nThreads > 1 && L.rows / nThreads >= 2;
|
||||
|
||||
@@ -743,6 +743,73 @@ TEST(Imgproc_ConnectedComponents, single_column)
|
||||
|
||||
}
|
||||
|
||||
// See https://github.com/opencv/opencv/issues/29593
|
||||
// cv::Mat_<bool>::depth() returns CV_Bool in 5.0, where it was CV_8U in 4.x, so
|
||||
// connected components should keep accepting boolean masks as binary input.
|
||||
TEST(Imgproc_ConnectedComponents, bool_mask_29593)
|
||||
{
|
||||
Mat_<bool> input_bool(5, 6, false);
|
||||
input_bool(0, 0) = true;
|
||||
input_bool(0, 1) = true;
|
||||
input_bool(1, 1) = true;
|
||||
input_bool(2, 4) = true;
|
||||
input_bool(3, 4) = true;
|
||||
input_bool(3, 5) = true;
|
||||
input_bool(4, 2) = true;
|
||||
|
||||
Mat1b input_uchar(input_bool.size(), uchar(0));
|
||||
for (int r = 0; r < input_bool.rows; ++r)
|
||||
{
|
||||
for (int c = 0; c < input_bool.cols; ++c)
|
||||
{
|
||||
input_uchar(r, c) = input_bool(r, c) ? uchar(255) : uchar(0);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_EQ(input_bool.depth(), CV_Bool);
|
||||
|
||||
const int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI,
|
||||
cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
|
||||
|
||||
for (int connectivity : {4, 8})
|
||||
{
|
||||
for (size_t cclt = 0; cclt < sizeof(ccltype) / sizeof(ccltype[0]); ++cclt)
|
||||
{
|
||||
Mat1i labels_bool, labels_uchar;
|
||||
int nlabels_bool = 0;
|
||||
ASSERT_NO_THROW(nlabels_bool = connectedComponents(
|
||||
input_bool, labels_bool, connectivity, CV_32S, ccltype[cclt]));
|
||||
const int nlabels_uchar = connectedComponents(
|
||||
input_uchar, labels_uchar, connectivity, CV_32S, ccltype[cclt]);
|
||||
|
||||
normalizeLabels(labels_bool, nlabels_bool);
|
||||
normalizeLabels(labels_uchar, nlabels_uchar);
|
||||
|
||||
EXPECT_EQ(nlabels_bool, nlabels_uchar)
|
||||
<< "connectivity = " << connectivity << ", ccltype = " << ccltype[cclt];
|
||||
EXPECT_EQ(countNonZero(labels_bool != labels_uchar), 0)
|
||||
<< "connectivity = " << connectivity << ", ccltype = " << ccltype[cclt];
|
||||
|
||||
Mat stats_bool, centroids_bool, stats_uchar, centroids_uchar;
|
||||
ASSERT_NO_THROW(nlabels_bool = connectedComponentsWithStats(
|
||||
input_bool, labels_bool, stats_bool, centroids_bool, connectivity, CV_32S, ccltype[cclt]));
|
||||
const int nlabels_uchar_with_stats = connectedComponentsWithStats(
|
||||
input_uchar, labels_uchar, stats_uchar, centroids_uchar, connectivity, CV_32S, ccltype[cclt]);
|
||||
|
||||
normalizeLabels(labels_bool, nlabels_bool);
|
||||
normalizeLabels(labels_uchar, nlabels_uchar_with_stats);
|
||||
|
||||
EXPECT_EQ(nlabels_bool, nlabels_uchar_with_stats)
|
||||
<< "connectivity = " << connectivity << ", ccltype = " << ccltype[cclt];
|
||||
EXPECT_EQ(countNonZero(labels_bool != labels_uchar), 0)
|
||||
<< "connectivity = " << connectivity << ", ccltype = " << ccltype[cclt];
|
||||
EXPECT_EQ(countNonZero(stats_bool != stats_uchar), 0)
|
||||
<< "connectivity = " << connectivity << ", ccltype = " << ccltype[cclt];
|
||||
EXPECT_EQ(cv::norm(centroids_bool, centroids_uchar, NORM_INF), 0)
|
||||
<< "connectivity = " << connectivity << ", ccltype = " << ccltype[cclt];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Imgproc_ConnectedComponents, 4conn_regression_21366)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user