1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge pull request #28171 from ramukhsuya:tflite-maximum-support

dnn(tflite): add support for MAXIMUM layer #28171

Fixes #26433
This PR adds support for the `MAXIMUM` layer in the TFLite importer.
It maps the TFLite `MAXIMUM` opcode to the existing OpenCV Element-wise `Max` operation.

### 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
- [x] There is a reference to the original bug report and related work
- [ ] 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
This commit is contained in:
ramukhsuya
2025-12-18 20:25:04 +05:30
committed by GitHub
parent bbda4e8964
commit 44b31dd82c
2 changed files with 34 additions and 2 deletions
+6 -2
View File
@@ -287,7 +287,8 @@ TFLiteImporter::DispatchMap TFLiteImporter::buildDispatchMap()
dispatch["DEPTHWISE_CONV_2D"] = &TFLiteImporter::parseDWConvolution;
dispatch["ADD"] = dispatch["MUL"] = dispatch["SUB"] =
dispatch["SQRT"] = dispatch["DIV"] = dispatch["NEG"] =
dispatch["RSQRT"] = dispatch["SQUARED_DIFFERENCE"] = &TFLiteImporter::parseEltwise;
dispatch["RSQRT"] = dispatch["SQUARED_DIFFERENCE"] =
dispatch["MAXIMUM"] = &TFLiteImporter::parseEltwise;
dispatch["RELU"] = dispatch["PRELU"] = dispatch["HARD_SWISH"] =
dispatch["LOGISTIC"] = dispatch["LEAKY_RELU"] = &TFLiteImporter::parseActivation;
dispatch["MAX_POOL_2D"] = dispatch["AVERAGE_POOL_2D"] = &TFLiteImporter::parsePooling;
@@ -577,7 +578,10 @@ void TFLiteImporter::parseEltwise(const Operator& op, const std::string& opcode,
}
else if (opcode == "SQRT" && !isOpInt8) {
layerParams.type = "Sqrt";
} else {
}
else if (opcode == "MAXIMUM" && !isOpInt8) {
layerParams.set("operation", "max");
}else {
CV_Error(Error::StsNotImplemented, cv::format("DNN/TFLite: Unknown opcode for %s Eltwise layer '%s'", isOpInt8 ? "INT8" : "FP32", opcode.c_str()));
}
+28
View File
@@ -283,6 +283,34 @@ TEST_P(Test_TFLite, face_blendshapes)
testModel("face_blendshapes", inp);
}
TEST_P(Test_TFLite, maximum)
{
Net net = readNetFromTFLite(findDataFile("dnn/tflite/maximum.tflite"));
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
Mat input_x = blobFromNPY(findDataFile("dnn/tflite/maximum_input_x.npy"));
Mat input_y = blobFromNPY(findDataFile("dnn/tflite/maximum_input_y.npy"));
net.setInput(input_x, "x");
net.setInput(input_y, "y");
Mat out = net.forward();
Mat ref = blobFromNPY(findDataFile("dnn/tflite/maximum_output.npy"));
double l1 = 1e-5;
double lInf = 1e-4;
if (target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16)
{
l1 = 1e-3;
lInf = 1e-3;
}
normAssert(ref, out, "", l1, lInf);
}
INSTANTIATE_TEST_CASE_P(/**/, Test_TFLite, dnnBackendsAndTargets());
}} // namespace