Merge remote-tracking branch 'upstream/3.4' into merge-3.4

pull/20126/head
Alexander Alekhin 3 years ago
commit 80492d663e
  1. 8
      cmake/OpenCVCompilerDefenses.cmake
  2. 8
      doc/opencv.bib
  3. 1
      modules/dnn/src/layers/flatten_layer.cpp
  4. 57
      modules/dnn/src/onnx/onnx_importer.cpp
  5. 6
      modules/dnn/test/test_onnx_conformance_layer_filter__halide_denylist.inl.hpp
  6. 24
      modules/dnn/test/test_onnx_conformance_layer_filter__openvino.inl.hpp
  7. 6
      modules/dnn/test/test_onnx_conformance_layer_filter_opencv_all_denylist.inl.hpp
  8. 18
      modules/imgproc/include/opencv2/imgproc.hpp
  9. 12
      modules/imgproc/src/color_lab.cpp
  10. 1393
      modules/imgproc/src/connectedcomponents.cpp
  11. 4
      modules/imgproc/src/thresh.cpp
  12. 2
      modules/imgproc/test/test_color.cpp
  13. 501
      modules/imgproc/test/test_connectedcomponents.cpp
  14. 30
      modules/imgproc/test/test_thresh.cpp

@ -87,11 +87,3 @@ endif()
set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OPENCV_LINKER_DEFENSES_FLAGS_COMMON}" )
set( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OPENCV_LINKER_DEFENSES_FLAGS_COMMON}" )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OPENCV_LINKER_DEFENSES_FLAGS_COMMON}" )
if(CV_GCC OR CV_CLANG)
foreach(flags
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG
CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_DEBUG)
string(REPLACE "-O3" "-O2" ${flags} "${${flags}}")
endforeach()
endif()

