From 0f1e19319365f1c753735b8e04e58461276f77fd Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Mon, 26 Feb 2018 00:16:02 +0300 Subject: [PATCH 1/9] Fixed two issues found by static analysis --- modules/dnn/src/layers/pooling_layer.cpp | 2 ++ modules/imgcodecs/src/grfmt_tiff.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/modules/dnn/src/layers/pooling_layer.cpp b/modules/dnn/src/layers/pooling_layer.cpp index 3cdc786517..1aeba3a7be 100644 --- a/modules/dnn/src/layers/pooling_layer.cpp +++ b/modules/dnn/src/layers/pooling_layer.cpp @@ -323,6 +323,8 @@ public: #if CV_SIMD128 const int* ofsptr = ofsbuf.empty() ? 0 : (const int*)&ofsbuf[0]; + if (poolingType == MAX && !compMaxIdx && !ofsptr) + CV_Error(Error::StsBadArg, "ofsbuf should be initialized in this mode"); v_float32x4 idx00(0.f, (float)stride_w, (float)(stride_w*2), (float)(stride_w*3)); v_float32x4 ones = v_setall_f32(1.f); v_float32x4 idx_delta = v_setall_f32((float)(inp_width - kernel_w)); diff --git a/modules/imgcodecs/src/grfmt_tiff.cpp b/modules/imgcodecs/src/grfmt_tiff.cpp index 372176ec40..e2aa2bd989 100644 --- a/modules/imgcodecs/src/grfmt_tiff.cpp +++ b/modules/imgcodecs/src/grfmt_tiff.cpp @@ -775,6 +775,7 @@ bool TiffEncoder::writeLibTiff( const std::vector& img_vec, const std::vect } default: { + TIFFClose(pTiffHandle); return false; } } From ca9af2017981b73903123a0de5f33c60b06e1c45 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 19 Feb 2018 17:39:30 +0300 Subject: [PATCH 2/9] OpenCV version '-cvsdk' --- modules/core/include/opencv2/core/version.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/include/opencv2/core/version.hpp b/modules/core/include/opencv2/core/version.hpp index c999a80245..3af07cd9cb 100644 --- a/modules/core/include/opencv2/core/version.hpp +++ b/modules/core/include/opencv2/core/version.hpp @@ -8,7 +8,7 @@ #define CV_VERSION_MAJOR 3 #define CV_VERSION_MINOR 4 #define CV_VERSION_REVISION 1 -#define CV_VERSION_STATUS "" +#define CV_VERSION_STATUS "-cvsdk" #define CVAUX_STR_EXP(__A) #__A #define CVAUX_STR(__A) CVAUX_STR_EXP(__A) From e969f184e11d45e7d6deb13326cda3b5d52181a7 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Tue, 27 Feb 2018 15:48:19 +0300 Subject: [PATCH 3/9] 3rdparty: fix protobuf version in README file --- 3rdparty/protobuf/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/protobuf/README.md b/3rdparty/protobuf/README.md index 6c5b6396d2..e0edb75f58 100644 --- a/3rdparty/protobuf/README.md +++ b/3rdparty/protobuf/README.md @@ -1,3 +1,3 @@ Project: Protocol Buffers - Google's data interchange format Source code: https://github.com/google/protobuf -Version: 3.1.0 +Version: 3.5.1 From 4a6d582f2ef3ddbcf16e7ad7b00359827640e8d3 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Wed, 28 Feb 2018 13:58:55 +0300 Subject: [PATCH 4/9] dnn: make OpenCL DNN code optional --- cmake/OpenCVModule.cmake | 8 ++++++-- modules/dnn/CMakeLists.txt | 19 +++++++++++++++++-- .../INIT_MODULE_SOURCES_opencv_dnn.cmake | 3 +++ modules/dnn/src/layers/batch_norm_layer.cpp | 3 +++ modules/dnn/src/layers/concat_layer.cpp | 3 +++ modules/dnn/src/layers/convolution_layer.cpp | 2 +- .../dnn/src/layers/detection_output_layer.cpp | 3 +++ modules/dnn/src/layers/elementwise_layers.cpp | 5 ++++- modules/dnn/src/layers/eltwise_layer.cpp | 3 +++ .../dnn/src/layers/fully_connected_layer.cpp | 2 +- modules/dnn/src/layers/layers_common.cpp | 1 + modules/dnn/src/layers/layers_common.hpp | 2 +- modules/dnn/src/layers/lrn_layer.cpp | 2 +- modules/dnn/src/layers/mvn_layer.cpp | 5 ++++- modules/dnn/src/layers/permute_layer.cpp | 3 +++ modules/dnn/src/layers/pooling_layer.cpp | 3 ++- modules/dnn/src/layers/prior_box_layer.cpp | 3 +++ modules/dnn/src/layers/region_layer.cpp | 3 +++ modules/dnn/src/layers/reorg_layer.cpp | 3 +++ modules/dnn/src/layers/slice_layer.cpp | 3 +++ modules/dnn/src/layers/softmax_layer.cpp | 3 ++- modules/dnn/src/ocl4dnn/include/common.hpp | 3 --- .../src/ocl4dnn/include/math_functions.hpp | 3 --- modules/dnn/src/ocl4dnn/include/ocl4dnn.hpp | 8 +++----- modules/dnn/src/ocl4dnn/src/common.cpp | 5 +---- .../dnn/src/ocl4dnn/src/math_functions.cpp | 18 ++++-------------- .../src/ocl4dnn/src/ocl4dnn_conv_spatial.cpp | 15 ++++++--------- .../src/ocl4dnn/src/ocl4dnn_inner_product.cpp | 13 +++++-------- modules/dnn/src/ocl4dnn/src/ocl4dnn_lrn.cpp | 11 ++++------- modules/dnn/src/ocl4dnn/src/ocl4dnn_pool.cpp | 11 ++++------- .../dnn/src/ocl4dnn/src/ocl4dnn_softmax.cpp | 11 ++++------- modules/dnn/src/precomp.hpp | 17 ++++++++++++++++- 32 files changed, 117 insertions(+), 80 deletions(-) create mode 100644 modules/dnn/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake diff --git a/cmake/OpenCVModule.cmake b/cmake/OpenCVModule.cmake index 3f22788745..f5beeba09a 100644 --- a/cmake/OpenCVModule.cmake +++ b/cmake/OpenCVModule.cmake @@ -747,7 +747,7 @@ endmacro() # finds and sets headers and sources for the standard OpenCV module # Usage: -# ocv_glob_module_sources([EXCLUDE_CUDA] ) +# ocv_glob_module_sources([EXCLUDE_CUDA] [EXCLUDE_OPENCL] ) macro(ocv_glob_module_sources) ocv_debug_message("ocv_glob_module_sources(" ${ARGN} ")") set(_argn ${ARGN}) @@ -755,6 +755,10 @@ macro(ocv_glob_module_sources) if(NOT exclude_cuda EQUAL -1) list(REMOVE_AT _argn ${exclude_cuda}) endif() + list(FIND _argn "EXCLUDE_OPENCL" exclude_opencl) + if(NOT exclude_opencl EQUAL -1) + list(REMOVE_AT _argn ${exclude_opencl}) + endif() file(GLOB_RECURSE lib_srcs "${CMAKE_CURRENT_LIST_DIR}/src/*.cpp" @@ -801,7 +805,7 @@ macro(ocv_glob_module_sources) file(GLOB cl_kernels "${CMAKE_CURRENT_LIST_DIR}/src/opencl/*.cl" ) - if(cl_kernels) + if(cl_kernels AND exclude_opencl EQUAL -1) set(OCL_NAME opencl_kernels_${name}) add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" # don't add .hpp file here to optimize build process diff --git a/modules/dnn/CMakeLists.txt b/modules/dnn/CMakeLists.txt index 7971046851..9f105d3453 100644 --- a/modules/dnn/CMakeLists.txt +++ b/modules/dnn/CMakeLists.txt @@ -11,6 +11,14 @@ set(the_description "Deep neural network module. It allows to load models from d ocv_add_dispatched_file_force_all("layers/layers_common" AVX AVX2 AVX512_SKX) ocv_add_module(dnn opencv_core opencv_imgproc WRAP python matlab java js) + +ocv_option(OPENCV_DNN_OPENCL "Build with OpenCL support" HAVE_OPENCL) +if(OPENCV_DNN_OPENCL AND HAVE_OPENCL) + add_definitions(-DCV_OCL4DNN=1) +else() + ocv_cmake_hook_append(INIT_MODULE_SOURCES_opencv_dnn "${CMAKE_CURRENT_LIST_DIR}/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake") +endif() + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-shadow -Wno-parentheses -Wmaybe-uninitialized -Wsign-promo -Wmissing-declarations -Wmissing-prototypes ) @@ -63,8 +71,15 @@ else() set(fw_inc "${CMAKE_CURRENT_LIST_DIR}/misc/caffe" "${CMAKE_CURRENT_LIST_DIR}/misc/tensorflow") endif() -ocv_module_include_directories(${fw_inc} ${CMAKE_CURRENT_LIST_DIR}/src/ocl4dnn/include ${OPENCL_INCLUDE_DIRS}) -ocv_glob_module_sources(SOURCES ${fw_srcs}) +set(include_dirs ${fw_inc}) +set(sources_options "") +if(OPENCV_DNN_OPENCL AND HAVE_OPENCL) + list(APPEND include_dirs ${OPENCL_INCLUDE_DIRS}) +else() + set(sources_options EXCLUDE_OPENCL) +endif() +ocv_module_include_directories(${include_dirs}) +ocv_glob_module_sources(${sources_options} SOURCES ${fw_srcs}) ocv_create_module(libprotobuf ${LAPACK_LIBRARIES}) ocv_add_samples() ocv_add_accuracy_tests() diff --git a/modules/dnn/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake b/modules/dnn/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake new file mode 100644 index 0000000000..f19002d13a --- /dev/null +++ b/modules/dnn/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake @@ -0,0 +1,3 @@ +message(STATUS "opencv_dnn: filter out ocl4dnn source code") +ocv_list_filterout(OPENCV_MODULE_${the_module}_SOURCES "/ocl4dnn/") +ocv_list_filterout(OPENCV_MODULE_${the_module}_HEADERS "/ocl4dnn/") diff --git a/modules/dnn/src/layers/batch_norm_layer.cpp b/modules/dnn/src/layers/batch_norm_layer.cpp index cab9bb7b60..ef8735aa21 100644 --- a/modules/dnn/src/layers/batch_norm_layer.cpp +++ b/modules/dnn/src/layers/batch_norm_layer.cpp @@ -13,7 +13,10 @@ Implementation of Batch Normalization layer. #include "op_halide.hpp" #include "op_inf_engine.hpp" #include + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/concat_layer.cpp b/modules/dnn/src/layers/concat_layer.cpp index 63b722ee9a..f9c4494b47 100644 --- a/modules/dnn/src/layers/concat_layer.cpp +++ b/modules/dnn/src/layers/concat_layer.cpp @@ -44,7 +44,10 @@ #include "layers_common.hpp" #include "op_halide.hpp" #include "op_inf_engine.hpp" + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/convolution_layer.cpp b/modules/dnn/src/layers/convolution_layer.cpp index 40681c963f..79a833ba15 100644 --- a/modules/dnn/src/layers/convolution_layer.cpp +++ b/modules/dnn/src/layers/convolution_layer.cpp @@ -47,9 +47,9 @@ #include "opencv2/core/hal/hal.hpp" #include "opencv2/core/hal/intrin.hpp" #include -#include "opencl_kernels_dnn.hpp" #ifdef HAVE_OPENCL +#include "opencl_kernels_dnn.hpp" using namespace cv::dnn::ocl4dnn; #endif diff --git a/modules/dnn/src/layers/detection_output_layer.cpp b/modules/dnn/src/layers/detection_output_layer.cpp index 70d7dfb0b1..712d542ed7 100644 --- a/modules/dnn/src/layers/detection_output_layer.cpp +++ b/modules/dnn/src/layers/detection_output_layer.cpp @@ -46,7 +46,10 @@ #include #include #include "../nms.inl.hpp" + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/elementwise_layers.cpp b/modules/dnn/src/layers/elementwise_layers.cpp index adf51c8942..7394f2ed70 100644 --- a/modules/dnn/src/layers/elementwise_layers.cpp +++ b/modules/dnn/src/layers/elementwise_layers.cpp @@ -46,9 +46,12 @@ #include "op_inf_engine.hpp" #include "opencv2/imgproc.hpp" #include -#include "opencl_kernels_dnn.hpp" #include +#ifdef HAVE_OPENCL +#include "opencl_kernels_dnn.hpp" +#endif + namespace cv { namespace dnn diff --git a/modules/dnn/src/layers/eltwise_layer.cpp b/modules/dnn/src/layers/eltwise_layer.cpp index 0e09202909..65238318be 100644 --- a/modules/dnn/src/layers/eltwise_layer.cpp +++ b/modules/dnn/src/layers/eltwise_layer.cpp @@ -44,7 +44,10 @@ #include "layers_common.hpp" #include "op_halide.hpp" #include "op_inf_engine.hpp" + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/fully_connected_layer.cpp b/modules/dnn/src/layers/fully_connected_layer.cpp index ccc8dec96a..174421e37b 100644 --- a/modules/dnn/src/layers/fully_connected_layer.cpp +++ b/modules/dnn/src/layers/fully_connected_layer.cpp @@ -44,10 +44,10 @@ #include "layers_common.hpp" #include "op_halide.hpp" #include "op_inf_engine.hpp" -#include "opencl_kernels_dnn.hpp" #include #ifdef HAVE_OPENCL +#include "opencl_kernels_dnn.hpp" using namespace cv::dnn::ocl4dnn; #endif diff --git a/modules/dnn/src/layers/layers_common.cpp b/modules/dnn/src/layers/layers_common.cpp index 8552a4a0cc..f854d91ccc 100644 --- a/modules/dnn/src/layers/layers_common.cpp +++ b/modules/dnn/src/layers/layers_common.cpp @@ -40,6 +40,7 @@ // //M*/ +#include "../precomp.hpp" #include "layers_common.hpp" namespace cv diff --git a/modules/dnn/src/layers/layers_common.hpp b/modules/dnn/src/layers/layers_common.hpp index ed8add94ff..97902138b1 100644 --- a/modules/dnn/src/layers/layers_common.hpp +++ b/modules/dnn/src/layers/layers_common.hpp @@ -52,7 +52,7 @@ #undef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY #ifdef HAVE_OPENCL -#include "ocl4dnn.hpp" +#include "../ocl4dnn/include/ocl4dnn.hpp" #endif namespace cv diff --git a/modules/dnn/src/layers/lrn_layer.cpp b/modules/dnn/src/layers/lrn_layer.cpp index a01d5f0a8d..1011cb66f2 100644 --- a/modules/dnn/src/layers/lrn_layer.cpp +++ b/modules/dnn/src/layers/lrn_layer.cpp @@ -47,10 +47,10 @@ #include "opencv2/imgproc.hpp" #include "opencv2/dnn/shape_utils.hpp" #include "opencv2/core/hal/hal.hpp" -#include "opencl_kernels_dnn.hpp" #include #ifdef HAVE_OPENCL +#include "opencl_kernels_dnn.hpp" using namespace cv::dnn::ocl4dnn; #endif diff --git a/modules/dnn/src/layers/mvn_layer.cpp b/modules/dnn/src/layers/mvn_layer.cpp index be44435386..09993a3c04 100644 --- a/modules/dnn/src/layers/mvn_layer.cpp +++ b/modules/dnn/src/layers/mvn_layer.cpp @@ -43,8 +43,11 @@ #include "../precomp.hpp" #include "layers_common.hpp" #include -#include "math_functions.hpp" + +#ifdef HAVE_OPENCL +#include "../ocl4dnn/include/math_functions.hpp" #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/permute_layer.cpp b/modules/dnn/src/layers/permute_layer.cpp index bdc47fb737..b98365848f 100644 --- a/modules/dnn/src/layers/permute_layer.cpp +++ b/modules/dnn/src/layers/permute_layer.cpp @@ -45,7 +45,10 @@ #include "op_inf_engine.hpp" #include #include + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/pooling_layer.cpp b/modules/dnn/src/layers/pooling_layer.cpp index 1aeba3a7be..9918cad91f 100644 --- a/modules/dnn/src/layers/pooling_layer.cpp +++ b/modules/dnn/src/layers/pooling_layer.cpp @@ -45,12 +45,13 @@ #include "opencv2/core/hal/intrin.hpp" #include "op_halide.hpp" #include "op_inf_engine.hpp" -#include "opencl_kernels_dnn.hpp" #include #include using std::max; using std::min; + #ifdef HAVE_OPENCL +#include "opencl_kernels_dnn.hpp" using namespace cv::dnn::ocl4dnn; #endif diff --git a/modules/dnn/src/layers/prior_box_layer.cpp b/modules/dnn/src/layers/prior_box_layer.cpp index 848e1921be..d8ea5b6042 100644 --- a/modules/dnn/src/layers/prior_box_layer.cpp +++ b/modules/dnn/src/layers/prior_box_layer.cpp @@ -46,7 +46,10 @@ #include #include #include + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/region_layer.cpp b/modules/dnn/src/layers/region_layer.cpp index 688cb90218..3f9ba1fc0c 100644 --- a/modules/dnn/src/layers/region_layer.cpp +++ b/modules/dnn/src/layers/region_layer.cpp @@ -44,7 +44,10 @@ #include #include #include "nms.inl.hpp" + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/reorg_layer.cpp b/modules/dnn/src/layers/reorg_layer.cpp index 51da9fd12e..b5e1149497 100644 --- a/modules/dnn/src/layers/reorg_layer.cpp +++ b/modules/dnn/src/layers/reorg_layer.cpp @@ -44,7 +44,10 @@ #include #include #include + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/slice_layer.cpp b/modules/dnn/src/layers/slice_layer.cpp index 2d8b4dc777..728d571dce 100644 --- a/modules/dnn/src/layers/slice_layer.cpp +++ b/modules/dnn/src/layers/slice_layer.cpp @@ -43,7 +43,10 @@ #include "../precomp.hpp" #include "layers_common.hpp" #include + +#ifdef HAVE_OPENCL #include "opencl_kernels_dnn.hpp" +#endif namespace cv { diff --git a/modules/dnn/src/layers/softmax_layer.cpp b/modules/dnn/src/layers/softmax_layer.cpp index 49807cd8ac..55ae3addb7 100644 --- a/modules/dnn/src/layers/softmax_layer.cpp +++ b/modules/dnn/src/layers/softmax_layer.cpp @@ -44,11 +44,12 @@ #include "layers_common.hpp" #include "op_halide.hpp" #include "op_inf_engine.hpp" -#include "opencl_kernels_dnn.hpp" #include #include using std::max; + #ifdef HAVE_OPENCL +#include "opencl_kernels_dnn.hpp" using namespace cv::dnn::ocl4dnn; #endif diff --git a/modules/dnn/src/ocl4dnn/include/common.hpp b/modules/dnn/src/ocl4dnn/include/common.hpp index 41466429b0..1cc1d7d5e8 100644 --- a/modules/dnn/src/ocl4dnn/include/common.hpp +++ b/modules/dnn/src/ocl4dnn/include/common.hpp @@ -45,8 +45,6 @@ #include "../../caffe/glog_emulator.hpp" #include -#ifdef HAVE_OPENCL - // Macro to select the single (_float) or double (_double) precision kernel #define CL_KERNEL_SELECT(kernel) kernel "_float" @@ -58,5 +56,4 @@ bool clOptionSupport(cv::String option); -#endif // HAVE_OPENCL #endif diff --git a/modules/dnn/src/ocl4dnn/include/math_functions.hpp b/modules/dnn/src/ocl4dnn/include/math_functions.hpp index cac860490f..241f515752 100644 --- a/modules/dnn/src/ocl4dnn/include/math_functions.hpp +++ b/modules/dnn/src/ocl4dnn/include/math_functions.hpp @@ -52,7 +52,6 @@ namespace dnn namespace ocl4dnn { -#ifdef HAVE_OPENCL enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113}; template @@ -81,8 +80,6 @@ bool ocl4dnnAXPY(const int32_t N, const Dtype alpha, const UMat x, const int32_t offx, UMat y, const int32_t offy); -#endif // HAVE_OPENCL - } // namespace ocl4dnn } // namespace dnn } // namespce cv diff --git a/modules/dnn/src/ocl4dnn/include/ocl4dnn.hpp b/modules/dnn/src/ocl4dnn/include/ocl4dnn.hpp index 70ced11276..e4cf304ca9 100644 --- a/modules/dnn/src/ocl4dnn/include/ocl4dnn.hpp +++ b/modules/dnn/src/ocl4dnn/include/ocl4dnn.hpp @@ -51,7 +51,6 @@ #include "common.hpp" namespace cv { namespace dnn { namespace ocl4dnn { -#ifdef HAVE_OPENCL struct OCL4DNNConvConfig { @@ -507,8 +506,7 @@ class OCL4DNNSoftmax bool log_softmax_; UMat scale_data_; }; -#endif // HAVE_OPENCL -} // namespace ocl4dnn -} // namespace dnn -} // namespce cv + +}}} // namespace cv::dnn::ocl4dnn + #endif diff --git a/modules/dnn/src/ocl4dnn/src/common.cpp b/modules/dnn/src/ocl4dnn/src/common.cpp index 5a18c41110..7ca196b355 100644 --- a/modules/dnn/src/ocl4dnn/src/common.cpp +++ b/modules/dnn/src/ocl4dnn/src/common.cpp @@ -41,17 +41,14 @@ //M*/ #include "../../precomp.hpp" -#include "common.hpp" +#include "../include/common.hpp" #include "opencl_kernels_dnn.hpp" using namespace cv; -#ifdef HAVE_OPENCL bool clOptionSupport(cv::String option) { cv::String errmsg; ocl::Program program = ocl::Context::getDefault().getProg(ocl::dnn::dummy_oclsrc, option, errmsg); return program.ptr() ? true : false; } - -#endif // HAVE_OPENCL diff --git a/modules/dnn/src/ocl4dnn/src/math_functions.cpp b/modules/dnn/src/ocl4dnn/src/math_functions.cpp index 05cfd509b9..3f4a70bc03 100644 --- a/modules/dnn/src/ocl4dnn/src/math_functions.cpp +++ b/modules/dnn/src/ocl4dnn/src/math_functions.cpp @@ -41,19 +41,13 @@ //M*/ #include "../../precomp.hpp" -#include "common.hpp" -#include "math_functions.hpp" +#include "../include/common.hpp" +#include "../include/math_functions.hpp" #include #include "opencl_kernels_dnn.hpp" -namespace cv -{ -namespace dnn -{ -namespace ocl4dnn -{ +namespace cv { namespace dnn { namespace ocl4dnn { -#ifdef HAVE_OPENCL // Create and copy buffer to image for GEMM's matrix A and B. // Will return image to caller if the input image is NULL. Otherwise, // will use the image directly. It's caller's responsibility to @@ -527,8 +521,4 @@ template bool ocl4dnnAXPY(const int32_t N, const float alpha, const UMat X, const int32_t offX, UMat Y, const int32_t offY); -#endif // HAVE_OPENCL - -} // namespace ocl4dnn -} // namespace dnn -} // namespce cv +}}} // namespace cv::dnn::ocl4dnn diff --git a/modules/dnn/src/ocl4dnn/src/ocl4dnn_conv_spatial.cpp b/modules/dnn/src/ocl4dnn/src/ocl4dnn_conv_spatial.cpp index 84ea1914dc..c58545f50f 100644 --- a/modules/dnn/src/ocl4dnn/src/ocl4dnn_conv_spatial.cpp +++ b/modules/dnn/src/ocl4dnn/src/ocl4dnn_conv_spatial.cpp @@ -49,18 +49,17 @@ #include #include #include -#include "common.hpp" -#include "ocl4dnn.hpp" +#include "../include/common.hpp" +#include "../include/ocl4dnn.hpp" #include "opencl_kernels_dnn.hpp" -#include "math_functions.hpp" -#include "default_kernel_config.hpp" +#include "../include/math_functions.hpp" +#include "../include/default_kernel_config.hpp" #if defined WIN32 || defined _WIN32 #include #include #endif -#ifdef HAVE_OPENCL namespace cv { namespace dnn { namespace ocl4dnn { static cv::Mutex kernelConfigMutex; typedef std::map kernel_hash_t; @@ -1855,7 +1854,5 @@ bool OCL4DNNConvSpatial::loadTunedConfig() } template class OCL4DNNConvSpatial; -} // namespace ocl4dnn -} -} -#endif // HAVE_OPENCL + +}}} // namespace cv::dnn::ocl4dnn diff --git a/modules/dnn/src/ocl4dnn/src/ocl4dnn_inner_product.cpp b/modules/dnn/src/ocl4dnn/src/ocl4dnn_inner_product.cpp index b6c1df9908..aabee57984 100644 --- a/modules/dnn/src/ocl4dnn/src/ocl4dnn_inner_product.cpp +++ b/modules/dnn/src/ocl4dnn/src/ocl4dnn_inner_product.cpp @@ -41,11 +41,10 @@ //M*/ #include "../../precomp.hpp" -#include "common.hpp" -#include "ocl4dnn.hpp" -#include "math_functions.hpp" +#include "../include/common.hpp" +#include "../include/ocl4dnn.hpp" +#include "../include/math_functions.hpp" -#ifdef HAVE_OPENCL namespace cv { namespace dnn { namespace ocl4dnn { template OCL4DNNInnerProduct::OCL4DNNInnerProduct(OCL4DNNInnerProductConfig config) @@ -102,7 +101,5 @@ bool OCL4DNNInnerProduct::Forward(const UMat& bottom, } template class OCL4DNNInnerProduct; -} // namespace ocl4dnn -} -} -#endif // HAVE_OPENCL + +}}} // namespace cv::dnn::ocl4dnn diff --git a/modules/dnn/src/ocl4dnn/src/ocl4dnn_lrn.cpp b/modules/dnn/src/ocl4dnn/src/ocl4dnn_lrn.cpp index 476d05287f..c7062f4090 100644 --- a/modules/dnn/src/ocl4dnn/src/ocl4dnn_lrn.cpp +++ b/modules/dnn/src/ocl4dnn/src/ocl4dnn_lrn.cpp @@ -41,11 +41,10 @@ //M*/ #include "../../precomp.hpp" -#include "common.hpp" -#include "ocl4dnn.hpp" +#include "../include/common.hpp" +#include "../include/ocl4dnn.hpp" #include "opencl_kernels_dnn.hpp" -#ifdef HAVE_OPENCL namespace cv { namespace dnn { namespace ocl4dnn { template OCL4DNNLRN::OCL4DNNLRN(OCL4DNNLRNConfig config) @@ -119,7 +118,5 @@ bool OCL4DNNLRN::crossChannelForward(const UMat& bottom, UMat& top) } template class OCL4DNNLRN; -} // namespace ocl4dnn -} -} -#endif // HAVE_OPENCL + +}}} // namespace cv::dnn::ocl4dnn diff --git a/modules/dnn/src/ocl4dnn/src/ocl4dnn_pool.cpp b/modules/dnn/src/ocl4dnn/src/ocl4dnn_pool.cpp index 4d4ea9e2a9..2d9c4dcf77 100644 --- a/modules/dnn/src/ocl4dnn/src/ocl4dnn_pool.cpp +++ b/modules/dnn/src/ocl4dnn/src/ocl4dnn_pool.cpp @@ -42,11 +42,10 @@ #include "../../precomp.hpp" #include #include -#include "common.hpp" -#include "ocl4dnn.hpp" +#include "../include/common.hpp" +#include "../include/ocl4dnn.hpp" #include "opencl_kernels_dnn.hpp" -#ifdef HAVE_OPENCL namespace cv { namespace dnn { namespace ocl4dnn { template OCL4DNNPool::OCL4DNNPool(OCL4DNNPoolConfig config) @@ -208,7 +207,5 @@ bool OCL4DNNPool::Forward(const UMat& bottom, } template class OCL4DNNPool; -} // namespace ocl4dnn -} -} -#endif // HAVE_OPENCL + +}}} // namespace cv::dnn::ocl4dnn diff --git a/modules/dnn/src/ocl4dnn/src/ocl4dnn_softmax.cpp b/modules/dnn/src/ocl4dnn/src/ocl4dnn_softmax.cpp index f2452ff654..6b957649e8 100644 --- a/modules/dnn/src/ocl4dnn/src/ocl4dnn_softmax.cpp +++ b/modules/dnn/src/ocl4dnn/src/ocl4dnn_softmax.cpp @@ -41,11 +41,10 @@ #include "../../precomp.hpp" #include -#include "common.hpp" -#include "ocl4dnn.hpp" +#include "../include/common.hpp" +#include "../include/ocl4dnn.hpp" #include "opencl_kernels_dnn.hpp" -#ifdef HAVE_OPENCL namespace cv { namespace dnn { namespace ocl4dnn { template OCL4DNNSoftmax::OCL4DNNSoftmax(OCL4DNNSoftmaxConfig config) @@ -130,7 +129,5 @@ bool OCL4DNNSoftmax::Forward(const UMat& bottom, UMat& top) } template class OCL4DNNSoftmax; -} // namespace ocl4dnn -} -} -#endif // HAVE_OPENCL + +}}} // namespace cv::dnn::ocl4dnn diff --git a/modules/dnn/src/precomp.hpp b/modules/dnn/src/precomp.hpp index 8b5a31c1c4..356eaff165 100644 --- a/modules/dnn/src/precomp.hpp +++ b/modules/dnn/src/precomp.hpp @@ -40,13 +40,28 @@ //M*/ #include +#include "cvconfig.h" + +#ifndef CV_OCL4DNN +#define CV_OCL4DNN 0 +#endif + +#if CV_OCL4DNN +#ifndef HAVE_OPENCL +#error "Configuration error: re-run CMake from clean build directory" +#endif +#else +#undef HAVE_OPENCL +#endif #include #include + + #include -#include "cvconfig.h" #include #include + namespace cv { namespace dnn { CV__DNN_EXPERIMENTAL_NS_BEGIN Mutex& getInitializationMutex(); From e79be78ef4ed1e284f84e1d14c8cee4d46b230e2 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Wed, 28 Feb 2018 15:22:20 +0300 Subject: [PATCH 5/9] dnn(workaround): switch to CPU target if compiled without OpenCL --- modules/dnn/src/dnn.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp index 194648c6ea..15755f73e9 100644 --- a/modules/dnn/src/dnn.cpp +++ b/modules/dnn/src/dnn.cpp @@ -53,6 +53,7 @@ #include #include +#include namespace cv { namespace dnn { @@ -846,6 +847,13 @@ struct Net::Impl if (!netWasAllocated || this->blobsToKeep != blobsToKeep_) { +#ifndef HAVE_OPENCL + if (preferableBackend == DNN_BACKEND_DEFAULT && preferableTarget == DNN_TARGET_OPENCL) + { + CV_LOG_WARNING(NULL, "DNN: OpenCL target is not available in this OpenCV build, switching to CPU.") + preferableTarget = DNN_TARGET_CPU; + } +#endif clear(); allocateLayers(blobsToKeep_); From ed962799202d0d3b02bcbf6f5b64db31eae09493 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 1 Mar 2018 13:52:43 +0300 Subject: [PATCH 6/9] ocl: update getOpenCLErrorString() code --- modules/core/src/ocl.cpp | 163 ++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 88 deletions(-) diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index 5bbed96749..e17464e3cb 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -6015,98 +6015,85 @@ const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf) const char* getOpenCLErrorString(int errorCode) { +#define CV_OCL_CODE(id) case id: return #id +#define CV_OCL_CODE_(id, name) case id: return #name switch (errorCode) { - case 0: return "CL_SUCCESS"; - case -1: return "CL_DEVICE_NOT_FOUND"; - case -2: return "CL_DEVICE_NOT_AVAILABLE"; - case -3: return "CL_COMPILER_NOT_AVAILABLE"; - case -4: return "CL_MEM_OBJECT_ALLOCATION_FAILURE"; - case -5: return "CL_OUT_OF_RESOURCES"; - case -6: return "CL_OUT_OF_HOST_MEMORY"; - case -7: return "CL_PROFILING_INFO_NOT_AVAILABLE"; - case -8: return "CL_MEM_COPY_OVERLAP"; - case -9: return "CL_IMAGE_FORMAT_MISMATCH"; - case -10: return "CL_IMAGE_FORMAT_NOT_SUPPORTED"; - case -11: return "CL_BUILD_PROGRAM_FAILURE"; - case -12: return "CL_MAP_FAILURE"; - case -13: return "CL_MISALIGNED_SUB_BUFFER_OFFSET"; - case -14: return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST"; - case -15: return "CL_COMPILE_PROGRAM_FAILURE"; - case -16: return "CL_LINKER_NOT_AVAILABLE"; - case -17: return "CL_LINK_PROGRAM_FAILURE"; - case -18: return "CL_DEVICE_PARTITION_FAILED"; - case -19: return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE"; - case -30: return "CL_INVALID_VALUE"; - case -31: return "CL_INVALID_DEVICE_TYPE"; - case -32: return "CL_INVALID_PLATFORM"; - case -33: return "CL_INVALID_DEVICE"; - case -34: return "CL_INVALID_CONTEXT"; - case -35: return "CL_INVALID_QUEUE_PROPERTIES"; - case -36: return "CL_INVALID_COMMAND_QUEUE"; - case -37: return "CL_INVALID_HOST_PTR"; - case -38: return "CL_INVALID_MEM_OBJECT"; - case -39: return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"; - case -40: return "CL_INVALID_IMAGE_SIZE"; - case -41: return "CL_INVALID_SAMPLER"; - case -42: return "CL_INVALID_BINARY"; - case -43: return "CL_INVALID_BUILD_OPTIONS"; - case -44: return "CL_INVALID_PROGRAM"; - case -45: return "CL_INVALID_PROGRAM_EXECUTABLE"; - case -46: return "CL_INVALID_KERNEL_NAME"; - case -47: return "CL_INVALID_KERNEL_DEFINITION"; - case -48: return "CL_INVALID_KERNEL"; - case -49: return "CL_INVALID_ARG_INDEX"; - case -50: return "CL_INVALID_ARG_VALUE"; - case -51: return "CL_INVALID_ARG_SIZE"; - case -52: return "CL_INVALID_KERNEL_ARGS"; - case -53: return "CL_INVALID_WORK_DIMENSION"; - case -54: return "CL_INVALID_WORK_GROUP_SIZE"; - case -55: return "CL_INVALID_WORK_ITEM_SIZE"; - case -56: return "CL_INVALID_GLOBAL_OFFSET"; - case -57: return "CL_INVALID_EVENT_WAIT_LIST"; - case -58: return "CL_INVALID_EVENT"; - case -59: return "CL_INVALID_OPERATION"; - case -60: return "CL_INVALID_GL_OBJECT"; - case -61: return "CL_INVALID_BUFFER_SIZE"; - case -62: return "CL_INVALID_MIP_LEVEL"; - case -63: return "CL_INVALID_GLOBAL_WORK_SIZE"; - case -64: return "CL_INVALID_PROPERTY"; - case -65: return "CL_INVALID_IMAGE_DESCRIPTOR"; - case -66: return "CL_INVALID_COMPILER_OPTIONS"; - case -67: return "CL_INVALID_LINKER_OPTIONS"; - case -68: return "CL_INVALID_DEVICE_PARTITION_COUNT"; - case -69: return "CL_INVALID_PIPE_SIZE"; - case -70: return "CL_INVALID_DEVICE_QUEUE"; - case -1000: return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR"; - case -1001: return "CL_PLATFORM_NOT_FOUND_KHR"; - case -1002: return "CL_INVALID_D3D10_DEVICE_KHR"; - case -1003: return "CL_INVALID_D3D10_RESOURCE_KHR"; - case -1004: return "CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR"; - case -1005: return "CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR"; - case -1024: return "clBLAS: Functionality is not implemented"; - case -1023: return "clBLAS: Library is not initialized yet"; - case -1022: return "clBLAS: Matrix A is not a valid memory object"; - case -1021: return "clBLAS: Matrix B is not a valid memory object"; - case -1020: return "clBLAS: Matrix C is not a valid memory object"; - case -1019: return "clBLAS: Vector X is not a valid memory object"; - case -1018: return "clBLAS: Vector Y is not a valid memory object"; - case -1017: return "clBLAS: An input dimension (M:N:K) is invalid"; - case -1016: return "clBLAS: Leading dimension A must not be less than the " - "size of the first dimension"; - case -1015: return "clBLAS: Leading dimension B must not be less than the " - "size of the second dimension"; - case -1014: return "clBLAS: Leading dimension C must not be less than the " - "size of the third dimension"; - case -1013: return "clBLAS: The increment for a vector X must not be 0"; - case -1012: return "clBLAS: The increment for a vector Y must not be 0"; - case -1011: return "clBLAS: The memory object for Matrix A is too small"; - case -1010: return "clBLAS: The memory object for Matrix B is too small"; - case -1009: return "clBLAS: The memory object for Matrix C is too small"; - case -1008: return "clBLAS: The memory object for Vector X is too small"; - case -1007: return "clBLAS: The memory object for Vector Y is too small"; + CV_OCL_CODE(CL_SUCCESS); + CV_OCL_CODE(CL_DEVICE_NOT_FOUND); + CV_OCL_CODE(CL_DEVICE_NOT_AVAILABLE); + CV_OCL_CODE(CL_COMPILER_NOT_AVAILABLE); + CV_OCL_CODE(CL_MEM_OBJECT_ALLOCATION_FAILURE); + CV_OCL_CODE(CL_OUT_OF_RESOURCES); + CV_OCL_CODE(CL_OUT_OF_HOST_MEMORY); + CV_OCL_CODE(CL_PROFILING_INFO_NOT_AVAILABLE); + CV_OCL_CODE(CL_MEM_COPY_OVERLAP); + CV_OCL_CODE(CL_IMAGE_FORMAT_MISMATCH); + CV_OCL_CODE(CL_IMAGE_FORMAT_NOT_SUPPORTED); + CV_OCL_CODE(CL_BUILD_PROGRAM_FAILURE); + CV_OCL_CODE(CL_MAP_FAILURE); + CV_OCL_CODE(CL_MISALIGNED_SUB_BUFFER_OFFSET); + CV_OCL_CODE(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); + CV_OCL_CODE(CL_COMPILE_PROGRAM_FAILURE); + CV_OCL_CODE(CL_LINKER_NOT_AVAILABLE); + CV_OCL_CODE(CL_LINK_PROGRAM_FAILURE); + CV_OCL_CODE(CL_DEVICE_PARTITION_FAILED); + CV_OCL_CODE(CL_KERNEL_ARG_INFO_NOT_AVAILABLE); + CV_OCL_CODE(CL_INVALID_VALUE); + CV_OCL_CODE(CL_INVALID_DEVICE_TYPE); + CV_OCL_CODE(CL_INVALID_PLATFORM); + CV_OCL_CODE(CL_INVALID_DEVICE); + CV_OCL_CODE(CL_INVALID_CONTEXT); + CV_OCL_CODE(CL_INVALID_QUEUE_PROPERTIES); + CV_OCL_CODE(CL_INVALID_COMMAND_QUEUE); + CV_OCL_CODE(CL_INVALID_HOST_PTR); + CV_OCL_CODE(CL_INVALID_MEM_OBJECT); + CV_OCL_CODE(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); + CV_OCL_CODE(CL_INVALID_IMAGE_SIZE); + CV_OCL_CODE(CL_INVALID_SAMPLER); + CV_OCL_CODE(CL_INVALID_BINARY); + CV_OCL_CODE(CL_INVALID_BUILD_OPTIONS); + CV_OCL_CODE(CL_INVALID_PROGRAM); + CV_OCL_CODE(CL_INVALID_PROGRAM_EXECUTABLE); + CV_OCL_CODE(CL_INVALID_KERNEL_NAME); + CV_OCL_CODE(CL_INVALID_KERNEL_DEFINITION); + CV_OCL_CODE(CL_INVALID_KERNEL); + CV_OCL_CODE(CL_INVALID_ARG_INDEX); + CV_OCL_CODE(CL_INVALID_ARG_VALUE); + CV_OCL_CODE(CL_INVALID_ARG_SIZE); + CV_OCL_CODE(CL_INVALID_KERNEL_ARGS); + CV_OCL_CODE(CL_INVALID_WORK_DIMENSION); + CV_OCL_CODE(CL_INVALID_WORK_GROUP_SIZE); + CV_OCL_CODE(CL_INVALID_WORK_ITEM_SIZE); + CV_OCL_CODE(CL_INVALID_GLOBAL_OFFSET); + CV_OCL_CODE(CL_INVALID_EVENT_WAIT_LIST); + CV_OCL_CODE(CL_INVALID_EVENT); + CV_OCL_CODE(CL_INVALID_OPERATION); + CV_OCL_CODE(CL_INVALID_GL_OBJECT); + CV_OCL_CODE(CL_INVALID_BUFFER_SIZE); + CV_OCL_CODE(CL_INVALID_MIP_LEVEL); + CV_OCL_CODE(CL_INVALID_GLOBAL_WORK_SIZE); + // OpenCL 1.1 + CV_OCL_CODE(CL_INVALID_PROPERTY); + // OpenCL 1.2 + CV_OCL_CODE(CL_INVALID_IMAGE_DESCRIPTOR); + CV_OCL_CODE(CL_INVALID_COMPILER_OPTIONS); + CV_OCL_CODE(CL_INVALID_LINKER_OPTIONS); + CV_OCL_CODE(CL_INVALID_DEVICE_PARTITION_COUNT); + // OpenCL 2.0 + CV_OCL_CODE_(-69, CL_INVALID_PIPE_SIZE); + CV_OCL_CODE_(-70, CL_INVALID_DEVICE_QUEUE); + // Extensions + CV_OCL_CODE_(-1000, CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR); + CV_OCL_CODE_(-1001, CL_PLATFORM_NOT_FOUND_KHR); + CV_OCL_CODE_(-1002, CL_INVALID_D3D10_DEVICE_KHR); + CV_OCL_CODE_(-1003, CL_INVALID_D3D10_RESOURCE_KHR); + CV_OCL_CODE_(-1004, CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR); + CV_OCL_CODE_(-1005, CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR); default: return "Unknown OpenCL error"; } +#undef CV_OCL_CODE +#undef CV_OCL_CODE_ } template From e283a75a19b1593b4e8fa82b93d5af03a2c69427 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Mon, 19 Feb 2018 18:53:17 +0300 Subject: [PATCH 7/9] Minor refactoring in several C++ samples: - bgfg_segm - peopledetect - opencv_version - dnn/colorization - tapi/opencl_custom_kernel - tapi/dense_optical_flow (renamed tvl1_optical_flow) --- samples/cpp/bgfg_segm.cpp | 20 ++- samples/cpp/opencv_version.cpp | 14 +- samples/cpp/peopledetect.cpp | 213 +++++++++-------------- samples/dnn/colorization.cpp | 95 ++++++----- samples/tapi/dense_optical_flow.cpp | 151 +++++++++++++++++ samples/tapi/opencl_custom_kernel.cpp | 4 + samples/tapi/tvl1_optical_flow.cpp | 233 -------------------------- 7 files changed, 304 insertions(+), 426 deletions(-) create mode 100644 samples/tapi/dense_optical_flow.cpp delete mode 100644 samples/tapi/tvl1_optical_flow.cpp diff --git a/samples/cpp/bgfg_segm.cpp b/samples/cpp/bgfg_segm.cpp index 71473d124a..9fc2780b07 100644 --- a/samples/cpp/bgfg_segm.cpp +++ b/samples/cpp/bgfg_segm.cpp @@ -1,3 +1,7 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + #include "opencv2/core.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/video.hpp" @@ -10,10 +14,10 @@ using namespace cv; int main(int argc, const char** argv) { - const String keys = "{c camera||use video stream from camera (default is NO)}" - "{fn file_name|../data/tree.avi|video file}" - "{m method|mog2|method: background subtraction algorithm ('knn', 'mog2')}" - "{h help||show help message}"; + const String keys = "{c camera | 0 | use video stream from camera (device index starting from 0) }" + "{fn file_name | | use video file as input }" + "{m method | mog2 | method: background subtraction algorithm ('knn', 'mog2')}" + "{h help | | show help message}"; CommandLineParser parser(argc, argv, keys); parser.about("This sample demonstrates background segmentation."); if (parser.has("help")) @@ -21,7 +25,7 @@ int main(int argc, const char** argv) parser.printMessage(); return 0; } - bool useCamera = parser.has("camera"); + int camera = parser.get("camera"); String file = parser.get("file_name"); String method = parser.get("method"); if (!parser.check()) @@ -31,13 +35,13 @@ int main(int argc, const char** argv) } VideoCapture cap; - if (useCamera) - cap.open(0); + if (file.empty()) + cap.open(camera); else cap.open(file.c_str()); if (!cap.isOpened()) { - cout << "Can not open video stream: '" << (useCamera ? "" : file) << "'" << endl; + cout << "Can not open video stream: '" << (file.empty() ? "" : file) << "'" << endl; return 2; } diff --git a/samples/cpp/opencv_version.cpp b/samples/cpp/opencv_version.cpp index 0ee3494a40..b500f117e3 100644 --- a/samples/cpp/opencv_version.cpp +++ b/samples/cpp/opencv_version.cpp @@ -1,16 +1,17 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + #include #include -const char* keys = -{ - "{ b build | | print complete build info }" - "{ h help | | print this help }" -}; +static const std::string keys = "{ b build | | print complete build info }" + "{ h help | | print this help }"; int main(int argc, const char* argv[]) { cv::CommandLineParser parser(argc, argv, keys); - + parser.about("This sample outputs OpenCV version and build configuration."); if (parser.has("help")) { parser.printMessage(); @@ -27,6 +28,5 @@ int main(int argc, const char* argv[]) { std::cout << "Welcome to OpenCV " << CV_VERSION << std::endl; } - return 0; } diff --git a/samples/cpp/peopledetect.cpp b/samples/cpp/peopledetect.cpp index 5fa2382f0f..ea45ae9c9b 100644 --- a/samples/cpp/peopledetect.cpp +++ b/samples/cpp/peopledetect.cpp @@ -1,177 +1,126 @@ -#include -#include +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + #include #include #include -#include -#include #include +#include +#include using namespace cv; using namespace std; - -const char* keys = +class Detector { - "{ help h | | print help message }" - "{ image i | | specify input image}" - "{ camera c | | enable camera capturing }" - "{ video v | ../data/vtest.avi | use video as input }" - "{ directory d | | images directory}" -}; - -static void detectAndDraw(const HOGDescriptor &hog, Mat &img) -{ - vector found, found_filtered; - double t = (double) getTickCount(); - // Run the detector with default parameters. to get a higher hit-rate - // (and more false alarms, respectively), decrease the hitThreshold and - // groupThreshold (set groupThreshold to 0 to turn off the grouping completely). - hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2); - t = (double) getTickCount() - t; - cout << "detection time = " << (t*1000./cv::getTickFrequency()) << " ms" << endl; - - for(size_t i = 0; i < found.size(); i++ ) + enum Mode { Default, Daimler } m; + HOGDescriptor hog, hog_d; +public: + Detector() : m(Default), hog(), hog_d(Size(48, 96), Size(16, 16), Size(8, 8), Size(8, 8), 9) { - Rect r = found[i]; - - size_t j; - // Do not add small detections inside a bigger detection. - for ( j = 0; j < found.size(); j++ ) - if ( j != i && (r & found[j]) == r ) - break; - - if ( j == found.size() ) - found_filtered.push_back(r); + hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); + hog_d.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector()); } - - for (size_t i = 0; i < found_filtered.size(); i++) + void toggleMode() { m = (m == Default ? Daimler : Default); } + string modeName() const { return (m == Default ? "Default" : "Daimler"); } + vector detect(InputArray img) + { + // Run the detector with default parameters. to get a higher hit-rate + // (and more false alarms, respectively), decrease the hitThreshold and + // groupThreshold (set groupThreshold to 0 to turn off the grouping completely). + vector found; + if (m == Default) + hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2, false); + else if (m == Daimler) + hog_d.detectMultiScale(img, found, 0.5, Size(8,8), Size(32,32), 1.05, 2, true); + return found; + } + void adjustRect(Rect & r) const { - Rect r = found_filtered[i]; - // The HOG detector returns slightly larger rectangles than the real objects, // so we slightly shrink the rectangles to get a nicer output. r.x += cvRound(r.width*0.1); r.width = cvRound(r.width*0.8); r.y += cvRound(r.height*0.07); r.height = cvRound(r.height*0.8); - rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3); } -} +}; + +static const string keys = "{ help h | | print help message }" + "{ camera c | 0 | capture video from camera (device index starting from 0) }" + "{ video v | | use video as input }"; int main(int argc, char** argv) { CommandLineParser parser(argc, argv, keys); - + parser.about("This sample demonstrates the use ot the HoG descriptor."); if (parser.has("help")) { - cout << "\nThis program demonstrates the use of the HoG descriptor using\n" - " HOGDescriptor::hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());\n"; parser.printMessage(); - cout << "During execution:\n\tHit q or ESC key to quit.\n" - "\tUsing OpenCV version " << CV_VERSION << "\n" - "Note: camera device number must be different from -1.\n" << endl; return 0; } - - HOGDescriptor hog; - hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); - namedWindow("people detector", 1); - - string pattern_glob = ""; - string video_filename = "../data/vtest.avi"; - int camera_id = -1; - if (parser.has("directory")) + int camera = parser.get("camera"); + string file = parser.get("video"); + if (!parser.check()) { - pattern_glob = parser.get("directory"); - } - else if (parser.has("image")) - { - pattern_glob = parser.get("image"); - } - else if (parser.has("camera")) - { - camera_id = parser.get("camera"); - } - else if (parser.has("video")) - { - video_filename = parser.get("video"); + parser.printErrors(); + return 1; } - if (!pattern_glob.empty() || camera_id != -1 || !video_filename.empty()) + VideoCapture cap; + if (file.empty()) + cap.open(camera); + else + cap.open(file.c_str()); + if (!cap.isOpened()) { - //Read from input image files - vector filenames; - //Read from video file - VideoCapture vc; - Mat frame; + cout << "Can not open video stream: '" << (file.empty() ? "" : file) << "'" << endl; + return 2; + } - if (!pattern_glob.empty()) + cout << "Press 'q' or to quit." << endl; + cout << "Press to toggle between Default and Daimler detector" << endl; + Detector detector; + Mat frame; + for (;;) + { + cap >> frame; + if (frame.empty()) { - String folder(pattern_glob); - glob(folder, filenames); + cout << "Finished reading: empty frame" << endl; + break; } - else if (camera_id != -1) + int64 t = getTickCount(); + vector found = detector.detect(frame); + t = getTickCount() - t; + + // show the window { - vc.open(camera_id); - if (!vc.isOpened()) - { - stringstream msg; - msg << "can't open camera: " << camera_id; - throw runtime_error(msg.str()); - } + ostringstream buf; + buf << "Mode: " << detector.modeName() << " ||| " + << "FPS: " << fixed << setprecision(1) << (getTickFrequency() / (double)t); + putText(frame, buf.str(), Point(10, 30), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255), 2, LINE_AA); } - else + for (vector::iterator i = found.begin(); i != found.end(); ++i) { - vc.open(video_filename.c_str()); - if (!vc.isOpened()) - throw runtime_error(string("can't open video file: " + video_filename)); + Rect &r = *i; + detector.adjustRect(r); + rectangle(frame, r.tl(), r.br(), cv::Scalar(0, 255, 0), 2); } + imshow("People detector", frame); - vector::const_iterator it_image = filenames.begin(); - - for (;;) + // interact with user + const char key = (char)waitKey(30); + if (key == 27 || key == 'q') // ESC { - if (!pattern_glob.empty()) - { - bool read_image_ok = false; - for (; it_image != filenames.end(); ++it_image) - { - cout << "\nRead: " << *it_image << endl; - // Read current image - frame = imread(*it_image); - - if (!frame.empty()) - { - ++it_image; - read_image_ok = true; - break; - } - } - - //No more valid images - if (!read_image_ok) - { - //Release the image in order to exit the while loop - frame.release(); - } - } - else - { - vc >> frame; - } - - if (frame.empty()) - break; - - detectAndDraw(hog, frame); - - imshow("people detector", frame); - int c = waitKey( vc.isOpened() ? 30 : 0 ) & 255; - if ( c == 'q' || c == 'Q' || c == 27) - break; + cout << "Exit requested" << endl; + break; + } + else if (key == ' ') + { + detector.toggleMode(); } } - return 0; } diff --git a/samples/dnn/colorization.cpp b/samples/dnn/colorization.cpp index 1c4ae07aac..9329e11d6a 100644 --- a/samples/dnn/colorization.cpp +++ b/samples/dnn/colorization.cpp @@ -1,20 +1,18 @@ -// -// This program is based on https://github.com/richzhang/colorization/blob/master/colorization/colorize.py -// download the caffemodel from: http://eecs.berkeley.edu/~rich.zhang/projects/2016_colorization/files/demo_v2/colorization_release_v2.caffemodel -// and the prototxt from: https://github.com/richzhang/colorization/blob/master/colorization/models/colorization_deploy_v2.prototxt -// +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + #include #include #include +#include + using namespace cv; using namespace cv::dnn; - -#include using namespace std; - // the 313 ab cluster centers from pts_in_hull.npy (already transposed) -float hull_pts[] = { +static float hull_pts[] = { -90., -90., -90., -90., -90., -80., -80., -80., -80., -80., -80., -80., -80., -70., -70., -70., -70., -70., -70., -70., -70., -70., -70., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -60., -50., -50., -50., -50., -50., -50., -50., -50., -50., -50., -50., -50., -50., -50., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -40., -30., @@ -43,54 +41,61 @@ float hull_pts[] = { -20., -10., 0., 10., 20., 30., 40., 50., 60., 70., -90., -80., -70., -60., -50., -40., -30., -20., -10., 0. }; - int main(int argc, char **argv) { - CommandLineParser parser(argc, argv, - "{ help | false | print this help message }" - "{ proto | colorization_deploy_v2.prototxt | model configuration }" - "{ model | colorization_release_v2.caffemodel | model weights }" - "{ image | space_shuttle.jpg | path to image file }" - "{ opencl | false | enable OpenCL }" - ); - - String modelTxt = parser.get("proto"); - String modelBin = parser.get("model"); - String imageFile = parser.get("image"); - if (parser.get("help") || modelTxt.empty() || modelBin.empty() || imageFile.empty()) + const string about = + "This sample demonstrates recoloring grayscale images with dnn.\n" + "This program is based on:\n" + " http://richzhang.github.io/colorization\n" + " https://github.com/richzhang/colorization\n" + "Download caffemodel and prototxt files:\n" + " http://eecs.berkeley.edu/~rich.zhang/projects/2016_colorization/files/demo_v2/colorization_release_v2.caffemodel\n" + " https://raw.githubusercontent.com/richzhang/colorization/master/colorization/models/colorization_deploy_v2.prototxt\n"; + const string keys = + "{ h help | | print this help message }" + "{ proto | colorization_deploy_v2.prototxt | model configuration }" + "{ model | colorization_release_v2.caffemodel | model weights }" + "{ image | space_shuttle.jpg | path to image file }" + "{ opencl | | enable OpenCL }"; + CommandLineParser parser(argc, argv, keys); + parser.about(about); + if (parser.has("help")) { - cout << "A sample app to demonstrate recoloring grayscale images with dnn." << endl; parser.printMessage(); return 0; } - - // fixed input size for the pretrained network - int W_in = 224; - int H_in = 224; - - Net net = dnn::readNetFromCaffe(modelTxt, modelBin); - - // setup additional layers: - int sz[] = {2, 313, 1, 1}; - Mat pts_in_hull(4, sz, CV_32F, hull_pts); - Ptr class8_ab = net.getLayer("class8_ab"); - class8_ab->blobs.push_back(pts_in_hull); - - Ptr conv8_313_rh = net.getLayer("conv8_313_rh"); - conv8_313_rh->blobs.push_back(Mat(1, 313, CV_32F, 2.606f)); - - if (parser.get("opencl")) + string modelTxt = parser.get("proto"); + string modelBin = parser.get("model"); + string imageFile = parser.get("image"); + bool useOpenCL = parser.has("opencl"); + if (!parser.check()) { - net.setPreferableTarget(DNN_TARGET_OPENCL); + parser.printErrors(); + return 1; } Mat img = imread(imageFile); if (img.empty()) { - std::cerr << "Can't read image from the file: " << imageFile << std::endl; - exit(-1); + cout << "Can't read image from file: " << imageFile << endl; + return 2; } + // fixed input size for the pretrained network + const int W_in = 224; + const int H_in = 224; + Net net = dnn::readNetFromCaffe(modelTxt, modelBin); + if (useOpenCL) + net.setPreferableTarget(DNN_TARGET_OPENCL); + + // setup additional layers: + int sz[] = {2, 313, 1, 1}; + const Mat pts_in_hull(4, sz, CV_32F, hull_pts); + Ptr class8_ab = net.getLayer("class8_ab"); + class8_ab->blobs.push_back(pts_in_hull); + Ptr conv8_313_rh = net.getLayer("conv8_313_rh"); + conv8_313_rh->blobs.push_back(Mat(1, 313, CV_32F, Scalar(2.606))); + // extract L channel and subtract mean Mat lab, L, input; img.convertTo(img, CV_32F, 1.0/255); @@ -111,13 +116,11 @@ int main(int argc, char **argv) resize(a, a, img.size()); resize(b, b, img.size()); - // merge, and convert back to bgr + // merge, and convert back to BGR Mat color, chn[] = {L, a, b}; merge(chn, 3, lab); cvtColor(lab, color, COLOR_Lab2BGR); - namedWindow("color", WINDOW_NORMAL); - namedWindow("original", WINDOW_NORMAL); imshow("color", color); imshow("original", img); waitKey(); diff --git a/samples/tapi/dense_optical_flow.cpp b/samples/tapi/dense_optical_flow.cpp new file mode 100644 index 0000000000..27ca2b867a --- /dev/null +++ b/samples/tapi/dense_optical_flow.cpp @@ -0,0 +1,151 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + +#include +#include +#include + +#include "opencv2/core/ocl.hpp" +#include "opencv2/core/utility.hpp" +#include "opencv2/imgcodecs.hpp" +#include "opencv2/videoio.hpp" +#include "opencv2/highgui.hpp" +#include "opencv2/video.hpp" + +using namespace std; +using namespace cv; + +static Mat getVisibleFlow(InputArray flow) +{ + vector flow_vec; + split(flow, flow_vec); + UMat magnitude, angle; + cartToPolar(flow_vec[0], flow_vec[1], magnitude, angle, true); + magnitude.convertTo(magnitude, CV_32F, 0.2); + vector hsv_vec; + hsv_vec.push_back(angle); + hsv_vec.push_back(UMat::ones(angle.size(), angle.type())); + hsv_vec.push_back(magnitude); + UMat hsv; + merge(hsv_vec, hsv); + Mat img; + cvtColor(hsv, img, COLOR_HSV2BGR); + return img; +} + +static Size fitSize(const Size & sz, const Size & bounds) +{ + CV_Assert(sz.area() > 0); + if (sz.width > bounds.width || sz.height > bounds.height) + { + double scale = std::min((double)bounds.width / sz.width, (double)bounds.height / sz.height); + return Size(cvRound(sz.width * scale), cvRound(sz.height * scale)); + } + return sz; +} + +int main(int argc, const char* argv[]) +{ + const char* keys = + "{ h help | | print help message }" + "{ c camera | 0 | capture video from camera (device index starting from 0) }" + "{ a algorithm | fb | algorithm (supported: 'fb', 'tvl')}" + "{ m cpu | | run without OpenCL }" + "{ v video | | use video as input }" + "{ o original | | use original frame size (do not resize to 640x480)}" + ; + CommandLineParser parser(argc, argv, keys); + parser.about("This sample demonstrates using of dense optical flow algorithms."); + if (parser.has("help")) + { + parser.printMessage(); + return 0; + } + int camera = parser.get("camera"); + string algorithm = parser.get("algorithm"); + bool useCPU = parser.has("cpu"); + string filename = parser.get("video"); + bool useOriginalSize = parser.has("original"); + if (!parser.check()) + { + parser.printErrors(); + return 1; + } + + VideoCapture cap; + if(filename.empty()) + cap.open(camera); + else + cap.open(filename); + if (!cap.isOpened()) + { + cout << "Can not open video stream: '" << (filename.empty() ? "" : filename) << "'" << endl; + return 2; + } + + cv::Ptr alg; + if (algorithm == "fb") + alg = cv::FarnebackOpticalFlow::create(); + else if (algorithm == "tvl") + alg = cv::DualTVL1OpticalFlow::create(); + else + { + cout << "Invalid algorithm: " << algorithm << endl; + return 3; + } + + ocl::setUseOpenCL(!useCPU); + + cout << "Press 'm' to toggle CPU/GPU processing mode" << endl; + cout << "Press ESC or 'q' to exit" << endl; + + UMat prevFrame, frame, input_frame, flow; + for(;;) + { + if (!cap.read(input_frame) || input_frame.empty()) + { + cout << "Finished reading: empty frame" << endl; + break; + } + Size small_size = fitSize(input_frame.size(), Size(640, 480)); + if (!useOriginalSize && small_size != input_frame.size()) + resize(input_frame, frame, small_size); + else + frame = input_frame; + cvtColor(frame, frame, COLOR_BGR2GRAY); + imshow("frame", frame); + if (!prevFrame.empty()) + { + int64 t = getTickCount(); + alg->calc(prevFrame, frame, flow); + t = getTickCount() - t; + { + Mat img = getVisibleFlow(flow); + ostringstream buf; + buf << "Algo: " << algorithm << " | " + << "Mode: " << (useCPU ? "CPU" : "GPU") << " | " + << "FPS: " << fixed << setprecision(1) << (getTickFrequency() / (double)t); + putText(img, buf.str(), Point(10, 30), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255), 2, LINE_AA); + imshow("Dense optical flow field", img); + } + } + frame.copyTo(prevFrame); + + // interact with user + const char key = (char)waitKey(30); + if (key == 27 || key == 'q') // ESC + { + cout << "Exit requested" << endl; + break; + } + else if (key == 'm') + { + useCPU = !useCPU; + ocl::setUseOpenCL(!useCPU); + cout << "Set processing mode to: " << (useCPU ? "CPU" : "GPU") << endl; + } + } + + return 0; +} diff --git a/samples/tapi/opencl_custom_kernel.cpp b/samples/tapi/opencl_custom_kernel.cpp index 87f5b9a24a..2395061a9a 100644 --- a/samples/tapi/opencl_custom_kernel.cpp +++ b/samples/tapi/opencl_custom_kernel.cpp @@ -1,3 +1,7 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html + #include "opencv2/core.hpp" #include "opencv2/core/ocl.hpp" #include "opencv2/highgui.hpp" diff --git a/samples/tapi/tvl1_optical_flow.cpp b/samples/tapi/tvl1_optical_flow.cpp deleted file mode 100644 index 3d301ee033..0000000000 --- a/samples/tapi/tvl1_optical_flow.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include -#include -#include - -#include "opencv2/core/ocl.hpp" -#include "opencv2/core/utility.hpp" -#include "opencv2/imgcodecs.hpp" -#include "opencv2/videoio.hpp" -#include "opencv2/highgui.hpp" -#include "opencv2/video.hpp" - -using namespace std; -using namespace cv; - -typedef unsigned char uchar; -#define LOOP_NUM 10 -int64 work_begin = 0; -int64 work_end = 0; - -static void workBegin() -{ - work_begin = getTickCount(); -} -static void workEnd() -{ - work_end += (getTickCount() - work_begin); -} -static double getTime() -{ - return work_end * 1000. / getTickFrequency(); -} - -template inline T clamp (T x, T a, T b) -{ - return ((x) > (a) ? ((x) < (b) ? (x) : (b)) : (a)); -} - -template inline T mapValue(T x, T a, T b, T c, T d) -{ - x = ::clamp(x, a, b); - return c + (d - c) * (x - a) / (b - a); -} - -static void getFlowField(const Mat& u, const Mat& v, Mat& flowField) -{ - float maxDisplacement = 1.0f; - - for (int i = 0; i < u.rows; ++i) - { - const float* ptr_u = u.ptr(i); - const float* ptr_v = v.ptr(i); - - for (int j = 0; j < u.cols; ++j) - { - float d = max(fabsf(ptr_u[j]), fabsf(ptr_v[j])); - - if (d > maxDisplacement) - maxDisplacement = d; - } - } - - flowField.create(u.size(), CV_8UC4); - - for (int i = 0; i < flowField.rows; ++i) - { - const float* ptr_u = u.ptr(i); - const float* ptr_v = v.ptr(i); - - - Vec4b* row = flowField.ptr(i); - - for (int j = 0; j < flowField.cols; ++j) - { - row[j][0] = 0; - row[j][1] = static_cast (mapValue (-ptr_v[j], -maxDisplacement, maxDisplacement, 0.0f, 255.0f)); - row[j][2] = static_cast (mapValue ( ptr_u[j], -maxDisplacement, maxDisplacement, 0.0f, 255.0f)); - row[j][3] = 255; - } - } -} - - -int main(int argc, const char* argv[]) -{ - const char* keys = - "{ h help | | print help message }" - "{ l left | | specify left image }" - "{ r right | | specify right image }" - "{ o output | tvl1_output.jpg | specify output save path }" - "{ c camera | 0 | enable camera capturing }" - "{ m cpu_mode | | run without OpenCL }" - "{ v video | | use video as input }"; - - CommandLineParser cmd(argc, argv, keys); - - if (cmd.has("help")) - { - cout << "Usage: pyrlk_optical_flow [options]" << endl; - cout << "Available options:" << endl; - cmd.printMessage(); - return EXIT_SUCCESS; - } - - string fname0 = cmd.get("l"); - string fname1 = cmd.get("r"); - string vdofile = cmd.get("v"); - string outpath = cmd.get("o"); - bool useCPU = cmd.get("m"); - bool useCamera = cmd.get("c"); - int inputName = cmd.get("c"); - - UMat frame0, frame1; - imread(fname0, cv::IMREAD_GRAYSCALE).copyTo(frame0); - imread(fname1, cv::IMREAD_GRAYSCALE).copyTo(frame1); - cv::Ptr alg = cv::createOptFlow_DualTVL1(); - - UMat flow; - Mat show_flow; - vector flow_vec; - if (frame0.empty() || frame1.empty()) - useCamera = true; - - if (useCamera) - { - VideoCapture capture; - UMat frame, frameCopy; - UMat frame0Gray, frame1Gray; - UMat ptr0, ptr1; - - if(vdofile.empty()) - capture.open( inputName ); - else - capture.open(vdofile.c_str()); - - if(!capture.isOpened()) - { - if(vdofile.empty()) - cout << "Capture from CAM " << inputName << " didn't work" << endl; - else - cout << "Capture from file " << vdofile << " failed" <calc(ptr0, ptr1, flow); - split(flow, flow_vec); - - if (i%2 == 1) - frame1.copyTo(frameCopy); - else - frame0.copyTo(frameCopy); - getFlowField(flow_vec[0].getMat(ACCESS_READ), flow_vec[1].getMat(ACCESS_READ), show_flow); - imshow("tvl1 optical flow field", show_flow); - } - - char key = (char)waitKey(10); - if (key == 27) - break; - else if (key == 'm' || key == 'M') - { - ocl::setUseOpenCL(!cv::ocl::useOpenCL()); - cout << "Switched to " << (ocl::useOpenCL() ? "OpenCL" : "CPU") << " mode\n"; - } - } - - capture.release(); - } - else - { -nocamera: - if (cmd.has("cpu_mode")) - { - ocl::setUseOpenCL(false); - std::cout << "OpenCL was disabled" << std::endl; - } - for(int i = 0; i <= LOOP_NUM; i ++) - { - cout << "loop" << i << endl; - - if (i > 0) workBegin(); - - alg->calc(frame0, frame1, flow); - split(flow, flow_vec); - - if (i > 0 && i <= LOOP_NUM) - workEnd(); - - if (i == LOOP_NUM) - { - if (useCPU) - cout << "average CPU time (noCamera) : "; - else - cout << "average GPU time (noCamera) : "; - cout << getTime() / LOOP_NUM << " ms" << endl; - - getFlowField(flow_vec[0].getMat(ACCESS_READ), flow_vec[1].getMat(ACCESS_READ), show_flow); - imshow("PyrLK [Sparse]", show_flow); - imwrite(outpath, show_flow); - } - } - } - - waitKey(); - - return EXIT_SUCCESS; -} From 265f335dae1d78b3e09a5ee21444575b588ba2d1 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Mon, 26 Feb 2018 21:10:21 +0300 Subject: [PATCH 8/9] Add install component for 3rdparty libraries licenses --- 3rdparty/cpufeatures/CMakeLists.txt | 2 ++ 3rdparty/include/opencl/LICENSE.txt | 25 ++++++++++++++ 3rdparty/ittnotify/CMakeLists.txt | 2 ++ 3rdparty/libjasper/CMakeLists.txt | 2 ++ 3rdparty/libjpeg/CMakeLists.txt | 2 ++ 3rdparty/libpng/CMakeLists.txt | 4 ++- 3rdparty/libtiff/CMakeLists.txt | 2 ++ 3rdparty/openexr/CMakeLists.txt | 2 ++ 3rdparty/protobuf/CMakeLists.txt | 2 ++ 3rdparty/tbb/CMakeLists.txt | 2 ++ 3rdparty/zlib/CMakeLists.txt | 2 ++ cmake/OpenCVDetectOpenCL.cmake | 1 + cmake/OpenCVFindIPP.cmake | 1 + cmake/OpenCVFindIPPIW.cmake | 15 ++++++++- cmake/OpenCVUtils.cmake | 12 +++++++ modules/core/3rdparty/SoftFloat/COPYING.txt | 36 +++++++++++++++++++++ modules/core/CMakeLists.txt | 2 ++ 17 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 3rdparty/include/opencl/LICENSE.txt create mode 100644 modules/core/3rdparty/SoftFloat/COPYING.txt diff --git a/3rdparty/cpufeatures/CMakeLists.txt b/3rdparty/cpufeatures/CMakeLists.txt index 6b19574864..92bce6abf8 100644 --- a/3rdparty/cpufeatures/CMakeLists.txt +++ b/3rdparty/cpufeatures/CMakeLists.txt @@ -31,3 +31,5 @@ endif() if(NOT BUILD_SHARED_LIBS) ocv_install_target(${OPENCV_CPUFEATURES_TARGET_NAME} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() + +ocv_install_3rdparty_licenses(cpufeatures LICENSE README.md) diff --git a/3rdparty/include/opencl/LICENSE.txt b/3rdparty/include/opencl/LICENSE.txt new file mode 100644 index 0000000000..020ce65fca --- /dev/null +++ b/3rdparty/include/opencl/LICENSE.txt @@ -0,0 +1,25 @@ +Copyright (c) 2008-2015 The Khronos Group Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and/or associated documentation files (the +"Materials"), to deal in the Materials without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Materials, and to +permit persons to whom the Materials are furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Materials. + +MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS +KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS +SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT + https://www.khronos.org/registry/ + +THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. diff --git a/3rdparty/ittnotify/CMakeLists.txt b/3rdparty/ittnotify/CMakeLists.txt index e8b2d289ea..2acb5347b4 100644 --- a/3rdparty/ittnotify/CMakeLists.txt +++ b/3rdparty/ittnotify/CMakeLists.txt @@ -60,3 +60,5 @@ endif() if(NOT BUILD_SHARED_LIBS) ocv_install_target(${ITT_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() + +ocv_install_3rdparty_licenses(ittnotify src/ittnotify/LICENSE.BSD src/ittnotify/LICENSE.GPL) diff --git a/3rdparty/libjasper/CMakeLists.txt b/3rdparty/libjasper/CMakeLists.txt index 13200eb445..29349e0c50 100644 --- a/3rdparty/libjasper/CMakeLists.txt +++ b/3rdparty/libjasper/CMakeLists.txt @@ -47,3 +47,5 @@ endif() if(NOT BUILD_SHARED_LIBS) ocv_install_target(${JASPER_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() + +ocv_install_3rdparty_licenses(jasper LICENSE README copyright) diff --git a/3rdparty/libjpeg/CMakeLists.txt b/3rdparty/libjpeg/CMakeLists.txt index c5509cac40..f686baf61a 100644 --- a/3rdparty/libjpeg/CMakeLists.txt +++ b/3rdparty/libjpeg/CMakeLists.txt @@ -51,3 +51,5 @@ endif() if(NOT BUILD_SHARED_LIBS) ocv_install_target(${JPEG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() + +ocv_install_3rdparty_licenses(libjpeg README) diff --git a/3rdparty/libpng/CMakeLists.txt b/3rdparty/libpng/CMakeLists.txt index b5f36a1875..01ac496976 100644 --- a/3rdparty/libpng/CMakeLists.txt +++ b/3rdparty/libpng/CMakeLists.txt @@ -48,7 +48,7 @@ if(PPC64LE OR PPC64) list(APPEND lib_srcs powerpc/powerpc_init.c powerpc/filter_vsx_intrinsics.c) add_definitions(-DPNG_POWERPC_VSX_OPT=2) else() - add_definitions(-DPNG_POWERPC_VSX_OPT=0) + add_definitions(-DPNG_POWERPC_VSX_OPT=0) endif() endif() @@ -80,3 +80,5 @@ endif() if(NOT BUILD_SHARED_LIBS) ocv_install_target(${PNG_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() + +ocv_install_3rdparty_licenses(libpng LICENSE README opencv-libpng.patch) diff --git a/3rdparty/libtiff/CMakeLists.txt b/3rdparty/libtiff/CMakeLists.txt index 73717e20c0..9d575bcab9 100644 --- a/3rdparty/libtiff/CMakeLists.txt +++ b/3rdparty/libtiff/CMakeLists.txt @@ -470,3 +470,5 @@ endif() if(NOT BUILD_SHARED_LIBS) ocv_install_target(${TIFF_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() + +ocv_install_3rdparty_licenses(libtiff COPYRIGHT) diff --git a/3rdparty/openexr/CMakeLists.txt b/3rdparty/openexr/CMakeLists.txt index 7302441d63..730b9a0d7e 100644 --- a/3rdparty/openexr/CMakeLists.txt +++ b/3rdparty/openexr/CMakeLists.txt @@ -76,5 +76,7 @@ if(NOT BUILD_SHARED_LIBS) ocv_install_target(IlmImf EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() +ocv_install_3rdparty_licenses(openexr LICENSE AUTHORS.ilmbase AUTHORS.openexr fix_msvc2013_errors.patch) + set(OPENEXR_INCLUDE_PATHS ${OPENEXR_INCLUDE_PATHS} PARENT_SCOPE) set(OPENEXR_VERSION "1.7.1" PARENT_SCOPE) diff --git a/3rdparty/protobuf/CMakeLists.txt b/3rdparty/protobuf/CMakeLists.txt index a10e20bfd8..f5ca6f1fff 100644 --- a/3rdparty/protobuf/CMakeLists.txt +++ b/3rdparty/protobuf/CMakeLists.txt @@ -150,3 +150,5 @@ set(Protobuf_VERSION ${Protobuf_VERSION} CACHE INTERNAL "" FORCE) if(NOT BUILD_SHARED_LIBS) ocv_install_target(libprotobuf EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() + +ocv_install_3rdparty_licenses(protobuf LICENSE README.md) diff --git a/3rdparty/tbb/CMakeLists.txt b/3rdparty/tbb/CMakeLists.txt index f2b7b286ab..5fe608619e 100644 --- a/3rdparty/tbb/CMakeLists.txt +++ b/3rdparty/tbb/CMakeLists.txt @@ -156,4 +156,6 @@ ocv_install_target(tbb EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev ) +ocv_install_3rdparty_licenses(tbb "${tbb_src_dir}/LICENSE" "${tbb_src_dir}/README") + ocv_tbb_read_version("${tbb_src_dir}/include") diff --git a/3rdparty/zlib/CMakeLists.txt b/3rdparty/zlib/CMakeLists.txt index cd1da16987..8525a11fac 100644 --- a/3rdparty/zlib/CMakeLists.txt +++ b/3rdparty/zlib/CMakeLists.txt @@ -99,3 +99,5 @@ endif() if(NOT BUILD_SHARED_LIBS) ocv_install_target(${ZLIB_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) endif() + +ocv_install_3rdparty_licenses(zlib README) diff --git a/cmake/OpenCVDetectOpenCL.cmake b/cmake/OpenCVDetectOpenCL.cmake index 433f244fe6..629d44a62d 100644 --- a/cmake/OpenCVDetectOpenCL.cmake +++ b/cmake/OpenCVDetectOpenCL.cmake @@ -5,6 +5,7 @@ if(APPLE) else(APPLE) set(OPENCL_LIBRARY "" CACHE STRING "OpenCL library") set(OPENCL_INCLUDE_DIR "${OpenCV_SOURCE_DIR}/3rdparty/include/opencl/1.2" CACHE PATH "OpenCL include directory") + ocv_install_3rdparty_licenses(opencl-headers "${OpenCV_SOURCE_DIR}/3rdparty/include/opencl/LICENSE.txt") endif(APPLE) mark_as_advanced(OPENCL_INCLUDE_DIR OPENCL_LIBRARY) diff --git a/cmake/OpenCVFindIPP.cmake b/cmake/OpenCVFindIPP.cmake index 068cef71be..52c8d50638 100644 --- a/cmake/OpenCVFindIPP.cmake +++ b/cmake/OpenCVFindIPP.cmake @@ -244,6 +244,7 @@ if(NOT DEFINED IPPROOT) if(NOT IPPROOT) return() endif() + ocv_install_3rdparty_licenses(ippicv "${IPPROOT}/readme.htm" "${IPPROOT}/license/ippEULA.txt") endif() file(TO_CMAKE_PATH "${IPPROOT}" __IPPROOT) diff --git a/cmake/OpenCVFindIPPIW.cmake b/cmake/OpenCVFindIPPIW.cmake index dcc546f29a..3b63aa1a0d 100644 --- a/cmake/OpenCVFindIPPIW.cmake +++ b/cmake/OpenCVFindIPPIW.cmake @@ -136,6 +136,13 @@ if(BUILD_IPP_IW) # local sources ippiw_setup("${OpenCV_SOURCE_DIR}/3rdparty/ippiw" 1) + set(IPPIW_ROOT "${IPPROOT}/../${IW_PACKAGE_SUBDIR}") + ocv_install_3rdparty_licenses(ippiw + "${IPPIW_ROOT}/EULA.txt" + "${IPPIW_ROOT}/redist.txt" + "${IPPIW_ROOT}/support.txt" + "${IPPIW_ROOT}/third-party-programs.txt") + # Package sources get_filename_component(__PATH "${IPPROOT}/../${IW_PACKAGE_SUBDIR}/" ABSOLUTE) ippiw_setup("${__PATH}" 1) @@ -161,9 +168,15 @@ if(NOT HAVE_IPP_ICV AND BUILD_IPP_IW) set(TEMP_ROOT 0) include("${OpenCV_SOURCE_DIR}/3rdparty/ippicv/ippicv.cmake") download_ippicv(TEMP_ROOT) + set(IPPIW_ROOT "${TEMP_ROOT}/../${IW_PACKAGE_SUBDIR}") + ocv_install_3rdparty_licenses(ippiw + "${IPPIW_ROOT}/EULA.txt" + "${IPPIW_ROOT}/redist.txt" + "${IPPIW_ROOT}/support.txt" + "${IPPIW_ROOT}/third-party-programs.txt") # Package sources. Only sources are compatible with regular Intel IPP - ippiw_setup("${TEMP_ROOT}/../${IW_PACKAGE_SUBDIR}/" 1) + ippiw_setup("${IPPIW_ROOT}" 1) endif() diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index ae367d74a3..30f36ac5e0 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -1002,6 +1002,18 @@ function(ocv_install_target) endif() endfunction() +# ocv_install_3rdparty_licenses( [ ..]) +function(ocv_install_3rdparty_licenses library) + foreach(filename ${ARGN}) + get_filename_component(name "${filename}" NAME) + install( + FILES "${filename}" + DESTINATION "${OPENCV_OTHER_INSTALL_PATH}/licenses" + COMPONENT licenses + RENAME "${library}-${name}" + OPTIONAL) + endforeach() +endfunction() # read set of version defines from the header file macro(ocv_parse_header FILENAME FILE_VAR) diff --git a/modules/core/3rdparty/SoftFloat/COPYING.txt b/modules/core/3rdparty/SoftFloat/COPYING.txt new file mode 100644 index 0000000000..e16aa0fd58 --- /dev/null +++ b/modules/core/3rdparty/SoftFloat/COPYING.txt @@ -0,0 +1,36 @@ + +License for Berkeley SoftFloat Release 3c + +John R. Hauser +2017 February 10 + +The following applies to the whole of SoftFloat Release 3c as well as to +each source file individually. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the +University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 4fb12f3c47..2ce93d374b 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -70,3 +70,5 @@ endif() ocv_add_accuracy_tests() ocv_add_perf_tests() + +ocv_install_3rdparty_licenses(SoftFloat "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/SoftFloat/COPYING.txt") From 3b15f3e3b9041ca742822e48c7241d1f39e611b8 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 29 Mar 2018 13:01:46 +0300 Subject: [PATCH 9/9] avoid calling of setNumThreads() to respect user settings --- modules/calib3d/perf/perf_stereosgbm.cpp | 1 - modules/calib3d/test/test_solvepnp_ransac.cpp | 2 ++ modules/imgproc/src/connectedcomponents.cpp | 31 ++++++++----------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/modules/calib3d/perf/perf_stereosgbm.cpp b/modules/calib3d/perf/perf_stereosgbm.cpp index e74e1da472..2947938d40 100644 --- a/modules/calib3d/perf/perf_stereosgbm.cpp +++ b/modules/calib3d/perf/perf_stereosgbm.cpp @@ -67,7 +67,6 @@ PERF_TEST_P( TestStereoCorresp, DISABLED_TooLongInDebug_SGBM, Combine(Values(Siz MakeArtificialExample(rng,src_left,src_right); - cv::setNumThreads(cv::getNumberOfCPUs()); int wsize = 3; int P1 = 8*src_left.channels()*wsize*wsize; TEST_CYCLE() diff --git a/modules/calib3d/test/test_solvepnp_ransac.cpp b/modules/calib3d/test/test_solvepnp_ransac.cpp index 0a164440a5..8eec7a7167 100644 --- a/modules/calib3d/test/test_solvepnp_ransac.cpp +++ b/modules/calib3d/test/test_solvepnp_ransac.cpp @@ -382,6 +382,7 @@ TEST(Calib3d_SolvePnPRansac, concurrency) Mat rvec1, rvec2; Mat tvec1, tvec2; + int threads = getNumThreads(); { // limit concurrency to get deterministic result theRNG().state = 20121010; @@ -390,6 +391,7 @@ TEST(Calib3d_SolvePnPRansac, concurrency) } { + setNumThreads(threads); Mat rvec; Mat tvec; // parallel executions diff --git a/modules/imgproc/src/connectedcomponents.cpp b/modules/imgproc/src/connectedcomponents.cpp index e0d91aef2b..676afc6e8b 100644 --- a/modules/imgproc/src/connectedcomponents.cpp +++ b/modules/imgproc/src/connectedcomponents.cpp @@ -579,9 +579,6 @@ namespace cv{ CV_Assert(img.cols == imgLabels.cols); CV_Assert(connectivity == 8 || connectivity == 4); - const int nThreads = cv::getNumberOfCPUs(); - cv::setNumThreads(nThreads); - const int h = img.rows; const int w = img.cols; @@ -606,12 +603,13 @@ namespace cv{ P[0] = 0; cv::Range range(0, h); + const double nParallelStripes = std::max(1, std::min(h / 2, getNumThreads()*4)); + LabelT nLabels = 1; if (connectivity == 8){ - //First scan, each thread works with chunk of img.rows/nThreads rows - //e.g. 300 rows, 4 threads -> each chunks is composed of 75 rows - cv::parallel_for_(range, FirstScan8Connectivity(img, imgLabels, P, chunksSizeAndLabels), nThreads); + //First scan + cv::parallel_for_(range, FirstScan8Connectivity(img, imgLabels, P, chunksSizeAndLabels), nParallelStripes); //merge labels of different chunks mergeLabels8Connectivity(imgLabels, P, chunksSizeAndLabels); @@ -621,9 +619,8 @@ namespace cv{ } } else{ - //First scan, each thread works with chunk of img.rows/nThreads rows - //e.g. 300 rows, 4 threads -> each chunks is composed of 75 rows - cv::parallel_for_(range, FirstScan4Connectivity(img, imgLabels, P, chunksSizeAndLabels), nThreads); + //First scan + cv::parallel_for_(range, FirstScan4Connectivity(img, imgLabels, P, chunksSizeAndLabels), nParallelStripes); //merge labels of different chunks mergeLabels4Connectivity(imgLabels, P, chunksSizeAndLabels); @@ -638,7 +635,7 @@ namespace cv{ sop.init(nLabels); //Second scan - cv::parallel_for_(range, SecondScan(imgLabels, P, sop, sopArray, nLabels), nThreads); + cv::parallel_for_(range, SecondScan(imgLabels, P, sop, sopArray, nLabels), nParallelStripes); StatsOp::mergeStats(imgLabels, sopArray, sop, nLabels); sop.finish(); @@ -2530,9 +2527,6 @@ namespace cv{ CV_Assert(img.cols == imgLabels.cols); CV_Assert(connectivity == 8); - const int nThreads = cv::getNumberOfCPUs(); - cv::setNumThreads(nThreads); - const int h = img.rows; const int w = img.cols; @@ -2556,10 +2550,11 @@ namespace cv{ P[0] = 0; cv::Range range(0, h); + const double nParallelStripes = std::max(1, std::min(h / 2, getNumThreads()*4)); //First scan, each thread works with chunk of img.rows/nThreads rows //e.g. 300 rows, 4 threads -> each chunks is composed of 75 rows - cv::parallel_for_(range, FirstScan(img, imgLabels, P, chunksSizeAndLabels), nThreads); + cv::parallel_for_(range, FirstScan(img, imgLabels, P, chunksSizeAndLabels), nParallelStripes); //merge labels of different chunks mergeLabels(img, imgLabels, P, chunksSizeAndLabels); @@ -2574,7 +2569,7 @@ namespace cv{ sop.init(nLabels); //Second scan - cv::parallel_for_(range, SecondScan(img, imgLabels, P, sop, sopArray, nLabels), nThreads); + cv::parallel_for_(range, SecondScan(img, imgLabels, P, sop, sopArray, nLabels), nParallelStripes); StatsOp::mergeStats(imgLabels, sopArray, sop, nLabels); sop.finish(); @@ -3936,12 +3931,12 @@ namespace cv{ int lDepth = L.depth(); int iDepth = I.depth(); const char *currentParallelFramework = cv::currentParallelFramework(); - const int numberOfCPUs = cv::getNumberOfCPUs(); + const int nThreads = cv::getNumThreads(); CV_Assert(iDepth == CV_8U || iDepth == CV_8S); - //Run parallel labeling only if the rows of the image are at least twice the number returned by getNumberOfCPUs - const bool is_parallel = currentParallelFramework != NULL && numberOfCPUs > 1 && L.rows / numberOfCPUs >= 2; + //Run parallel labeling only if the rows of the image are at least twice the number of available threads + const bool is_parallel = currentParallelFramework != NULL && nThreads > 1 && L.rows / nThreads >= 2; if (ccltype == CCL_WU || connectivity == 4){ // Wu algorithm is used