From 3218dbb0ab3960388d679292c508f89482cfd9ce Mon Sep 17 00:00:00 2001 From: "Shelia J." <12310645@mail.sustech.edu.cn> Date: Mon, 25 May 2026 16:11:44 +0800 Subject: [PATCH] Merge pull request #29124 from SheliaJimenez:dnn-pow-fix Dnn pow layer output type fix #29124 ### Description This pull request needs https://github.com/opencv/opencv_extra/pull/1372 to run. **issue:** when running disk-lightglue `.onnx` model, such error message is thrown: ```bash Error message OpenCV(5.0.0-pre) /home/tapakya/cpp/opencv_mod/opencv/modules/dnn/src/layers/nary_eltwise_layers.cpp:410: error: (-2:Unspecified error) in function 'virtual void cv::dnn::NaryEltwiseLayerImpl::getTypes(const std::vector&, int, int, std::vector&, std::vector&) const' > All inputs should have equal types (expected: 'inputs[0] == input'), where > 'inputs[0]' is 11 (CV_64SC1) > must be equal to > 'input' is 5 (CV_32FC1) ``` This is because in `nary_eltwise_layers.cpp`, `getTypes` didn't set the output type of power operation correctly. `int`^`float` should output `float`, whereas `getTypes` set the output type to `int` in this case. ```c++ if (op == OPERATION::POW) { CV_Assert(inputs.size() == 2); auto isIntegerType = [](int t) { return t == CV_8S || t == CV_8U || t == CV_16S || t == CV_16U || t == CV_32S || t == CV_32U || t == CV_64S || t == CV_64U; }; auto isFloatType = [](int t) { return t == CV_32F || t == CV_64F || t == CV_16F || t == CV_16BF; }; int out_type; const bool baseIsInt = isIntegerType(inputs[0]); const bool expIsInt = isIntegerType(inputs[1]); const bool baseIsFloat = isFloatType(inputs[0]); const bool expIsFloat = isFloatType(inputs[1]); if ((baseIsInt && expIsInt) || (baseIsFloat && expIsFloat)) { out_type = (inputs[0] == inputs[1]) ? inputs[0] : CV_32F; } else if (baseIsFloat != expIsFloat) { out_type = inputs[0]; // if base is int and exp is float, output type should be float } ``` **fix:** corrected the logic of determining output type ```c++ if ((baseIsInt && expIsInt) || (baseIsFloat && expIsFloat)) { out_type = (inputs[0] == inputs[1]) ? inputs[0] : CV_32F; } else if (baseIsFloat && !expIsFloat) { out_type = inputs[0]; } else if (!baseIsFloat && expIsFloat) { out_type = CV_32F; } ``` ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/dnn/src/layers/nary_eltwise_layers.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/dnn/src/layers/nary_eltwise_layers.cpp b/modules/dnn/src/layers/nary_eltwise_layers.cpp index a84bc82530..d244fd6f81 100644 --- a/modules/dnn/src/layers/nary_eltwise_layers.cpp +++ b/modules/dnn/src/layers/nary_eltwise_layers.cpp @@ -406,10 +406,14 @@ public: { out_type = (inputs[0] == inputs[1]) ? inputs[0] : CV_32F; } - else if (baseIsFloat != expIsFloat) + else if (baseIsFloat && !expIsFloat) { out_type = inputs[0]; } + else if (!baseIsFloat && expIsFloat) + { + out_type = CV_32F; + } else { out_type = CV_32F;