@ -1301,6 +1301,14 @@
pages={281--305},
year={1987}
}
@article{Bolelli2021,
title={One DAG to Rule Them All},
author={Bolelli, Federico and Allegretti, Stefano and Grana, Costantino},
journal={IEEE Transactions on Pattern Analysis and Machine Intelligence},
year={2021},
publisher={IEEE},
doi = {10.1109/TPAMI.2021.3055337}
}
@inproceedings{liao2020real,
author={Liao, Minghui and Wan, Zhaoyi and Yao, Cong and Chen, Kai and Bai, Xiang},
title={Real-time Scene Text Detection with Differentiable Binarization},

@ -107,7 +107,6 @@ public:
{
outputShapeVec.push_back(inputs[0][i]);
}
CV_Assert(outputShapeVec.size() <= 4);
outputs.resize(inputs.size(), outputShapeVec);

@ -2023,20 +2023,67 @@ void ONNXImporter::parseSqueeze(LayerParams& layerParams, const opencv_onnx::Nod
addLayer(layerParams, node_proto);
}
void ONNXImporter::parseFlatten(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto)
void ONNXImporter::parseFlatten(LayerParams& layerParams, const opencv_onnx::NodeProto& node_proto_)
{
opencv_onnx::NodeProto node_proto = node_proto_;
CV_CheckEQ(node_proto.input_size(), 1, "");
int axis_ = layerParams.get<int>("axis", 1);
if (constBlobs.find(node_proto.input(0)) != constBlobs.end())
{
Mat input = getBlob(node_proto, 0);
int axis = normalize_axis(layerParams.get<int>("axis", 1), input.dims);
int axis = normalize_axis(axis_, input.dims);
std::vector<int> out_size(&input.size[0], &input.size[0] + axis);
out_size.push_back(input.total(axis));
Mat output = input.reshape(1, out_size);
int out_size[2] = {1, 1};
for (int i = 0; i < axis; ++i)
{
out_size[0] *= input.size[i];
}
for (int i = axis; i < input.dims; ++i)
{
out_size[1] *= input.size[i];
}
Mat output = input.reshape(1, 2, out_size);
addConstant(layerParams.name, output);
return;
}
IterShape_t shapeIt = outShapes.find(node_proto.input(0));
CV_Assert(shapeIt != outShapes.end());
MatShape inpShape = shapeIt->second;
int axis = normalize_axis(axis_, inpShape.size());
if (axis == 0 || axis == inpShape.size())
{
LayerParams reshapeLp;
reshapeLp.name = layerParams.name + "/reshape";
reshapeLp.type = "Reshape";
CV_Assert(layer_id.find(reshapeLp.name) == layer_id.end());
inpShape.insert(axis == 0 ? inpShape.begin() : inpShape.end(), 1);
reshapeLp.set("dim", DictValue::arrayInt(&inpShape[0], inpShape.size()));
opencv_onnx::NodeProto proto;
proto.add_input(node_proto.input(0));
proto.add_output(reshapeLp.name);
addLayer(reshapeLp, proto);
node_proto.set_input(0, reshapeLp.name);
axis += 1;
}
LayerParams first_pass;
first_pass.name = layerParams.name + "/flatten";
CV_Assert(layer_id.find(first_pass.name) == layer_id.end());
first_pass.type = "Flatten";
first_pass.set("axis", 0);
first_pass.set("end_axis", axis - 1);
opencv_onnx::NodeProto proto;
proto.add_input(node_proto.input(0));
proto.add_output(first_pass.name);
addLayer(first_pass, proto);
layerParams.set("axis", 1);
node_proto.set_input(0, first_pass.name);
addLayer(layerParams, node_proto);
}

@ -53,12 +53,6 @@
"test_elu",
"test_elu_default",
"test_exp",
"test_flatten_axis0",
"test_flatten_axis2",
"test_flatten_axis3",
"test_flatten_negative_axis1",
"test_flatten_negative_axis2",
"test_flatten_negative_axis4",
"test_floor",
"test_leakyrelu",
"test_leakyrelu_default",

@ -629,35 +629,23 @@ CASE(test_eyelike_with_dtype)
CASE(test_eyelike_without_dtype)
// no filter
CASE(test_flatten_axis0)
#if INF_ENGINE_VER_MAJOR_EQ(2021040000)
SKIP;
#endif
// no filter
CASE(test_flatten_axis1)
// no filter
CASE(test_flatten_axis2)
#if INF_ENGINE_VER_MAJOR_EQ(2021040000)
SKIP;
#endif
// no filter
CASE(test_flatten_axis3)
#if INF_ENGINE_VER_MAJOR_EQ(2021040000)
SKIP;
#endif
// no filter
CASE(test_flatten_default_axis)
// no filter
CASE(test_flatten_negative_axis1)
#if INF_ENGINE_VER_MAJOR_EQ(2021040000)
SKIP;
#endif
// no filter
CASE(test_flatten_negative_axis2)
#if INF_ENGINE_VER_MAJOR_EQ(2021040000)
SKIP;
#endif
// no filter
CASE(test_flatten_negative_axis3)
// no filter
CASE(test_flatten_negative_axis4)
#if INF_ENGINE_VER_MAJOR_EQ(2021040000)
SKIP;
#endif
// no filter
CASE(test_floor)
// no filter
CASE(test_floor_example)

@ -43,12 +43,6 @@
"test_castlike_STRING_to_FLOAT_expanded",
"test_concat_1d_axis_negative_1",
"test_div_uint8", // output type mismatch
"test_flatten_axis0",
"test_flatten_axis2",
"test_flatten_axis3",
"test_flatten_negative_axis1",
"test_flatten_negative_axis2",
"test_flatten_negative_axis4",
"test_logsoftmax_default_axis",
"test_maxpool_2d_dilations",
"test_maxpool_2d_same_lower",

@ -405,10 +405,10 @@ enum ConnectedComponentsTypes {
//! connected components algorithm
enum ConnectedComponentsAlgorithmsTypes {
CCL_DEFAULT = -1, //!< BBDT @cite Grana2010 algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity. The parallel implementation described in @cite Bolelli2017 is available for both BBDT and SAUF.
CCL_DEFAULT = -1, //!< Spaghetti @cite Bolelli2019 algorithm for 8-way connectivity, Spaghetti4C @cite Bolelli2021 algorithm for 4-way connectivity.
CCL_WU = 0, //!< SAUF @cite Wu2009 algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity. The parallel implementation described in @cite Bolelli2017 is available for SAUF.
CCL_GRANA = 1, //!< BBDT @cite Grana2010 algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity. The parallel implementation described in @cite Bolelli2017 is available for both BBDT and SAUF.
CCL_BOLELLI = 2, //!< Spaghetti @cite Bolelli2019 algorithm for 8-way connectivity, SAUF algorithm for 4-way connectivity.
CCL_BOLELLI = 2, //!< Spaghetti @cite Bolelli2019 algorithm for 8-way connectivity, Spaghetti4C @cite Bolelli2021 algorithm for 4-way connectivity. The parallel implementation described in @cite Bolelli2017 is available for both Spaghetti and Spaghetti4C.
CCL_SAUF = 3, //!< Same as CCL_WU. It is preferable to use the flag with the name of the algorithm (CCL_SAUF) rather than the one with the name of the first author (CCL_WU).
CCL_BBDT = 4, //!< Same as CCL_GRANA. It is preferable to use the flag with the name of the algorithm (CCL_BBDT) rather than the one with the name of the first author (CCL_GRANA).
CCL_SPAGHETTI = 5, //!< Same as CCL_BOLELLI. It is preferable to use the flag with the name of the algorithm (CCL_SPAGHETTI) rather than the one with the name of the first author (CCL_BOLELLI).
@ -3858,9 +3858,10 @@ image with 4 or 8 way connectivity - returns N, the total number of labels [0, N
represents the background label. ltype specifies the output label image type, an important
consideration based on the total number of labels or alternatively the total number of pixels in
the source image. ccltype specifies the connected components labeling algorithm to use, currently
Grana (BBDT) and Wu's (SAUF) @cite Wu2009 algorithms are supported, see the #ConnectedComponentsAlgorithmsTypes
for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
This function uses parallel version of both Grana and Wu's algorithms if at least one allowed
Bolelli (Spaghetti) @cite Bolelli2019, Grana (BBDT) @cite Grana2010 and Wu's (SAUF) @cite Wu2009 algorithms
are supported, see the #ConnectedComponentsAlgorithmsTypes for details. Note that SAUF algorithm forces
a row major ordering of labels while Spaghetti and BBDT do not.
This function uses parallel version of the algorithms if at least one allowed
parallel framework is enabled and if the rows of the image are at least twice the number returned by #getNumberOfCPUs.
@param image the 8-bit single-channel image to be labeled
@ -3890,9 +3891,10 @@ image with 4 or 8 way connectivity - returns N, the total number of labels [0, N
represents the background label. ltype specifies the output label image type, an important
consideration based on the total number of labels or alternatively the total number of pixels in
the source image. ccltype specifies the connected components labeling algorithm to use, currently
Grana's (BBDT) and Wu's (SAUF) @cite Wu2009 algorithms are supported, see the #ConnectedComponentsAlgorithmsTypes
for details. Note that SAUF algorithm forces a row major ordering of labels while BBDT does not.
This function uses parallel version of both Grana and Wu's algorithms (statistics included) if at least one allowed
Bolelli (Spaghetti) @cite Bolelli2019, Grana (BBDT) @cite Grana2010 and Wu's (SAUF) @cite Wu2009 algorithms
are supported, see the #ConnectedComponentsAlgorithmsTypes for details. Note that SAUF algorithm forces
a row major ordering of labels while Spaghetti and BBDT do not.
This function uses parallel version of the algorithms (statistics included) if at least one allowed
parallel framework is enabled and if the rows of the image are at least twice the number returned by #getNumberOfCPUs.
@param image the 8-bit single-channel image to be labeled

@ -2979,9 +2979,9 @@ struct RGB2Luvfloat
for( ; i < n; i++, src += scn, dst += 3 )
{
float R = src[0], G = src[1], B = src[2];
R = std::min(std::max(R, 0.f), 1.f);
G = std::min(std::max(G, 0.f), 1.f);
B = std::min(std::max(B, 0.f), 1.f);
R = clip(R);
G = clip(G);
B = clip(B);
if( gammaTab )
{
R = splineInterpolate(R*gscale, gammaTab, GAMMA_TAB_SIZE);
@ -3205,9 +3205,9 @@ struct Luv2RGBfloat
float G = X*C3 + Y*C4 + Z*C5;
float B = X*C6 + Y*C7 + Z*C8;
R = std::min(std::max(R, 0.f), 1.f);
G = std::min(std::max(G, 0.f), 1.f);
B = std::min(std::max(B, 0.f), 1.f);
R = clip(R);
G = clip(G);
B = clip(B);
if( gammaTab )
{

File diff suppressed because it is too large Load Diff

@ -757,16 +757,14 @@ thresh_32f( const Mat& _src, Mat& _dst, float thresh, float maxval, int type )
}
setIppErrorStatus();
break;
#if 0 // details: https://github.com/opencv/opencv/pull/16085
case THRESH_TOZERO:
if (0 <= CV_INSTRUMENT_FUN_IPP(ippiThreshold_LTVal_32f_C1R, src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, thresh + FLT_EPSILON, 0))
if (0 <= CV_INSTRUMENT_FUN_IPP(ippiThreshold_LTVal_32f_C1R, src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, nextafterf(thresh, std::numeric_limits<float>::infinity()), 0))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
break;
#endif
case THRESH_TOZERO_INV:
if (0 <= CV_INSTRUMENT_FUN_IPP(ippiThreshold_GTVal_32f_C1R, src, (int)src_step*sizeof(src[0]), dst, (int)dst_step*sizeof(dst[0]), sz, thresh, 0))
{

@ -3203,6 +3203,8 @@ TEST(ImgProc_RGB2Lab, NaN_21111)
src(0, 1) = src(0, 28) = src(0, 82) = src(0, 109) = cv::Vec3f(0, kNaN, 0);
src(0, 2) = src(0, 29) = src(0, 83) = src(0, 110) = cv::Vec3f(kNaN, 0, 0);
EXPECT_NO_THROW(cvtColor(src, dst, COLOR_RGB2Lab));
EXPECT_NO_THROW(cvtColor(src, dst, COLOR_RGB2Luv));
EXPECT_NO_THROW(cvtColor(src, dst, COLOR_Luv2RGB));
#if 0 // no NaN propagation guarantee
for (int i = 0; i < 20; ++i)

@ -42,7 +42,8 @@
#include "test_precomp.hpp"
namespace opencv_test { namespace {
namespace opencv_test {
namespace {
class CV_ConnectedComponentsTest : public cvtest::BaseTest
{
@ -61,10 +62,10 @@ void normalizeLabels(Mat1i& imgLabels, int iNumLabels) {
vector<int> vecNewLabels(iNumLabels + 1, 0);
int iMaxNewLabel = 0;
for (int r = 0; r<imgLabels.rows; ++r) {
for (int c = 0; c<imgLabels.cols; ++c) {
for (int r = 0; r < imgLabels.rows; ++r) {
for (int c = 0; c < imgLabels.cols; ++c) {
int iCurLabel = imgLabels(r, c);
if (iCurLabel>0) {
if (iCurLabel > 0) {
if (vecNewLabels[iCurLabel] == 0) {
vecNewLabels[iCurLabel] = ++iMaxNewLabel;
}
@ -74,7 +75,7 @@ void normalizeLabels(Mat1i& imgLabels, int iNumLabels) {
}
}
void CV_ConnectedComponentsTest::run( int /* start_from */)
void CV_ConnectedComponentsTest::run(int /* start_from */)
{
int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI, cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
@ -91,7 +92,7 @@ void CV_ConnectedComponentsTest::run( int /* start_from */)
Mat bw = orig > 128;
for (uint cclt = 0; cclt < sizeof(ccltype)/sizeof(int); ++cclt)
for (uint cclt = 0; cclt < sizeof(ccltype) / sizeof(int); ++cclt)
{
Mat1i labelImage;
@ -100,11 +101,11 @@ void CV_ConnectedComponentsTest::run( int /* start_from */)
normalizeLabels(labelImage, nLabels);
// Validate test results
for (int r = 0; r < labelImage.rows; ++r){
for (int c = 0; c < labelImage.cols; ++c){
for (int r = 0; r < labelImage.rows; ++r) {
for (int c = 0; c < labelImage.cols; ++c) {
int l = labelImage.at<int>(r, c);
bool pass = l >= 0 && l <= nLabels;
if (!pass){
if (!pass) {
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
return;
}
@ -166,12 +167,12 @@ static cv::Mat createCrashMat(int numThreads) {
for (int s = stripeRange.start; s < stripeRange.end; s++) {
cv::Range sr(s, s + 1);
cv::Range r;
r.start = (int) (wholeRange.start +
((uint64) sr.start * (wholeRange.end - wholeRange.start) + nstripes / 2) / nstripes);
r.start = (int)(wholeRange.start +
((uint64)sr.start * (wholeRange.end - wholeRange.start) + nstripes / 2) / nstripes);
r.end = sr.end >= nstripes ?
wholeRange.end :
(int) (wholeRange.start +
((uint64) sr.end * (wholeRange.end - wholeRange.start) + nstripes / 2) / nstripes);
wholeRange.end :
(int)(wholeRange.start +
((uint64)sr.end * (wholeRange.end - wholeRange.start) + nstripes / 2) / nstripes);
if (r.start > 0 && r.start % 2 == 1 && r.end % 2 == 0 && r.end >= r.start + 2) {
bugRange = r;
@ -203,7 +204,7 @@ static cv::Mat createCrashMat(int numThreads) {
TEST(Imgproc_ConnectedComponents, parallel_wu_labels)
{
cv::Mat mat = createCrashMat(cv::getNumThreads());
if(mat.empty()) {
if (mat.empty()) {
return;
}
@ -213,10 +214,10 @@ TEST(Imgproc_ConnectedComponents, parallel_wu_labels)
cv::Mat stats;
cv::Mat centroids;
int nb = 0;
EXPECT_NO_THROW( nb = cv::connectedComponentsWithStats(mat, labels, stats, centroids, 8, CV_32S, cv::CCL_WU) );
EXPECT_NO_THROW(nb = cv::connectedComponentsWithStats(mat, labels, stats, centroids, 8, CV_32S, cv::CCL_WU));
int area = 0;
for(int i=1; i<nb; ++i) {
for (int i = 1; i < nb; ++i) {
area += stats.at<int32_t>(i, cv::CC_STAT_AREA);
}
@ -229,7 +230,7 @@ TEST(Imgproc_ConnectedComponents, missing_background_pixels)
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_NO_THROW(cv::connectedComponentsWithStats(m, labels, stats, centroids, 8, CV_32S, cv::CCL_WU));
EXPECT_EQ(stats.at<int32_t>(0, cv::CC_STAT_WIDTH), 0);
EXPECT_EQ(stats.at<int32_t>(0, cv::CC_STAT_HEIGHT), 0);
EXPECT_EQ(stats.at<int32_t>(0, cv::CC_STAT_LEFT), -1);
@ -241,21 +242,21 @@ TEST(Imgproc_ConnectedComponents, spaghetti_bbdt_sauf_stats)
{
cv::Mat1b img(16, 16);
img << 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 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;
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 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;
cv::Mat1i labels;
cv::Mat1i stats;
@ -357,4 +358,436 @@ TEST(Imgproc_ConnectedComponents, spaghetti_bbdt_sauf_stats)
}
}
}} // namespace
TEST(Imgproc_ConnectedComponents, chessboard_even)
{
cv::Size size(16, 16);
cv::Mat1b input(size);
cv::Mat1i output_8c(size);
cv::Mat1i output_4c(size);
// Chessboard image with even number of rows and cols
// Note that this is the maximum number of labels for 4-way connectivity
{
input <<
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1;
output_8c <<
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1;
output_4c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0,
0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16,
17, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24, 0,
0, 25, 0, 26, 0, 27, 0, 28, 0, 29, 0, 30, 0, 31, 0, 32,
33, 0, 34, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40, 0,
0, 41, 0, 42, 0, 43, 0, 44, 0, 45, 0, 46, 0, 47, 0, 48,
49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0,
0, 57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 64,
65, 0, 66, 0, 67, 0, 68, 0, 69, 0, 70, 0, 71, 0, 72, 0,
0, 73, 0, 74, 0, 75, 0, 76, 0, 77, 0, 78, 0, 79, 0, 80,
81, 0, 82, 0, 83, 0, 84, 0, 85, 0, 86, 0, 87, 0, 88, 0,
0, 89, 0, 90, 0, 91, 0, 92, 0, 93, 0, 94, 0, 95, 0, 96,
97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0,
0, 105, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112,
113, 0, 114, 0, 115, 0, 116, 0, 117, 0, 118, 0, 119, 0, 120, 0,
0, 121, 0, 122, 0, 123, 0, 124, 0, 125, 0, 126, 0, 127, 0, 128;
}
int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI, cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
cv::Mat1i labels;
cv::Mat diff;
int nLabels = 0;
for (size_t cclt = 0; cclt < sizeof(ccltype) / sizeof(int); ++cclt) {
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 8, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_8c;
EXPECT_EQ(cv::countNonZero(diff), 0);
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 4, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_4c;
EXPECT_EQ(cv::countNonZero(diff), 0);
}
}
TEST(Imgproc_ConnectedComponents, chessboard_odd)
{
cv::Size size(15, 15);
cv::Mat1b input(size);
cv::Mat1i output_8c(size);
cv::Mat1i output_4c(size);
// Chessboard image with odd number of rows and cols
// Note that this is the maximum number of labels for 4-way connectivity
{
input <<
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1;
output_8c <<
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1;
output_4c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8,
0, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0,
16, 0, 17, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23,
0, 24, 0, 25, 0, 26, 0, 27, 0, 28, 0, 29, 0, 30, 0,
31, 0, 32, 0, 33, 0, 34, 0, 35, 0, 36, 0, 37, 0, 38,
0, 39, 0, 40, 0, 41, 0, 42, 0, 43, 0, 44, 0, 45, 0,
46, 0, 47, 0, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53,
0, 54, 0, 55, 0, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0,
61, 0, 62, 0, 63, 0, 64, 0, 65, 0, 66, 0, 67, 0, 68,
0, 69, 0, 70, 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, 0,
76, 0, 77, 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, 0, 83,
0, 84, 0, 85, 0, 86, 0, 87, 0, 88, 0, 89, 0, 90, 0,
91, 0, 92, 0, 93, 0, 94, 0, 95, 0, 96, 0, 97, 0, 98,
0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 105, 0,
106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113;
}
int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI, cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
cv::Mat1i labels;
cv::Mat diff;
int nLabels = 0;
for (size_t cclt = 0; cclt < sizeof(ccltype) / sizeof(int); ++cclt) {
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 8, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_8c;
EXPECT_EQ(cv::countNonZero(diff), 0);
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 4, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_4c;
EXPECT_EQ(cv::countNonZero(diff), 0);
}
}
TEST(Imgproc_ConnectedComponents, maxlabels_8conn_even)
{
cv::Size size(16, 16);
cv::Mat1b input(size);
cv::Mat1i output_8c(size);
cv::Mat1i output_4c(size);
{
input <<
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
output_8c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25, 0, 26, 0, 27, 0, 28, 0, 29, 0, 30, 0, 31, 0, 32, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33, 0, 34, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41, 0, 42, 0, 43, 0, 44, 0, 45, 0, 46, 0, 47, 0, 48, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 64, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
output_4c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25, 0, 26, 0, 27, 0, 28, 0, 29, 0, 30, 0, 31, 0, 32, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33, 0, 34, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41, 0, 42, 0, 43, 0, 44, 0, 45, 0, 46, 0, 47, 0, 48, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 64, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
}
int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI, cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
cv::Mat1i labels;
cv::Mat diff;
int nLabels = 0;
for (size_t cclt = 0; cclt < sizeof(ccltype) / sizeof(int); ++cclt) {
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 8, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_8c;
EXPECT_EQ(cv::countNonZero(diff), 0);
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 4, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_4c;
EXPECT_EQ(cv::countNonZero(diff), 0);
}
}
TEST(Imgproc_ConnectedComponents, maxlabels_8conn_odd)
{
cv::Size size(15, 15);
cv::Mat1b input(size);
cv::Mat1i output_8c(size);
cv::Mat1i output_4c(size);
{
input <<
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1;
output_8c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25, 0, 26, 0, 27, 0, 28, 0, 29, 0, 30, 0, 31, 0, 32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33, 0, 34, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41, 0, 42, 0, 43, 0, 44, 0, 45, 0, 46, 0, 47, 0, 48,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 64;
output_4c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 18, 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, 0, 24,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25, 0, 26, 0, 27, 0, 28, 0, 29, 0, 30, 0, 31, 0, 32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33, 0, 34, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41, 0, 42, 0, 43, 0, 44, 0, 45, 0, 46, 0, 47, 0, 48,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 64;
}
int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI, cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
cv::Mat1i labels;
cv::Mat diff;
int nLabels = 0;
for (size_t cclt = 0; cclt < sizeof(ccltype) / sizeof(int); ++cclt) {
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 8, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_8c;
EXPECT_EQ(cv::countNonZero(diff), 0);
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 4, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_4c;
EXPECT_EQ(cv::countNonZero(diff), 0);
}
}
TEST(Imgproc_ConnectedComponents, single_row)
{
cv::Size size(1, 15);
cv::Mat1b input(size);
cv::Mat1i output_8c(size);
cv::Mat1i output_4c(size);
{
input <<
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1;
output_8c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8;
output_4c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8;
}
int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI, cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
cv::Mat1i labels;
cv::Mat diff;
int nLabels = 0;
for (size_t cclt = 0; cclt < sizeof(ccltype) / sizeof(int); ++cclt) {
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 8, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_8c;
EXPECT_EQ(cv::countNonZero(diff), 0);
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 4, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_4c;
EXPECT_EQ(cv::countNonZero(diff), 0);
}
}
TEST(Imgproc_ConnectedComponents, single_column)
{
cv::Size size(15, 1);
cv::Mat1b input(size);
cv::Mat1i output_8c(size);
cv::Mat1i output_4c(size);
{
input <<
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1;
output_8c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8;
output_4c <<
1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8;
}
int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI, cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
cv::Mat1i labels;
cv::Mat diff;
int nLabels = 0;
for (size_t cclt = 0; cclt < sizeof(ccltype) / sizeof(int); ++cclt) {
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 8, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_8c;
EXPECT_EQ(cv::countNonZero(diff), 0);
EXPECT_NO_THROW(nLabels = cv::connectedComponents(input, labels, 4, CV_32S, ccltype[cclt]));
normalizeLabels(labels, nLabels);
diff = labels != output_4c;
EXPECT_EQ(cv::countNonZero(diff), 0);
}
}
}
} // namespace

@ -511,4 +511,34 @@ TEST(Imgproc_Threshold, regression_THRESH_TOZERO_IPP_16085)
EXPECT_EQ(0, cv::norm(result, NORM_INF));
}
TEST(Imgproc_Threshold, regression_THRESH_TOZERO_IPP_21258)
{
Size sz(16, 16);
float val = nextafterf(16.0f, 0.0f); // 0x417fffff, all bits in mantissa are 1
Mat input(sz, CV_32F, Scalar::all(val));
Mat result;
cv::threshold(input, result, val, 0.0, THRESH_TOZERO);
EXPECT_EQ(0, cv::norm(result, NORM_INF));
}
TEST(Imgproc_Threshold, regression_THRESH_TOZERO_IPP_21258_Min)
{
Size sz(16, 16);
float min_val = -std::numeric_limits<float>::max();
Mat input(sz, CV_32F, Scalar::all(min_val));
Mat result;
cv::threshold(input, result, min_val, 0.0, THRESH_TOZERO);
EXPECT_EQ(0, cv::norm(result, NORM_INF));
}
TEST(Imgproc_Threshold, regression_THRESH_TOZERO_IPP_21258_Max)
{
Size sz(16, 16);
float max_val = std::numeric_limits<float>::max();
Mat input(sz, CV_32F, Scalar::all(max_val));
Mat result;
cv::threshold(input, result, max_val, 0.0, THRESH_TOZERO);
EXPECT_EQ(0, cv::norm(result, NORM_INF));
}
}} // namespace

Loading…
Cancel
Save