Merge pull request #24372 from Kumataro:fix24369

Supporting protobuf v22 and later(with abseil-cpp/C++17) #24372

fix https://github.com/opencv/opencv/issues/24369
related https://github.com/opencv/opencv/issues/23791

1. This patch supports external protobuf v22 and later, it required abseil-cpp and c++17.
    Even if the built-in protobuf is upgraded to v22 or later, 
    the dependency on abseil-cpp and the requirement for C++17 will continue.
2. Some test for caffe required patched protobuf, so this patch disable them.

This patch is tested by following libraries.
-  Protobuf:                    /usr/local/lib/libprotobuf.so (4.24.4)
-  abseil-cpp:                YES (20230125)

### 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
- [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.
- [x] The feature is well documented and sample code can be built with the project CMake
pull/24427/head
Kumataro 1 year ago committed by GitHub
parent ba4d6c859d
commit 6e4280ea81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      cmake/OpenCVFindProtobuf.cmake
  2. 6
      modules/dnn/CMakeLists.txt
  3. 24
      modules/dnn/test/test_layers.cpp

@ -30,8 +30,14 @@ if(BUILD_PROTOBUF)
set(Protobuf_LIBRARIES "libprotobuf") set(Protobuf_LIBRARIES "libprotobuf")
set(HAVE_PROTOBUF TRUE) set(HAVE_PROTOBUF TRUE)
else() else()
# we still need this for command PROTOBUF_GENERATE_CPP.
set(protobuf_MODULE_COMPATIBLE ON)
unset(Protobuf_VERSION CACHE) unset(Protobuf_VERSION CACHE)
find_package(Protobuf QUIET CONFIG)
if(NOT Protobuf_FOUND)
find_package(Protobuf QUIET) find_package(Protobuf QUIET)
endif()
# Backwards compatibility # Backwards compatibility
# Define camel case versions of input variables # Define camel case versions of input variables
@ -67,6 +73,20 @@ else()
endif() endif()
endif() endif()
# See https://github.com/opencv/opencv/issues/24369
# In Protocol Buffers v22.0 and later drops C++11 support and depends abseil-cpp.
# Details: https://protobuf.dev/news/2022-08-03/
# And if std::text_view is in abseil-cpp requests C++17 and later.
if(HAVE_PROTOBUF)
if(NOT (Protobuf_VERSION VERSION_LESS 22))
if((CMAKE_CXX_STANDARD EQUAL 98) OR (CMAKE_CXX_STANDARD LESS 17))
message(STATUS "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} is too old to support protobuf(${Protobuf_VERSION}) and/or abseil-cpp. Use C++17 or later. Turning HAVE_PROTOBUF off")
set(HAVE_PROTOBUF FALSE)
endif()
endif()
endif()
if(HAVE_PROTOBUF AND PROTOBUF_UPDATE_FILES AND NOT COMMAND PROTOBUF_GENERATE_CPP) if(HAVE_PROTOBUF AND PROTOBUF_UPDATE_FILES AND NOT COMMAND PROTOBUF_GENERATE_CPP)
message(FATAL_ERROR "Can't configure protobuf dependency (BUILD_PROTOBUF=${BUILD_PROTOBUF} PROTOBUF_UPDATE_FILES=${PROTOBUF_UPDATE_FILES})") message(FATAL_ERROR "Can't configure protobuf dependency (BUILD_PROTOBUF=${BUILD_PROTOBUF} PROTOBUF_UPDATE_FILES=${PROTOBUF_UPDATE_FILES})")
endif() endif()
@ -74,17 +94,22 @@ endif()
if(HAVE_PROTOBUF) if(HAVE_PROTOBUF)
list(APPEND CUSTOM_STATUS protobuf) list(APPEND CUSTOM_STATUS protobuf)
if(NOT BUILD_PROTOBUF) if(NOT BUILD_PROTOBUF)
unset( __location)
if(TARGET "${Protobuf_LIBRARIES}") if(TARGET "${Protobuf_LIBRARIES}")
get_target_property(__location "${Protobuf_LIBRARIES}" IMPORTED_LOCATION_RELEASE) get_target_property(__location "${Protobuf_LIBRARIES}" IMPORTED_LOCATION_RELEASE)
if(NOT __location) if(NOT __location)
get_target_property(__location "${Protobuf_LIBRARIES}" IMPORTED_LOCATION) get_target_property(__location "${Protobuf_LIBRARIES}" IMPORTED_LOCATION)
endif() endif()
elseif(Protobuf_LIBRARY) endif()
if(NOT __location)
if(Protobuf_LIBRARY)
set(__location "${Protobuf_LIBRARY}") set(__location "${Protobuf_LIBRARY}")
else() else()
set(__location "${Protobuf_LIBRARIES}") set(__location "${Protobuf_LIBRARIES}")
endif() endif()
endif() endif()
endif()
list(APPEND CUSTOM_STATUS_protobuf " Protobuf:" list(APPEND CUSTOM_STATUS_protobuf " Protobuf:"
BUILD_PROTOBUF THEN "build (${Protobuf_VERSION})" BUILD_PROTOBUF THEN "build (${Protobuf_VERSION})"
ELSE "${__location} (${Protobuf_VERSION})") ELSE "${__location} (${Protobuf_VERSION})")

@ -240,6 +240,12 @@ ocv_create_module(${libs} ${dnn_runtime_libs})
ocv_add_samples() ocv_add_samples()
ocv_add_accuracy_tests(${dnn_runtime_libs}) ocv_add_accuracy_tests(${dnn_runtime_libs})
if(NOT BUILD_PROTOBUF)
if(TARGET opencv_test_dnn)
ocv_target_compile_definitions(opencv_test_dnn PRIVATE "OPENCV_DNN_EXTERNAL_PROTOBUF=1")
endif()
endif()
set(perf_path "${CMAKE_CURRENT_LIST_DIR}/perf") set(perf_path "${CMAKE_CURRENT_LIST_DIR}/perf")
file(GLOB_RECURSE perf_srcs "${perf_path}/*.cpp") file(GLOB_RECURSE perf_srcs "${perf_path}/*.cpp")
file(GLOB_RECURSE perf_hdrs "${perf_path}/*.hpp" "${perf_path}/*.h") file(GLOB_RECURSE perf_hdrs "${perf_path}/*.hpp" "${perf_path}/*.h")

@ -764,11 +764,15 @@ TEST_F(Layer_RNN_Test, get_set_test)
TEST_P(Test_Caffe_layers, Accum) TEST_P(Test_Caffe_layers, Accum)
{ {
#ifdef OPENCV_DNN_EXTERNAL_PROTOBUF
throw SkipTestException("Requires patched protobuf");
#else
if (backend == DNN_BACKEND_OPENCV && target != DNN_TARGET_CPU) if (backend == DNN_BACKEND_OPENCV && target != DNN_TARGET_CPU)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16); applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
testLayerUsingCaffeModels("accum", false, false, 0.0, 0.0, 2); testLayerUsingCaffeModels("accum", false, false, 0.0, 0.0, 2);
testLayerUsingCaffeModels("accum_ref", false, false, 0.0, 0.0, 2); testLayerUsingCaffeModels("accum_ref", false, false, 0.0, 0.0, 2);
#endif
} }
TEST_P(Test_Caffe_layers, FlowWarp) TEST_P(Test_Caffe_layers, FlowWarp)
@ -788,29 +792,41 @@ TEST_P(Test_Caffe_layers, ChannelNorm)
TEST_P(Test_Caffe_layers, DataAugmentation) TEST_P(Test_Caffe_layers, DataAugmentation)
{ {
#ifdef OPENCV_DNN_EXTERNAL_PROTOBUF
throw SkipTestException("Requires patched protobuf");
#else
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16); applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
testLayerUsingCaffeModels("data_augmentation", true, false); testLayerUsingCaffeModels("data_augmentation", true, false);
testLayerUsingCaffeModels("data_augmentation_2x1", true, false); testLayerUsingCaffeModels("data_augmentation_2x1", true, false);
testLayerUsingCaffeModels("data_augmentation_8x6", true, false); testLayerUsingCaffeModels("data_augmentation_8x6", true, false);
#endif
} }
TEST_P(Test_Caffe_layers, Resample) TEST_P(Test_Caffe_layers, Resample)
{ {
#ifdef OPENCV_DNN_EXTERNAL_PROTOBUF
throw SkipTestException("Requires patched protobuf");
#else
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2023000000) #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2023000000)
if (backend != DNN_BACKEND_OPENCV) if (backend != DNN_BACKEND_OPENCV)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
#endif #endif
testLayerUsingCaffeModels("nearest_2inps", false, false, 0.0, 0.0, 2); testLayerUsingCaffeModels("nearest_2inps", false, false, 0.0, 0.0, 2);
testLayerUsingCaffeModels("nearest", false, false); testLayerUsingCaffeModels("nearest", false, false);
#endif
} }
TEST_P(Test_Caffe_layers, Correlation) TEST_P(Test_Caffe_layers, Correlation)
{ {
#ifdef OPENCV_DNN_EXTERNAL_PROTOBUF
throw SkipTestException("Requires patched protobuf");
#else
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER,
CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16); CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
testLayerUsingCaffeModels("correlation", false, false, 0.0, 0.0, 2); testLayerUsingCaffeModels("correlation", false, false, 0.0, 0.0, 2);
#endif
} }
TEST_P(Test_Caffe_layers, Convolution2Inputs) TEST_P(Test_Caffe_layers, Convolution2Inputs)
@ -1651,12 +1667,11 @@ private:
int outWidth, outHeight, zoomFactor; int outWidth, outHeight, zoomFactor;
}; };
#ifndef OPENCV_DNN_EXTERNAL_PROTOBUF
TEST_P(Test_Caffe_layers, Interp) TEST_P(Test_Caffe_layers, Interp)
#else
TEST_P(Test_Caffe_layers, DISABLED_Interp) // requires patched protobuf (available in OpenCV source tree only)
#endif
{ {
#ifdef OPENCV_DNN_EXTERNAL_PROTOBUF
throw SkipTestException("Requires patched protobuf");
#else
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000) #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD) if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception
@ -1680,6 +1695,7 @@ TEST_P(Test_Caffe_layers, DISABLED_Interp) // requires patched protobuf (availa
// Test an implemented layer. // Test an implemented layer.
testLayerUsingCaffeModels("layer_interp", false, false); testLayerUsingCaffeModels("layer_interp", false, false);
#endif
} }
INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_Caffe_layers, dnnBackendsAndTargets()); INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_Caffe_layers, dnnBackendsAndTargets());

Loading…
Cancel
Save