1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 08:13:04 +04:00

dnn(tflite): add 3rdparty flatbuffers with pre-generated schema

This commit is contained in:
Alexander Alekhin
2023-02-18 16:21:07 +00:00
parent ca48e217f1
commit bdff0949bb
28 changed files with 15285 additions and 66 deletions
+24 -13
View File
@@ -127,23 +127,27 @@ else()
set(fw_inc "${CMAKE_CURRENT_LIST_DIR}/misc/caffe" "${CMAKE_CURRENT_LIST_DIR}/misc/tensorflow" "${CMAKE_CURRENT_LIST_DIR}/misc/onnx")
endif()
ocv_option(OPENCV_DNN_TFLITE "Build with TFLite support" (TARGET ocv.3rdparty.flatbuffers))
if(TARGET ocv.3rdparty.flatbuffers AND OPENCV_DNN_TFLITE)
if(NOT HAVE_FLATBUFFERS)
message(FATAL_ERROR "DNN: TFLite is not supported without enabled 'flatbuffers'. Check build configuration.")
endif()
list(APPEND libs ocv.3rdparty.flatbuffers)
list(APPEND fw_hdrs "${CMAKE_CURRENT_LIST_DIR}/misc/tflite/schema_generated.h")
list(APPEND fw_inc "${CMAKE_CURRENT_LIST_DIR}/misc/tflite")
# Schema is generated by this command:
#add_custom_command(
# OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/schema_generated.h"
# COMMAND flatbuffers::flatc --cpp -o "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_LIST_DIR}/src/tflite/schema.fbs")
endif()
list(APPEND include_dirs ${fw_inc})
list(APPEND libs ${Protobuf_LIBRARIES})
if(NOT BUILD_PROTOBUF)
list(APPEND include_dirs ${Protobuf_INCLUDE_DIRS})
endif()
if(HAVE_FLATBUFFERS)
list(APPEND libs flatbuffers::flatbuffers)
list(APPEND fw_srcs "${CMAKE_CURRENT_BINARY_DIR}/schema_generated.h")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/schema_generated.h"
COMMAND flatbuffers::flatc --cpp -o "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_LIST_DIR}/src/tflite/schema.fbs")
ocv_target_compile_definitions(${the_module} PRIVATE "HAVE_FLATBUFFERS=1")
endif()
set(sources_options "")
list(APPEND libs ${LAPACK_LIBRARIES})
@@ -232,6 +236,9 @@ if(TARGET ocv.3rdparty.openvino AND OPENCV_DNN_OPENVINO)
endif()
endif()
ocv_install_used_external_targets(${libs} ${dnn_runtime_libs})
ocv_glob_module_sources(${sources_options} SOURCES ${fw_srcs} ${webnn_srcs})
ocv_create_module(${libs} ${dnn_runtime_libs})
ocv_add_samples()
@@ -292,8 +299,12 @@ if(TARGET ocv.3rdparty.cann AND OPENCV_TEST_DNN_CANN)
endif()
endif()
if(HAVE_FLATBUFFERS)
ocv_option(OPENCV_TEST_DNN_TFLITE "Build test with TFLite" (OPENCV_DNN_TFLITE))
if(OPENCV_TEST_DNN_TFLITE)
if(TARGET opencv_test_dnn)
ocv_target_compile_definitions(opencv_test_dnn PRIVATE "HAVE_FLATBUFFERS=1")
ocv_target_compile_definitions(opencv_test_dnn PRIVATE "OPENCV_TEST_DNN_TFLITE=1")
endif()
if(TARGET opencv_perf_dnn)
ocv_target_compile_definitions(opencv_perf_dnn PRIVATE "OPENCV_TEST_DNN_TFLITE=1")
endif()
endif()
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -119,7 +119,7 @@ TFLiteImporter::TFLiteImporter(Net& dstNet, const char* modelBuffer, size_t bufS
CV_Assert(model);
CV_Assert(model->subgraphs());
CV_Assert(model->buffers());
CV_CheckEQ(model->subgraphs()->size(), 1, "");
CV_CheckEQ((size_t)model->subgraphs()->size(), 1u, "");
modelTensors = model->subgraphs()->Get(0)->tensors();
CV_Assert(modelTensors);
+13 -15
View File
@@ -12,17 +12,15 @@ Test for TFLite models loading
#include <opencv2/dnn/layer.details.hpp> // CV_DNN_REGISTER_LAYER_CLASS
#include <opencv2/dnn/utils/debug_utils.hpp>
namespace opencv_test
{
#ifdef OPENCV_TEST_DNN_TFLITE
namespace opencv_test { namespace {
using namespace cv;
using namespace cv::dnn;
void testModel(const std::string& modelName, const Mat& input, double norm = 1e-5) {
#ifndef HAVE_FLATBUFFERS
throw SkipTestException("FlatBuffers required for TFLite importer");
#endif
void testModel(const std::string& modelName, const Mat& input, double l1 = 1e-5, double lInf = 1e-4)
{
Net net = readNet(findDataFile("dnn/tflite/" + modelName + ".tflite", false));
net.setInput(input);
@@ -34,20 +32,21 @@ void testModel(const std::string& modelName, const Mat& input, double norm = 1e-
ASSERT_EQ(outs.size(), outNames.size());
for (int i = 0; i < outNames.size(); ++i) {
Mat ref = blobFromNPY(findDataFile(format("dnn/tflite/%s_out_%s.npy", modelName.c_str(), outNames[i].c_str())));
normAssert(ref.reshape(1, 1), outs[i].reshape(1, 1), outNames[i].c_str(), norm);
normAssert(ref.reshape(1, 1), outs[i].reshape(1, 1), outNames[i].c_str(), l1, lInf);
}
}
void testModel(const std::string& modelName, const Size& inpSize, double norm = 1e-5) {
void testModel(const std::string& modelName, const Size& inpSize, double l1 = 1e-5, double lInf = 1e-4)
{
Mat input = imread(findDataFile("cv/shared/lena.png"));
input = blobFromImage(input, 1.0 / 255, inpSize, 0, true);
testModel(modelName, input, norm);
testModel(modelName, input, l1, lInf);
}
// https://google.github.io/mediapipe/solutions/face_mesh
TEST(Test_TFLite, face_landmark)
{
testModel("face_landmark", Size(192, 192), 2e-5);
testModel("face_landmark", Size(192, 192), 2e-5, 2e-4);
}
// https://google.github.io/mediapipe/solutions/face_detection
@@ -64,9 +63,6 @@ TEST(Test_TFLite, selfie_segmentation)
TEST(Test_TFLite, max_unpooling)
{
#ifndef HAVE_FLATBUFFERS
throw SkipTestException("FlatBuffers required for TFLite importer");
#endif
// Due Max Unpoling is a numerically unstable operation and small difference between frameworks
// might lead to positional difference of maximal elements in the tensor, this test checks
// behavior of Max Unpooling layer only.
@@ -120,4 +116,6 @@ TEST(Test_TFLite, max_unpooling)
}
}
}
}} // namespace
#endif // OPENCV_TEST_DNN_TFLITE