diff --git a/modules/dnn/src/layers/reduce2_layer.cpp b/modules/dnn/src/layers/reduce2_layer.cpp index 2049e6aa7b..56c59e96ce 100644 --- a/modules/dnn/src/layers/reduce2_layer.cpp +++ b/modules/dnn/src/layers/reduce2_layer.cpp @@ -122,7 +122,7 @@ public: std::fill(shape_out.begin(), shape_out.end(), 1); outs[0] = shape_out; } else { - outs[0] = MatShape(1, 1); + outs[0] = MatShape::scalar(); } } return false; @@ -142,7 +142,7 @@ public: shape_output.push_back(shape_output_[i]); } } - if (shape_output.empty()) shape_output.push_back(1); + if (shape_output.empty()) shape_output = MatShape::scalar(); outs[0] = shape_output; return false; } @@ -471,7 +471,7 @@ public: outShape = inpShape; for (int i = 0; i < (int)outShape.size(); ++i) outShape[i] = 1; } else { - outShape.assign(1, 1); + outShape = MatShape::scalar(); } } } else { @@ -487,7 +487,7 @@ public: outShape.push_back(tmp[i]); } } - if (outShape.empty()) outShape.push_back(1); + if (outShape.empty()) outShape = MatShape::scalar(); axes = norm_axes; } diff --git a/modules/dnn/src/layers/reduce_layer.cpp b/modules/dnn/src/layers/reduce_layer.cpp index 6ce05e7b2b..6cd662edb3 100644 --- a/modules/dnn/src/layers/reduce_layer.cpp +++ b/modules/dnn/src/layers/reduce_layer.cpp @@ -118,7 +118,7 @@ public: for (auto i = 0; i < shape_output.size(); ++i) shape_output[i] = 1; } else { - shape_output.push_back(1); + shape_output = MatShape::scalar(); } outputs.assign(1, shape_output); } @@ -139,7 +139,7 @@ public: shape_output.push_back(shape_output_[i]); } if (shape_output.empty()) - shape_output.push_back(1); + shape_output = MatShape::scalar(); outputs.assign(1, shape_output); } diff --git a/modules/dnn/test/test_common.impl.hpp b/modules/dnn/test/test_common.impl.hpp index b2a626d47a..499b610b4a 100644 --- a/modules/dnn/test/test_common.impl.hpp +++ b/modules/dnn/test/test_common.impl.hpp @@ -79,11 +79,27 @@ void normAssert( cv::InputArray ref, cv::InputArray test, const char *comment /*= ""*/, double l1 /*= 0.00001*/, double lInf /*= 0.0001*/) { - double normL1 = cvtest::norm(ref, test, cv::NORM_L1) / ref.getMat().total(); - EXPECT_LE(normL1, l1) << comment << " |ref| = " << cvtest::norm(ref, cv::NORM_INF); + cv::Mat refMat = ref.getMat(); + cv::Mat testMat = test.getMat(); + const cv::MatShape refShape = refMat.shape(); + const cv::MatShape testShape = testMat.shape(); + const bool scalar1dCompatible = + (refShape.isScalar() && testShape.size() == 1 && testShape[0] == 1) || + (testShape.isScalar() && refShape.size() == 1 && refShape[0] == 1); + if (scalar1dCompatible) + { + const cv::MatShape oneShape{1}; + if (refShape.isScalar()) + refMat = refMat.reshape(1, oneShape); + if (testShape.isScalar()) + testMat = testMat.reshape(1, oneShape); + } - double normInf = cvtest::norm(ref, test, cv::NORM_INF); - EXPECT_LE(normInf, lInf) << comment << " |ref| = " << cvtest::norm(ref, cv::NORM_INF); + double normL1 = cvtest::norm(refMat, testMat, cv::NORM_L1) / refMat.total(); + EXPECT_LE(normL1, l1) << comment << " |ref| = " << cvtest::norm(refMat, cv::NORM_INF); + + double normInf = cvtest::norm(refMat, testMat, cv::NORM_INF); + EXPECT_LE(normInf, lInf) << comment << " |ref| = " << cvtest::norm(refMat, cv::NORM_INF); } std::vector matToBoxes(const cv::Mat& m) diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index 49585dc7d1..625f5fb526 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -118,8 +118,12 @@ public: net.setInput(inps[i], inputNames[i]); Mat out = net.forward(""); - // BUG: https://github.com/opencv/opencv/issues/28563 - // EXPECT_EQ(shape(out), shape(ref)); + MatShape outShape = shape(out); + MatShape refShape = shape(ref); + bool scalar1dCompatible = + (outShape.isScalar() && refShape.size() == 1 && refShape[0] == 1) || + (refShape.isScalar() && outShape.size() == 1 && outShape[0] == 1); + EXPECT_TRUE(outShape == refShape || scalar1dCompatible); if (useSoftmax) {