From 8bac8b513c1bba5d66742508a244207e1712cab8 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 18 Jul 2019 07:25:59 +0000 Subject: [PATCH 1/8] core: support SIMD intrinsics in user code --- .../include/opencv2/core/simd_intrinsics.hpp | 88 +++++++++++++++++++ samples/cpp/CMakeLists.txt | 7 ++ samples/cpp/simd_basic.cpp | 49 +++++++++++ 3 files changed, 144 insertions(+) create mode 100644 modules/core/include/opencv2/core/simd_intrinsics.hpp create mode 100644 samples/cpp/simd_basic.cpp diff --git a/modules/core/include/opencv2/core/simd_intrinsics.hpp b/modules/core/include/opencv2/core/simd_intrinsics.hpp new file mode 100644 index 0000000000..c3d65cded5 --- /dev/null +++ b/modules/core/include/opencv2/core/simd_intrinsics.hpp @@ -0,0 +1,88 @@ +// 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. + +#ifndef OPENCV_CORE_SIMD_INTRINSICS_HPP +#define OPENCV_CORE_SIMD_INTRINSICS_HPP + +/** +Helper header to support SIMD intrinsics (universal intrinsics) in user code. +Intrinsics documentation: https://docs.opencv.org/3.4/df/d91/group__core__hal__intrin.html + + +Checks of target CPU instruction set based on compiler definitions don't work well enough. +More reliable solutions require utilization of configuration systems (like CMake). + +So, probably you need to specify your own configuration. + +You can do that via CMake in this way: + add_definitions(/DOPENCV_SIMD_CONFIG_HEADER=opencv_simd_config_custom.hpp) +or + add_definitions(/DOPENCV_SIMD_CONFIG_INCLUDE_DIR=1) + +Additionally you may need to add include directory to your files: + include_directories("${CMAKE_CURRENT_LIST_DIR}/opencv_config_${MYTARGET}") + +These files can be pre-generated for target configurations of your application +or generated by CMake on the fly (use CMAKE_BINARY_DIR for that). + +Notes: +- H/W capability checks are still responsibility of your applcation +- runtime dispatching is not covered by this helper header +*/ + +#ifdef __OPENCV_BUILD +#error "Use core/hal/intrin.hpp during OpenCV build" +#endif + +#ifdef OPENCV_HAL_INTRIN_HPP +#error "core/simd_intrinsics.hpp must be included before core/hal/intrin.hpp" +#endif + +#include "opencv2/core/cvdef.h" +#include "opencv2/core/version.hpp" + +#ifdef OPENCV_SIMD_CONFIG_HEADER +#include CVAUX_STR(OPENCV_SIMD_CONFIG_HEADER) +#elif defined(OPENCV_SIMD_CONFIG_INCLUDE_DIR) +#include "opencv_simd_config.hpp" // corresponding directory should be added via -I compiler parameter +#else // custom config headers + +#if (!defined(CV_AVX_512F) || !CV_AVX_512F) && (defined(__AVX512__) || defined(__AVX512F__)) +# include +# undef CV_AVX_512F +# define CV_AVX_512F 1 +# ifndef OPENCV_SIMD_DONT_ASSUME_SKX // Skylake-X with AVX-512F/CD/BW/DQ/VL +# undef CV_AVX512_SKX +# define CV_AVX512_SKX 1 +# undef CV_AVX_512CD +# define CV_AVX_512CD 1 +# undef CV_AVX_512BW +# define CV_AVX_512BW 1 +# undef CV_AVX_512DQ +# define CV_AVX_512DQ 1 +# undef CV_AVX_512VL +# define CV_AVX_512VL 1 +# endif +#endif // AVX512 + +// GCC/Clang: -mavx2 +// MSVC: /arch:AVX2 +#if defined __AVX2__ +# include +# undef CV_AVX2 +# define CV_AVX2 1 +# if defined __F16C__ +# undef CV_FP16 +# define CV_FP16 1 +# endif +#endif + +#endif + +// SSE / NEON / VSX is handled by cv_cpu_dispatch.h compatibility block +#include "cv_cpu_dispatch.h" + +#include "hal/intrin.hpp" + +#endif // OPENCV_CORE_SIMD_INTRINSICS_HPP diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index d4417f90ac..109675da04 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -57,6 +57,13 @@ foreach(sample_filename ${cpp_samples}) if(HAVE_OPENGL AND sample_filename MATCHES "detect_mser") target_compile_definitions(${tgt} PRIVATE HAVE_OPENGL) endif() + if(sample_filename MATCHES "simd_") + # disabled intentionally - demonstation purposes only + #target_include_directories(${tgt} PRIVATE "${CMAKE_CURRENT_LIST_DIR}") + #target_compile_definitions(${tgt} PRIVATE OPENCV_SIMD_CONFIG_HEADER=opencv_simd_config_custom.hpp) + #target_compile_definitions(${tgt} PRIVATE OPENCV_SIMD_CONFIG_INCLUDE_DIR=1) + #target_compile_options(${tgt} PRIVATE -mavx2) + endif() endforeach() include("tutorial_code/calib3d/real_time_pose_estimation/CMakeLists.txt" OPTIONAL) diff --git a/samples/cpp/simd_basic.cpp b/samples/cpp/simd_basic.cpp new file mode 100644 index 0000000000..9af4d91cef --- /dev/null +++ b/samples/cpp/simd_basic.cpp @@ -0,0 +1,49 @@ +#include "opencv2/core.hpp" +#include "opencv2/core/simd_intrinsics.hpp" + +using namespace cv; + +int main(int /*argc*/, char** /*argv*/) +{ + printf("================== macro dump ===================\n"); +#ifdef CV_SIMD + printf("CV_SIMD is defined: " CVAUX_STR(CV_SIMD) "\n"); +#ifdef CV_SIMD_WIDTH + printf("CV_SIMD_WIDTH is defined: " CVAUX_STR(CV_SIMD_WIDTH) "\n"); +#endif +#ifdef CV_SIMD128 + printf("CV_SIMD128 is defined: " CVAUX_STR(CV_SIMD128) "\n"); +#endif +#ifdef CV_SIMD256 + printf("CV_SIMD256 is defined: " CVAUX_STR(CV_SIMD256) "\n"); +#endif +#ifdef CV_SIMD512 + printf("CV_SIMD512 is defined: " CVAUX_STR(CV_SIMD512) "\n"); +#endif +#ifdef CV_SIMD_64F + printf("CV_SIMD_64F is defined: " CVAUX_STR(CV_SIMD_64F) "\n"); +#endif +#ifdef CV_SIMD_FP16 + printf("CV_SIMD_FP16 is defined: " CVAUX_STR(CV_SIMD_FP16) "\n"); +#endif +#else + printf("CV_SIMD is NOT defined\n"); +#endif + +#ifdef CV_SIMD + printf("================= sizeof checks =================\n"); + printf("sizeof(v_uint8) = %d\n", (int)sizeof(v_uint8)); + printf("sizeof(v_int32) = %d\n", (int)sizeof(v_int32)); + printf("sizeof(v_float32) = %d\n", (int)sizeof(v_float32)); + + printf("================== arithm check =================\n"); + v_uint8 a = vx_setall_u8(10); + v_uint8 c = a + vx_setall_u8(45); + printf("(vx_setall_u8(10) + vx_setall_u8(45)).get0() => %d\n", (int)c.get0()); +#else + printf("\nSIMD intrinsics are not available. Check compilation target and passed build options.\n"); +#endif + + printf("===================== done ======================\n"); + return 0; +} From 2ee00e7f7defcf119be9742e2d83fd7c4a7cd95a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20Lindstr=C3=B6m?= Date: Wed, 24 Jul 2019 22:12:09 +0200 Subject: [PATCH 2/8] Merge pull request #15059 from hugolm84:improved-support-for-wince * Improve support for Windows Embedded Compact * Remove redundant set(WINCE true) and format CMake --- 3rdparty/zlib/zutil.c | 2 +- 3rdparty/zlib/zutil.h | 12 ++-- CMakeLists.txt | 62 ++++++++++--------- .../opencv2/core/utils/filesystem.private.hpp | 2 +- modules/core/src/glob.cpp | 6 +- modules/core/src/ocl.cpp | 2 +- modules/core/src/system.cpp | 24 +++++-- .../wince/arm-wince-headless-overrides.cmake | 12 ++++ platforms/wince/arm-wince.toolchain.cmake | 35 +++++++++++ platforms/wince/readme.md | 62 +++++++++++++++++++ 10 files changed, 174 insertions(+), 45 deletions(-) create mode 100644 platforms/wince/arm-wince-headless-overrides.cmake create mode 100644 platforms/wince/arm-wince.toolchain.cmake create mode 100644 platforms/wince/readme.md diff --git a/3rdparty/zlib/zutil.c b/3rdparty/zlib/zutil.c index a76c6b0c7e..7271667fd7 100644 --- a/3rdparty/zlib/zutil.c +++ b/3rdparty/zlib/zutil.c @@ -136,7 +136,7 @@ const char * ZEXPORT zError(err) return ERR_MSG(err); } -#if defined(_WIN32_WCE) +#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 /* The Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. * Its value is always 0 and should not be used. diff --git a/3rdparty/zlib/zutil.h b/3rdparty/zlib/zutil.h index b079ea6a80..4774fc3235 100644 --- a/3rdparty/zlib/zutil.h +++ b/3rdparty/zlib/zutil.h @@ -169,11 +169,13 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX # if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif +# if _WIN32_WCE < 0x800 +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# endif # else # define fdopen(fd,type) _fdopen(fd,type) # endif diff --git a/CMakeLists.txt b/CMakeLists.txt index c9a5c42965..6ce583bc69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,35 +53,6 @@ if(NOT DEFINED CMAKE_INSTALL_PREFIX) endif() endif() -if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) - set(WINRT TRUE) -endif() - -if(WINRT) - add_definitions(-DWINRT -DNO_GETENV) - - # Making definitions available to other configurations and - # to filter dependency restrictions at compile time. - if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone) - set(WINRT_PHONE TRUE) - add_definitions(-DWINRT_PHONE) - elseif(CMAKE_SYSTEM_NAME MATCHES WindowsStore) - set(WINRT_STORE TRUE) - add_definitions(-DWINRT_STORE) - endif() - - if(CMAKE_SYSTEM_VERSION MATCHES 10) - set(WINRT_10 TRUE) - add_definitions(-DWINRT_10) - elseif(CMAKE_SYSTEM_VERSION MATCHES 8.1) - set(WINRT_8_1 TRUE) - add_definitions(-DWINRT_8_1) - elseif(CMAKE_SYSTEM_VERSION MATCHES 8.0) - set(WINRT_8_0 TRUE) - add_definitions(-DWINRT_8_0) - endif() -endif() - if(POLICY CMP0026) cmake_policy(SET CMP0026 NEW) endif() @@ -136,6 +107,39 @@ enable_testing() project(OpenCV CXX C) +if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore) + set(WINRT TRUE) +endif() + +if(WINRT OR WINCE) + add_definitions(-DNO_GETENV) +endif() + +if(WINRT) + add_definitions(-DWINRT) + + # Making definitions available to other configurations and + # to filter dependency restrictions at compile time. + if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone) + set(WINRT_PHONE TRUE) + add_definitions(-DWINRT_PHONE) + elseif(CMAKE_SYSTEM_NAME MATCHES WindowsStore) + set(WINRT_STORE TRUE) + add_definitions(-DWINRT_STORE) + endif() + + if(CMAKE_SYSTEM_VERSION MATCHES 10) + set(WINRT_10 TRUE) + add_definitions(-DWINRT_10) + elseif(CMAKE_SYSTEM_VERSION MATCHES 8.1) + set(WINRT_8_1 TRUE) + add_definitions(-DWINRT_8_1) + elseif(CMAKE_SYSTEM_VERSION MATCHES 8.0) + set(WINRT_8_0 TRUE) + add_definitions(-DWINRT_8_0) + endif() +endif() + if(MSVC) set(CMAKE_USE_RELATIVE_PATHS ON CACHE INTERNAL "" FORCE) endif() diff --git a/modules/core/include/opencv2/core/utils/filesystem.private.hpp b/modules/core/include/opencv2/core/utils/filesystem.private.hpp index deca4a4f95..b477cafc8e 100644 --- a/modules/core/include/opencv2/core/utils/filesystem.private.hpp +++ b/modules/core/include/opencv2/core/utils/filesystem.private.hpp @@ -9,7 +9,7 @@ #ifndef OPENCV_HAVE_FILESYSTEM_SUPPORT # if defined(__EMSCRIPTEN__) || defined(__native_client__) /* no support */ -# elif defined WINRT +# elif defined WINRT || defined _WIN32_WCE /* not supported */ # elif defined __ANDROID__ || defined __linux__ || defined _WIN32 || \ defined __FreeBSD__ || defined __bsdi__ || defined __HAIKU__ diff --git a/modules/core/src/glob.cpp b/modules/core/src/glob.cpp index 5aad2756f6..db054daa52 100644 --- a/modules/core/src/glob.cpp +++ b/modules/core/src/glob.cpp @@ -57,7 +57,7 @@ namespace struct DIR { -#ifdef WINRT +#if defined(WINRT) || defined(_WIN32_WCE) WIN32_FIND_DATAW data; #else WIN32_FIND_DATAA data; @@ -78,7 +78,7 @@ namespace { DIR* dir = new DIR; dir->ent.d_name = 0; -#ifdef WINRT +#if defined(WINRT) || defined(_WIN32_WCE) cv::String full_path = cv::String(path) + "\\*"; wchar_t wfull_path[MAX_PATH]; size_t copied = mbstowcs(wfull_path, full_path.c_str(), MAX_PATH); @@ -100,7 +100,7 @@ namespace dirent* readdir(DIR* dir) { -#ifdef WINRT +#if defined(WINRT) || defined(_WIN32_WCE) if (dir->ent.d_name != 0) { if (::FindNextFileW(dir->handle, &dir->data) != TRUE) diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp index bef36f31b0..79797bc801 100644 --- a/modules/core/src/ocl.cpp +++ b/modules/core/src/ocl.cpp @@ -1722,7 +1722,7 @@ static bool parseOpenCLDeviceConfiguration(const std::string& configurationStr, return true; } -#ifdef WINRT +#if defined WINRT || defined _WIN32_WCE static cl_device_id selectOpenCLDevice() { return NULL; diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 2c0038b80e..eec0082486 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -378,7 +378,7 @@ struct HWFeatures void initialize(void) { -#ifndef WINRT +#ifndef NO_GETENV if (getenv("OPENCV_DUMP_CONFIG")) { fprintf(stderr, "\nOpenCV build configuration is:\n%s\n", @@ -614,10 +614,10 @@ struct HWFeatures { bool dump = true; const char* disabled_features = -#ifndef WINRT - getenv("OPENCV_CPU_DISABLE"); -#else +#ifdef NO_GETENV NULL; +#else + getenv("OPENCV_CPU_DISABLE"); #endif if (disabled_features && disabled_features[0] != 0) { @@ -892,7 +892,7 @@ String format( const char* fmt, ... ) String tempfile( const char* suffix ) { String fname; -#ifndef WINRT +#ifndef NO_GETENV const char *temp_dir = getenv("OPENCV_TEMP_PATH"); #endif @@ -913,6 +913,20 @@ String tempfile( const char* suffix ) CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1)); fname = String(aname); RoUninitialize(); +#elif defined(_WIN32_WCE) + const auto kMaxPathSize = MAX_PATH+1; + wchar_t temp_dir[kMaxPathSize] = {0}; + wchar_t temp_file[kMaxPathSize] = {0}; + + ::GetTempPathW(kMaxPathSize, temp_dir); + + if(0 != ::GetTempFileNameW(temp_dir, L"ocv", 0, temp_file)) { + DeleteFileW(temp_file); + char aname[MAX_PATH]; + size_t copied = wcstombs(aname, temp_file, MAX_PATH); + CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1)); + fname = String(aname); + } #else char temp_dir2[MAX_PATH] = { 0 }; char temp_file[MAX_PATH] = { 0 }; diff --git a/platforms/wince/arm-wince-headless-overrides.cmake b/platforms/wince/arm-wince-headless-overrides.cmake new file mode 100644 index 0000000000..e658f8812e --- /dev/null +++ b/platforms/wince/arm-wince-headless-overrides.cmake @@ -0,0 +1,12 @@ +if(WINCE) + # CommCtrl.lib does not exist in headless WINCE Adding this will make CMake + # Try_Compile succeed and therefore also C/C++ ABI Detetection work + # https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/Platform/Windows- + # MSVC.cmake + set(CMAKE_C_STANDARD_LIBRARIES_INIT "coredll.lib") + set(CMAKE_CXX_STANDARD_LIBRARIES_INIT ${CMAKE_C_STANDARD_LIBRARIES_INIT}) + foreach(ID EXE SHARED MODULE) + string(APPEND CMAKE_${ID}_LINKER_FLAGS_INIT + " /NODEFAULTLIB:libc.lib /NODEFAULTLIB:oldnames.lib") + endforeach() +endif() diff --git a/platforms/wince/arm-wince.toolchain.cmake b/platforms/wince/arm-wince.toolchain.cmake new file mode 100644 index 0000000000..fc96d12eb9 --- /dev/null +++ b/platforms/wince/arm-wince.toolchain.cmake @@ -0,0 +1,35 @@ +set(CMAKE_SYSTEM_NAME WindowsCE) + +if(NOT CMAKE_SYSTEM_VERSION) + set(CMAKE_SYSTEM_VERSION 8.0) +endif() + +if(NOT CMAKE_SYSTEM_PROCESSOR) + set(CMAKE_SYSTEM_PROCESSOR armv7-a) +endif() + +if(NOT CMAKE_GENERATOR_TOOLSET) + set(CMAKE_GENERATOR_TOOLSET CE800) +endif() + +# Needed to make try_compile to succeed +if(BUILD_HEADLESS) + set(CMAKE_USER_MAKE_RULES_OVERRIDE + ${CMAKE_CURRENT_LIST_DIR}/arm-wince-headless-overrides.cmake) +endif() + +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +endif() + +if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +endif() + +if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +endif() diff --git a/platforms/wince/readme.md b/platforms/wince/readme.md new file mode 100644 index 0000000000..3b7ca2c764 --- /dev/null +++ b/platforms/wince/readme.md @@ -0,0 +1,62 @@ +# Building OpenCV from Source for Windows Embedded Compact (WINCE/WEC) + +## Requirements +CMake 3.1.0 or higher +Windows Embedded Compact SDK + +## Configuring +To configure CMake for Windows Embedded, specify Visual Studio 2013 as generator and the name of your installed SDK: + +`cmake -G "Visual Studio 12 2013" -A "MySDK WEC2013" -DCMAKE_TOOLCHAIN_FILE:FILEPATH=../platforms/wince/arm-wince.toolchain.cmake` + +If you are building for a headless WINCE, specify `-DBUILD_HEADLESS=ON` when configuring. This will remove the `commctrl.lib` dependency. + +If you are building for anything else than WINCE800, you need to specify that in the configuration step. Example: + +``` +-DCMAKE_SYSTEM_VERSION=7.0 -DCMAKE_GENERATOR_TOOLSET=CE700 -DCMAKE_SYSTEM_PROCESSOR=arm-v4 +``` + +For headless WEC2013, this configuration may not be limited to but is known to work: + +``` +-DBUILD_EXAMPLES=OFF ` +-DBUILD_opencv_apps=OFF ` +-DBUILD_opencv_calib3d=OFF ` +-DBUILD_opencv_highgui=OFF ` +-DBUILD_opencv_features2d=OFF ` +-DBUILD_opencv_flann=OFF ` +-DBUILD_opencv_ml=OFF ` +-DBUILD_opencv_objdetect=OFF ` +-DBUILD_opencv_photo=OFF ` +-DBUILD_opencv_shape=OFF ` +-DBUILD_opencv_stitching=OFF ` +-DBUILD_opencv_superres=OFF ` +-DBUILD_opencv_ts=OFF ` +-DBUILD_opencv_video=OFF ` +-DBUILD_opencv_videoio=OFF ` +-DBUILD_opencv_videostab=OFF ` +-DBUILD_opencv_dnn=OFF ` +-DBUILD_opencv_java=OFF ` +-DBUILD_opencv_python2=OFF ` +-DBUILD_opencv_python3=OFF ` +-DBUILD_opencv_java_bindings_generator=OFF ` +-DBUILD_opencv_python_bindings_generator=OFF ` +-DBUILD_TIFF=OFF ` +-DCV_TRACE=OFF ` +-DWITH_OPENCL=OFF ` +-DHAVE_OPENCL=OFF ` +-DWITH_QT=OFF ` +-DWITH_GTK=OFF ` +-DWITH_QUIRC=OFF ` +-DWITH_JASPER=OFF ` +-DWITH_WEBP=OFF ` +-DWITH_PROTOBUF=OFF ` +-DBUILD_SHARED_LIBS=OFF ` +-DWITH_OPENEXR=OFF ` +-DWITH_TIFF=OFF ` +``` + +## Building +You are required to build using Unicode: +`cmake --build . -- /p:CharacterSet=Unicode` From d2911a8d416440b33ce0fdc11291614ae216dc9d Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 24 Jun 2019 14:57:44 +0300 Subject: [PATCH 3/8] dnn: use OpenVINO 2019R2 defines --- cmake/OpenCVDetectInferenceEngine.cmake | 4 ++-- modules/dnn/src/op_inf_engine.hpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/OpenCVDetectInferenceEngine.cmake b/cmake/OpenCVDetectInferenceEngine.cmake index 5a4ddc6470..10901be8d2 100644 --- a/cmake/OpenCVDetectInferenceEngine.cmake +++ b/cmake/OpenCVDetectInferenceEngine.cmake @@ -87,9 +87,9 @@ endif() if(INF_ENGINE_TARGET) if(NOT INF_ENGINE_RELEASE) - message(WARNING "InferenceEngine version have not been set, 2019R1 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.") + message(WARNING "InferenceEngine version have not been set, 2019R2 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.") endif() - set(INF_ENGINE_RELEASE "2019010000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)") + set(INF_ENGINE_RELEASE "2019020000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)") set_target_properties(${INF_ENGINE_TARGET} PROPERTIES INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}" ) diff --git a/modules/dnn/src/op_inf_engine.hpp b/modules/dnn/src/op_inf_engine.hpp index c183cd0e81..f131d1788a 100644 --- a/modules/dnn/src/op_inf_engine.hpp +++ b/modules/dnn/src/op_inf_engine.hpp @@ -21,10 +21,11 @@ #define INF_ENGINE_RELEASE_2018R5 2018050000 #define INF_ENGINE_RELEASE_2019R1 2019010000 +#define INF_ENGINE_RELEASE_2019R2 2019020000 #ifndef INF_ENGINE_RELEASE -#warning("IE version have not been provided via command-line. Using 2019R1 by default") -#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2019R1 +#warning("IE version have not been provided via command-line. Using 2019R2 by default") +#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2019R2 #endif #define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000)) From 321c74ccd6077bdea1d47450ca4fe955cb5b6330 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 25 Jul 2019 17:15:59 +0300 Subject: [PATCH 4/8] objdetect: validate feature rectangle on reading --- modules/objdetect/src/cascadedetect.cpp | 43 +++++++++++++++++++++---- modules/objdetect/src/cascadedetect.hpp | 6 ++-- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/modules/objdetect/src/cascadedetect.cpp b/modules/objdetect/src/cascadedetect.cpp index 4b2078306f..bd62cd21a1 100644 --- a/modules/objdetect/src/cascadedetect.cpp +++ b/modules/objdetect/src/cascadedetect.cpp @@ -47,6 +47,10 @@ #include "opencv2/objdetect/objdetect_c.h" #include "opencl_kernels_objdetect.hpp" +#if defined(_MSC_VER) +# pragma warning(disable:4458) // declaration of 'origWinSize' hides class member +#endif + namespace cv { @@ -537,7 +541,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector& _s //---------------------------------------------- HaarEvaluator --------------------------------------- -bool HaarEvaluator::Feature :: read( const FileNode& node ) +bool HaarEvaluator::Feature::read(const FileNode& node, const Size& origWinSize) { FileNode rnode = node[CC_RECTS]; FileNodeIterator it = rnode.begin(), it_end = rnode.end(); @@ -549,11 +553,23 @@ bool HaarEvaluator::Feature :: read( const FileNode& node ) rect[ri].weight = 0.f; } + const int W = origWinSize.width; + const int H = origWinSize.height; + for(ri = 0; it != it_end; ++it, ri++) { FileNodeIterator it2 = (*it).begin(); - it2 >> rect[ri].r.x >> rect[ri].r.y >> - rect[ri].r.width >> rect[ri].r.height >> rect[ri].weight; + Feature::RectWeigth& rw = rect[ri]; + it2 >> rw.r.x >> rw.r.y >> rw.r.width >> rw.r.height >> rw.weight; + // input validation + { + CV_CheckGE(rw.r.x, 0, "Invalid HAAR feature"); + CV_CheckGE(rw.r.y, 0, "Invalid HAAR feature"); + CV_CheckLT(rw.r.x, W, "Invalid HAAR feature"); // necessary for overflow checks + CV_CheckLT(rw.r.y, H, "Invalid HAAR feature"); // necessary for overflow checks + CV_CheckLE(rw.r.x + rw.r.width, W, "Invalid HAAR feature"); + CV_CheckLE(rw.r.y + rw.r.height, H, "Invalid HAAR feature"); + } } tilted = (int)node[CC_TILTED] != 0; @@ -598,7 +614,7 @@ bool HaarEvaluator::read(const FileNode& node, Size _origWinSize) for(i = 0; i < n; i++, ++it) { - if(!ff[i].read(*it)) + if(!ff[i].read(*it, _origWinSize)) return false; if( ff[i].tilted ) hasTiltedFeatures = true; @@ -759,11 +775,24 @@ int HaarEvaluator::getSquaresOffset() const } //---------------------------------------------- LBPEvaluator ------------------------------------- -bool LBPEvaluator::Feature :: read(const FileNode& node ) +bool LBPEvaluator::Feature::read(const FileNode& node, const Size& origWinSize) { FileNode rnode = node[CC_RECT]; FileNodeIterator it = rnode.begin(); it >> rect.x >> rect.y >> rect.width >> rect.height; + + const int W = origWinSize.width; + const int H = origWinSize.height; + // input validation + { + CV_CheckGE(rect.x, 0, "Invalid LBP feature"); + CV_CheckGE(rect.y, 0, "Invalid LBP feature"); + CV_CheckLT(rect.x, W, "Invalid LBP feature"); + CV_CheckLT(rect.y, H, "Invalid LBP feature"); + CV_CheckLE(rect.x + rect.width, W, "Invalid LBP feature"); + CV_CheckLE(rect.y + rect.height, H, "Invalid LBP feature"); + } + return true; } @@ -797,7 +826,7 @@ bool LBPEvaluator::read( const FileNode& node, Size _origWinSize ) std::vector& ff = *features; for(int i = 0; it != it_end; ++it, i++) { - if(!ff[i].read(*it)) + if(!ff[i].read(*it, _origWinSize)) return false; } nchannels = 1; @@ -1477,6 +1506,8 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root) origWinSize.width = (int)root[CC_WIDTH]; origWinSize.height = (int)root[CC_HEIGHT]; CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 ); + CV_CheckLE(origWinSize.width, 1000000, "Invalid window size (too large)"); + CV_CheckLE(origWinSize.height, 1000000, "Invalid window size (too large)"); // load feature params FileNode fn = root[CC_FEATURE_PARAMS]; diff --git a/modules/objdetect/src/cascadedetect.hpp b/modules/objdetect/src/cascadedetect.hpp index f9910530b9..d9a288fcdd 100644 --- a/modules/objdetect/src/cascadedetect.hpp +++ b/modules/objdetect/src/cascadedetect.hpp @@ -317,12 +317,12 @@ public: struct Feature { Feature(); - bool read( const FileNode& node ); + bool read(const FileNode& node, const Size& origWinSize); bool tilted; enum { RECT_NUM = 3 }; - struct + struct RectWeigth { Rect r; float weight; @@ -412,7 +412,7 @@ public: Feature( int x, int y, int _block_w, int _block_h ) : rect(x, y, _block_w, _block_h) {} - bool read(const FileNode& node ); + bool read(const FileNode& node, const Size& origWinSize); Rect rect; // weight and height for block }; From 416c693b3f3af9be994798087aa4587635de4fe7 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 25 Jul 2019 06:57:49 +0000 Subject: [PATCH 5/8] dnn(test): OpenVINO 2019R2 --- modules/dnn/perf/perf_net.cpp | 13 +++++++++++++ modules/dnn/test/test_backends.cpp | 19 +++++++++++++++++++ modules/dnn/test/test_common.hpp | 1 + modules/dnn/test/test_common.impl.hpp | 7 +++++-- modules/dnn/test/test_ie_models.cpp | 22 ++++++++++++++++++++++ modules/dnn/test/test_tf_importer.cpp | 27 ++++++++++++++++++++------- 6 files changed, 80 insertions(+), 9 deletions(-) diff --git a/modules/dnn/perf/perf_net.cpp b/modules/dnn/perf/perf_net.cpp index bba1eb5dae..cd357bc343 100644 --- a/modules/dnn/perf/perf_net.cpp +++ b/modules/dnn/perf/perf_net.cpp @@ -142,6 +142,8 @@ PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow) { if (backend == DNN_BACKEND_HALIDE) throw SkipTestException(""); + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + throw SkipTestException(""); processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "ssd_mobilenet_v1_coco_2017_11_17.pbtxt", "", Mat(cv::Size(300, 300), CV_32FC3)); } @@ -150,6 +152,8 @@ PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow) { if (backend == DNN_BACKEND_HALIDE) throw SkipTestException(""); + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + throw SkipTestException(""); processNet("dnn/ssd_mobilenet_v2_coco_2018_03_29.pb", "ssd_mobilenet_v2_coco_2018_03_29.pbtxt", "", Mat(cv::Size(300, 300), CV_32FC3)); } @@ -190,6 +194,11 @@ PERF_TEST_P_(DNNTestNetwork, Inception_v2_SSD_TensorFlow) && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) throw SkipTestException("Test is disabled for MyriadX"); #endif +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000) + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + throw SkipTestException("Test is disabled for Myriad in OpenVINO 2019R2"); +#endif + processNet("dnn/ssd_inception_v2_coco_2017_11_17.pb", "ssd_inception_v2_coco_2017_11_17.pbtxt", "", Mat(cv::Size(300, 300), CV_32FC3)); } @@ -223,6 +232,10 @@ PERF_TEST_P_(DNNTestNetwork, Inception_v2_Faster_RCNN) #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019010000) if (backend == DNN_BACKEND_INFERENCE_ENGINE) throw SkipTestException("Test is disabled in OpenVINO 2019R1"); +#endif +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000) + if (backend == DNN_BACKEND_INFERENCE_ENGINE) + throw SkipTestException("Test is disabled in OpenVINO 2019R2"); #endif if (backend == DNN_BACKEND_HALIDE || (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) || diff --git a/modules/dnn/test/test_backends.cpp b/modules/dnn/test/test_backends.cpp index 831f754bc7..ff77a0b330 100644 --- a/modules/dnn/test/test_backends.cpp +++ b/modules/dnn/test/test_backends.cpp @@ -205,6 +205,11 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow) applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB); if (backend == DNN_BACKEND_HALIDE) applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE); +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000) + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2); +#endif + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false); float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.095 : 0.0; @@ -224,6 +229,11 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height) && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); #endif +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000) + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2); +#endif + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f, Size(300, 560), Scalar(), false); float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.012 : 0.0; @@ -238,6 +248,11 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow) applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB); if (backend == DNN_BACKEND_HALIDE) applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE); +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000) + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2); +#endif + Mat sample = imread(findDataFile("dnn/street.png")); Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false); float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.013 : 2e-5; @@ -355,6 +370,10 @@ TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow) if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); +#endif +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000) + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2); #endif if (backend == DNN_BACKEND_HALIDE) applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE); diff --git a/modules/dnn/test/test_common.hpp b/modules/dnn/test/test_common.hpp index 03acac38eb..d504a316b5 100644 --- a/modules/dnn/test/test_common.hpp +++ b/modules/dnn/test/test_common.hpp @@ -18,6 +18,7 @@ #define CV_TEST_TAG_DNN_SKIP_IE_2018R5 "dnn_skip_ie_2018r5" #define CV_TEST_TAG_DNN_SKIP_IE_2019R1 "dnn_skip_ie_2019r1" #define CV_TEST_TAG_DNN_SKIP_IE_2019R1_1 "dnn_skip_ie_2019r1_1" +#define CV_TEST_TAG_DNN_SKIP_IE_2019R2 "dnn_skip_ie_2019r2" #define CV_TEST_TAG_DNN_SKIP_IE_OPENCL "dnn_skip_ie_ocl" #define CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16 "dnn_skip_ie_ocl_fp16" #define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2 "dnn_skip_ie_myriad2" diff --git a/modules/dnn/test/test_common.impl.hpp b/modules/dnn/test/test_common.impl.hpp index ee0a3a66b5..4b19a6a025 100644 --- a/modules/dnn/test/test_common.impl.hpp +++ b/modules/dnn/test/test_common.impl.hpp @@ -310,8 +310,11 @@ void initDNNTests() CV_TEST_TAG_DNN_SKIP_IE_2018R5, #elif INF_ENGINE_VER_MAJOR_EQ(2019010000) CV_TEST_TAG_DNN_SKIP_IE_2019R1, -#elif INF_ENGINE_VER_MAJOR_EQ(2019010100) - CV_TEST_TAG_DNN_SKIP_IE_2019R1_1 +# if INF_ENGINE_RELEASE == 2019010100 + CV_TEST_TAG_DNN_SKIP_IE_2019R1_1, +# endif +#elif INF_ENGINE_VER_MAJOR_EQ(2019020000) + CV_TEST_TAG_DNN_SKIP_IE_2019R2, #endif CV_TEST_TAG_DNN_SKIP_IE ); diff --git a/modules/dnn/test/test_ie_models.cpp b/modules/dnn/test/test_ie_models.cpp index be463789e6..26983707b1 100644 --- a/modules/dnn/test/test_ie_models.cpp +++ b/modules/dnn/test/test_ie_models.cpp @@ -9,10 +9,32 @@ #ifdef HAVE_INF_ENGINE #include + +// +// Synchronize headers include statements with src/op_inf_engine.hpp +// +//#define INFERENCE_ENGINE_DEPRECATED // turn off deprecation warnings from IE +//there is no way to suppress warnigns from IE only at this moment, so we are forced to suppress warnings globally +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#ifdef _MSC_VER +#pragma warning(disable: 4996) // was declared deprecated +#endif + +#if defined(__GNUC__) +#pragma GCC visibility push(default) +#endif + #include #include #include +#if defined(__GNUC__) +#pragma GCC visibility pop +#endif + + namespace opencv_test { namespace { static void initDLDTDataPath() diff --git a/modules/dnn/test/test_tf_importer.cpp b/modules/dnn/test/test_tf_importer.cpp index 8fcf81245a..de42bf3b04 100644 --- a/modules/dnn/test/test_tf_importer.cpp +++ b/modules/dnn/test/test_tf_importer.cpp @@ -357,11 +357,11 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD) #if defined(INF_ENGINE_RELEASE) if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) { -#if INF_ENGINE_VER_MAJOR_GE(2019010000) +#if INF_ENGINE_VER_MAJOR_EQ(2019010000) if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); #else - applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD); + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD); #endif } #endif @@ -395,12 +395,16 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD) TEST_P(Test_TensorFlow_nets, Inception_v2_SSD) { applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB); - #if defined(INF_ENGINE_RELEASE) - if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD - && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X - ) - applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + { +#if INF_ENGINE_VER_MAJOR_LE(2019010000) + if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X); +#else + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD); +#endif + } #endif checkBackend(); @@ -432,6 +436,11 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_SSD) TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD) { +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000) + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2); +#endif + checkBackend(); std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt"); std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false); @@ -506,6 +515,10 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN) if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)) applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16); #endif +#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000) + if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD) + applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2); +#endif checkBackend(); std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt"); From a2125594ea942ce12604ddebbd503cfa335f7ecd Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Mon, 22 Jul 2019 12:18:57 +0300 Subject: [PATCH 6/8] Fix false positives of face detection network for large faces --- modules/dnn/test/test_caffe_importer.cpp | 25 +- samples/dnn/face_detector/deploy.prototxt | 4 +- .../dnn/face_detector/deploy_lowres.prototxt | 1790 +++++++++++++++++ samples/dnn/js_face_recognition.html | 2 +- 4 files changed, 1817 insertions(+), 4 deletions(-) create mode 100644 samples/dnn/face_detector/deploy_lowres.prototxt diff --git a/modules/dnn/test/test_caffe_importer.cpp b/modules/dnn/test/test_caffe_importer.cpp index 9588015a1e..1a79f6a562 100644 --- a/modules/dnn/test/test_caffe_importer.cpp +++ b/modules/dnn/test/test_caffe_importer.cpp @@ -561,7 +561,7 @@ TEST(Test_Caffe, shared_weights) typedef testing::TestWithParam > opencv_face_detector; TEST_P(opencv_face_detector, Accuracy) { - std::string proto = findDataFile("dnn/opencv_face_detector.prototxt", false); + std::string proto = findDataFile("dnn/opencv_face_detector.prototxt"); std::string model = findDataFile(get<0>(GetParam()), false); dnn::Target targetId = (dnn::Target)(int)get<1>(GetParam()); @@ -584,6 +584,29 @@ TEST_P(opencv_face_detector, Accuracy) 0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801); normAssertDetections(ref, out, "", 0.5, 1e-5, 2e-4); } + +// False positives bug for large faces: https://github.com/opencv/opencv/issues/15106 +TEST_P(opencv_face_detector, issue_15106) +{ + std::string proto = findDataFile("dnn/opencv_face_detector.prototxt"); + std::string model = findDataFile(get<0>(GetParam()), false); + dnn::Target targetId = (dnn::Target)(int)get<1>(GetParam()); + + Net net = readNetFromCaffe(proto, model); + Mat img = imread(findDataFile("cv/shared/lena.png")); + img = img.rowRange(img.rows / 4, 3 * img.rows / 4).colRange(img.cols / 4, 3 * img.cols / 4); + Mat blob = blobFromImage(img, 1.0, Size(300, 300), Scalar(104.0, 177.0, 123.0), false, false); + + net.setPreferableBackend(DNN_BACKEND_OPENCV); + net.setPreferableTarget(targetId); + + net.setInput(blob); + // Output has shape 1x1xNx7 where N - number of detections. + // An every detection is a vector of values [id, classId, confidence, left, top, right, bottom] + Mat out = net.forward(); + Mat ref = (Mat_(1, 7) << 0, 1, 0.9149431, 0.30424616, 0.26964942, 0.88733053, 0.99815309); + normAssertDetections(ref, out, "", 0.2, 6e-5, 1e-4); +} INSTANTIATE_TEST_CASE_P(Test_Caffe, opencv_face_detector, Combine( Values("dnn/opencv_face_detector.caffemodel", diff --git a/samples/dnn/face_detector/deploy.prototxt b/samples/dnn/face_detector/deploy.prototxt index 905580ee46..8b7ba1aa20 100644 --- a/samples/dnn/face_detector/deploy.prototxt +++ b/samples/dnn/face_detector/deploy.prototxt @@ -892,7 +892,7 @@ layer { } convolution_param { num_output: 128 - pad: 1 + pad: 0 kernel_size: 3 stride: 1 weight_filler { @@ -958,7 +958,7 @@ layer { } convolution_param { num_output: 128 - pad: 1 + pad: 0 kernel_size: 3 stride: 1 weight_filler { diff --git a/samples/dnn/face_detector/deploy_lowres.prototxt b/samples/dnn/face_detector/deploy_lowres.prototxt new file mode 100644 index 0000000000..5a1520d850 --- /dev/null +++ b/samples/dnn/face_detector/deploy_lowres.prototxt @@ -0,0 +1,1790 @@ +# This file is based on deploy.prototxt but might be used for input resolution less than 300x300 +input: "data" +input_shape { + dim: 1 + dim: 3 + dim: 300 + dim: 300 +} + +layer { + name: "data_bn" + type: "BatchNorm" + bottom: "data" + top: "data_bn" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "data_scale" + type: "Scale" + bottom: "data_bn" + top: "data_bn" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "conv1_h" + type: "Convolution" + bottom: "data_bn" + top: "conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + pad: 3 + kernel_size: 7 + stride: 2 + weight_filler { + type: "msra" + variance_norm: FAN_OUT + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "conv1_bn_h" + type: "BatchNorm" + bottom: "conv1_h" + top: "conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "conv1_scale_h" + type: "Scale" + bottom: "conv1_h" + top: "conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "conv1_relu" + type: "ReLU" + bottom: "conv1_h" + top: "conv1_h" +} +layer { + name: "conv1_pool" + type: "Pooling" + bottom: "conv1_h" + top: "conv1_pool" + pooling_param { + kernel_size: 3 + stride: 2 + } +} +layer { + name: "layer_64_1_conv1_h" + type: "Convolution" + bottom: "conv1_pool" + top: "layer_64_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_64_1_bn2_h" + type: "BatchNorm" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_64_1_scale2_h" + type: "Scale" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_64_1_relu2" + type: "ReLU" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv1_h" +} +layer { + name: "layer_64_1_conv2_h" + type: "Convolution" + bottom: "layer_64_1_conv1_h" + top: "layer_64_1_conv2_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 32 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_64_1_sum" + type: "Eltwise" + bottom: "layer_64_1_conv2_h" + bottom: "conv1_pool" + top: "layer_64_1_sum" +} +layer { + name: "layer_128_1_bn1_h" + type: "BatchNorm" + bottom: "layer_64_1_sum" + top: "layer_128_1_bn1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_128_1_scale1_h" + type: "Scale" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_bn1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_128_1_relu1" + type: "ReLU" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_bn1_h" +} +layer { + name: "layer_128_1_conv1_h" + type: "Convolution" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_bn2" + type: "BatchNorm" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_128_1_scale2" + type: "Scale" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_128_1_relu2" + type: "ReLU" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv1_h" +} +layer { + name: "layer_128_1_conv2" + type: "Convolution" + bottom: "layer_128_1_conv1_h" + top: "layer_128_1_conv2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_conv_expand_h" + type: "Convolution" + bottom: "layer_128_1_bn1_h" + top: "layer_128_1_conv_expand_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_128_1_sum" + type: "Eltwise" + bottom: "layer_128_1_conv2" + bottom: "layer_128_1_conv_expand_h" + top: "layer_128_1_sum" +} +layer { + name: "layer_256_1_bn1" + type: "BatchNorm" + bottom: "layer_128_1_sum" + top: "layer_256_1_bn1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_256_1_scale1" + type: "Scale" + bottom: "layer_256_1_bn1" + top: "layer_256_1_bn1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_256_1_relu1" + type: "ReLU" + bottom: "layer_256_1_bn1" + top: "layer_256_1_bn1" +} +layer { + name: "layer_256_1_conv1" + type: "Convolution" + bottom: "layer_256_1_bn1" + top: "layer_256_1_conv1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_bn2" + type: "BatchNorm" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_256_1_scale2" + type: "Scale" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_256_1_relu2" + type: "ReLU" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv1" +} +layer { + name: "layer_256_1_conv2" + type: "Convolution" + bottom: "layer_256_1_conv1" + top: "layer_256_1_conv2" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_conv_expand" + type: "Convolution" + bottom: "layer_256_1_bn1" + top: "layer_256_1_conv_expand" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_256_1_sum" + type: "Eltwise" + bottom: "layer_256_1_conv2" + bottom: "layer_256_1_conv_expand" + top: "layer_256_1_sum" +} +layer { + name: "layer_512_1_bn1" + type: "BatchNorm" + bottom: "layer_256_1_sum" + top: "layer_512_1_bn1" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_512_1_scale1" + type: "Scale" + bottom: "layer_512_1_bn1" + top: "layer_512_1_bn1" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_512_1_relu1" + type: "ReLU" + bottom: "layer_512_1_bn1" + top: "layer_512_1_bn1" +} +layer { + name: "layer_512_1_conv1_h" + type: "Convolution" + bottom: "layer_512_1_bn1" + top: "layer_512_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 128 + bias_term: false + pad: 1 + kernel_size: 3 + stride: 1 # 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_bn2_h" + type: "BatchNorm" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "layer_512_1_scale2_h" + type: "Scale" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "layer_512_1_relu2" + type: "ReLU" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv1_h" +} +layer { + name: "layer_512_1_conv2_h" + type: "Convolution" + bottom: "layer_512_1_conv1_h" + top: "layer_512_1_conv2_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 2 # 1 + kernel_size: 3 + stride: 1 + dilation: 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_conv_expand_h" + type: "Convolution" + bottom: "layer_512_1_bn1" + top: "layer_512_1_conv_expand_h" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + convolution_param { + num_output: 256 + bias_term: false + pad: 0 + kernel_size: 1 + stride: 1 # 2 + weight_filler { + type: "msra" + } + bias_filler { + type: "constant" + value: 0.0 + } + } +} +layer { + name: "layer_512_1_sum" + type: "Eltwise" + bottom: "layer_512_1_conv2_h" + bottom: "layer_512_1_conv_expand_h" + top: "layer_512_1_sum" +} +layer { + name: "last_bn_h" + type: "BatchNorm" + bottom: "layer_512_1_sum" + top: "layer_512_1_sum" + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } + param { + lr_mult: 0.0 + } +} +layer { + name: "last_scale_h" + type: "Scale" + bottom: "layer_512_1_sum" + top: "layer_512_1_sum" + param { + lr_mult: 1.0 + decay_mult: 1.0 + } + param { + lr_mult: 2.0 + decay_mult: 1.0 + } + scale_param { + bias_term: true + } +} +layer { + name: "last_relu" + type: "ReLU" + bottom: "layer_512_1_sum" + top: "fc7" +} + +layer { + name: "conv6_1_h" + type: "Convolution" + bottom: "fc7" + top: "conv6_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_1_relu" + type: "ReLU" + bottom: "conv6_1_h" + top: "conv6_1_h" +} +layer { + name: "conv6_2_h" + type: "Convolution" + bottom: "conv6_1_h" + top: "conv6_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_relu" + type: "ReLU" + bottom: "conv6_2_h" + top: "conv6_2_h" +} +layer { + name: "conv7_1_h" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv7_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_1_relu" + type: "ReLU" + bottom: "conv7_1_h" + top: "conv7_1_h" +} +layer { + name: "conv7_2_h" + type: "Convolution" + bottom: "conv7_1_h" + top: "conv7_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + stride: 2 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_relu" + type: "ReLU" + bottom: "conv7_2_h" + top: "conv7_2_h" +} +layer { + name: "conv8_1_h" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv8_1_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 0 + kernel_size: 1 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_1_relu" + type: "ReLU" + bottom: "conv8_1_h" + top: "conv8_1_h" +} +layer { + name: "conv8_2_h" + type: "Convolution" + bottom: "conv8_1_h" + top: "conv8_2_h" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_relu" + type: "ReLU" + bottom: "conv8_2_h" + top: "conv8_2_h" +} +# layer { +# name: "conv9_1_h" +# type: "Convolution" +# bottom: "conv8_2_h" +# top: "conv9_1_h" +# param { +# lr_mult: 1 +# decay_mult: 1 +# } +# param { +# lr_mult: 2 +# decay_mult: 0 +# } +# convolution_param { +# num_output: 64 +# pad: 0 +# kernel_size: 1 +# stride: 1 +# weight_filler { +# type: "xavier" +# } +# bias_filler { +# type: "constant" +# value: 0 +# } +# } +# } +# layer { +# name: "conv9_1_relu" +# type: "ReLU" +# bottom: "conv9_1_h" +# top: "conv9_1_h" +# } +# layer { +# name: "conv9_2_h" +# type: "Convolution" +# bottom: "conv9_1_h" +# top: "conv9_2_h" +# param { +# lr_mult: 1 +# decay_mult: 1 +# } +# param { +# lr_mult: 2 +# decay_mult: 0 +# } +# convolution_param { +# num_output: 128 +# pad: 0 +# kernel_size: 3 +# stride: 1 +# weight_filler { +# type: "xavier" +# } +# bias_filler { +# type: "constant" +# value: 0 +# } +# } +# } +# layer { +# name: "conv9_2_relu" +# type: "ReLU" +# bottom: "conv9_2_h" +# top: "conv9_2_h" +# } +layer { + name: "conv4_3_norm" + type: "Normalize" + bottom: "layer_256_1_bn1" + top: "conv4_3_norm" + norm_param { + across_spatial: false + scale_filler { + type: "constant" + value: 20 + } + channel_shared: false + } +} +layer { + name: "conv4_3_norm_mbox_loc" + type: "Convolution" + bottom: "conv4_3_norm" + top: "conv4_3_norm_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv4_3_norm_mbox_loc_perm" + type: "Permute" + bottom: "conv4_3_norm_mbox_loc" + top: "conv4_3_norm_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv4_3_norm_mbox_loc_flat" + type: "Flatten" + bottom: "conv4_3_norm_mbox_loc_perm" + top: "conv4_3_norm_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv4_3_norm_mbox_conf" + type: "Convolution" + bottom: "conv4_3_norm" + top: "conv4_3_norm_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 8 # 84 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv4_3_norm_mbox_conf_perm" + type: "Permute" + bottom: "conv4_3_norm_mbox_conf" + top: "conv4_3_norm_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv4_3_norm_mbox_conf_flat" + type: "Flatten" + bottom: "conv4_3_norm_mbox_conf_perm" + top: "conv4_3_norm_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv4_3_norm_mbox_priorbox" + type: "PriorBox" + bottom: "conv4_3_norm" + bottom: "data" + top: "conv4_3_norm_mbox_priorbox" + prior_box_param { + min_size: 30.0 + max_size: 60.0 + aspect_ratio: 2 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 8 + offset: 0.5 + } +} +layer { + name: "fc7_mbox_loc" + type: "Convolution" + bottom: "fc7" + top: "fc7_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "fc7_mbox_loc_perm" + type: "Permute" + bottom: "fc7_mbox_loc" + top: "fc7_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "fc7_mbox_loc_flat" + type: "Flatten" + bottom: "fc7_mbox_loc_perm" + top: "fc7_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "fc7_mbox_conf" + type: "Convolution" + bottom: "fc7" + top: "fc7_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "fc7_mbox_conf_perm" + type: "Permute" + bottom: "fc7_mbox_conf" + top: "fc7_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "fc7_mbox_conf_flat" + type: "Flatten" + bottom: "fc7_mbox_conf_perm" + top: "fc7_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "fc7_mbox_priorbox" + type: "PriorBox" + bottom: "fc7" + bottom: "data" + top: "fc7_mbox_priorbox" + prior_box_param { + min_size: 60.0 + max_size: 111.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 16 + offset: 0.5 + } +} +layer { + name: "conv6_2_mbox_loc" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv6_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_mbox_loc_perm" + type: "Permute" + bottom: "conv6_2_mbox_loc" + top: "conv6_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv6_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv6_2_mbox_loc_perm" + top: "conv6_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv6_2_mbox_conf" + type: "Convolution" + bottom: "conv6_2_h" + top: "conv6_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv6_2_mbox_conf_perm" + type: "Permute" + bottom: "conv6_2_mbox_conf" + top: "conv6_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv6_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv6_2_mbox_conf_perm" + top: "conv6_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv6_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv6_2_h" + bottom: "data" + top: "conv6_2_mbox_priorbox" + prior_box_param { + min_size: 111.0 + max_size: 162.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 32 + offset: 0.5 + } +} +layer { + name: "conv7_2_mbox_loc" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv7_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 24 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_mbox_loc_perm" + type: "Permute" + bottom: "conv7_2_mbox_loc" + top: "conv7_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv7_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv7_2_mbox_loc_perm" + top: "conv7_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv7_2_mbox_conf" + type: "Convolution" + bottom: "conv7_2_h" + top: "conv7_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 12 # 126 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv7_2_mbox_conf_perm" + type: "Permute" + bottom: "conv7_2_mbox_conf" + top: "conv7_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv7_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv7_2_mbox_conf_perm" + top: "conv7_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv7_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv7_2_h" + bottom: "data" + top: "conv7_2_mbox_priorbox" + prior_box_param { + min_size: 162.0 + max_size: 213.0 + aspect_ratio: 2 + aspect_ratio: 3 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 64 + offset: 0.5 + } +} +layer { + name: "conv8_2_mbox_loc" + type: "Convolution" + bottom: "conv8_2_h" + top: "conv8_2_mbox_loc" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 16 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_mbox_loc_perm" + type: "Permute" + bottom: "conv8_2_mbox_loc" + top: "conv8_2_mbox_loc_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv8_2_mbox_loc_flat" + type: "Flatten" + bottom: "conv8_2_mbox_loc_perm" + top: "conv8_2_mbox_loc_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv8_2_mbox_conf" + type: "Convolution" + bottom: "conv8_2_h" + top: "conv8_2_mbox_conf" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 8 # 84 + pad: 1 + kernel_size: 3 + stride: 1 + weight_filler { + type: "xavier" + } + bias_filler { + type: "constant" + value: 0 + } + } +} +layer { + name: "conv8_2_mbox_conf_perm" + type: "Permute" + bottom: "conv8_2_mbox_conf" + top: "conv8_2_mbox_conf_perm" + permute_param { + order: 0 + order: 2 + order: 3 + order: 1 + } +} +layer { + name: "conv8_2_mbox_conf_flat" + type: "Flatten" + bottom: "conv8_2_mbox_conf_perm" + top: "conv8_2_mbox_conf_flat" + flatten_param { + axis: 1 + } +} +layer { + name: "conv8_2_mbox_priorbox" + type: "PriorBox" + bottom: "conv8_2_h" + bottom: "data" + top: "conv8_2_mbox_priorbox" + prior_box_param { + min_size: 213.0 + max_size: 264.0 + aspect_ratio: 2 + flip: true + clip: false + variance: 0.1 + variance: 0.1 + variance: 0.2 + variance: 0.2 + step: 100 + offset: 0.5 + } +} +# layer { +# name: "conv9_2_mbox_loc" +# type: "Convolution" +# bottom: "conv9_2_h" +# top: "conv9_2_mbox_loc" +# param { +# lr_mult: 1 +# decay_mult: 1 +# } +# param { +# lr_mult: 2 +# decay_mult: 0 +# } +# convolution_param { +# num_output: 16 +# pad: 1 +# kernel_size: 3 +# stride: 1 +# weight_filler { +# type: "xavier" +# } +# bias_filler { +# type: "constant" +# value: 0 +# } +# } +# } +# layer { +# name: "conv9_2_mbox_loc_perm" +# type: "Permute" +# bottom: "conv9_2_mbox_loc" +# top: "conv9_2_mbox_loc_perm" +# permute_param { +# order: 0 +# order: 2 +# order: 3 +# order: 1 +# } +# } +# layer { +# name: "conv9_2_mbox_loc_flat" +# type: "Flatten" +# bottom: "conv9_2_mbox_loc_perm" +# top: "conv9_2_mbox_loc_flat" +# flatten_param { +# axis: 1 +# } +# } +# layer { +# name: "conv9_2_mbox_conf" +# type: "Convolution" +# bottom: "conv9_2_h" +# top: "conv9_2_mbox_conf" +# param { +# lr_mult: 1 +# decay_mult: 1 +# } +# param { +# lr_mult: 2 +# decay_mult: 0 +# } +# convolution_param { +# num_output: 8 # 84 +# pad: 1 +# kernel_size: 3 +# stride: 1 +# weight_filler { +# type: "xavier" +# } +# bias_filler { +# type: "constant" +# value: 0 +# } +# } +# } +# layer { +# name: "conv9_2_mbox_conf_perm" +# type: "Permute" +# bottom: "conv9_2_mbox_conf" +# top: "conv9_2_mbox_conf_perm" +# permute_param { +# order: 0 +# order: 2 +# order: 3 +# order: 1 +# } +# } +# layer { +# name: "conv9_2_mbox_conf_flat" +# type: "Flatten" +# bottom: "conv9_2_mbox_conf_perm" +# top: "conv9_2_mbox_conf_flat" +# flatten_param { +# axis: 1 +# } +# } +# layer { +# name: "conv9_2_mbox_priorbox" +# type: "PriorBox" +# bottom: "conv9_2_h" +# bottom: "data" +# top: "conv9_2_mbox_priorbox" +# prior_box_param { +# min_size: 264.0 +# max_size: 315.0 +# aspect_ratio: 2 +# flip: true +# clip: false +# variance: 0.1 +# variance: 0.1 +# variance: 0.2 +# variance: 0.2 +# step: 300 +# offset: 0.5 +# } +# } +layer { + name: "mbox_loc" + type: "Concat" + bottom: "conv4_3_norm_mbox_loc_flat" + bottom: "fc7_mbox_loc_flat" + bottom: "conv6_2_mbox_loc_flat" + bottom: "conv7_2_mbox_loc_flat" + bottom: "conv8_2_mbox_loc_flat" + # bottom: "conv9_2_mbox_loc_flat" + top: "mbox_loc" + concat_param { + axis: 1 + } +} +layer { + name: "mbox_conf" + type: "Concat" + bottom: "conv4_3_norm_mbox_conf_flat" + bottom: "fc7_mbox_conf_flat" + bottom: "conv6_2_mbox_conf_flat" + bottom: "conv7_2_mbox_conf_flat" + bottom: "conv8_2_mbox_conf_flat" + # bottom: "conv9_2_mbox_conf_flat" + top: "mbox_conf" + concat_param { + axis: 1 + } +} +layer { + name: "mbox_priorbox" + type: "Concat" + bottom: "conv4_3_norm_mbox_priorbox" + bottom: "fc7_mbox_priorbox" + bottom: "conv6_2_mbox_priorbox" + bottom: "conv7_2_mbox_priorbox" + bottom: "conv8_2_mbox_priorbox" + # bottom: "conv9_2_mbox_priorbox" + top: "mbox_priorbox" + concat_param { + axis: 2 + } +} + +layer { + name: "mbox_conf_reshape" + type: "Reshape" + bottom: "mbox_conf" + top: "mbox_conf_reshape" + reshape_param { + shape { + dim: 0 + dim: -1 + dim: 2 + } + } +} +layer { + name: "mbox_conf_softmax" + type: "Softmax" + bottom: "mbox_conf_reshape" + top: "mbox_conf_softmax" + softmax_param { + axis: 2 + } +} +layer { + name: "mbox_conf_flatten" + type: "Flatten" + bottom: "mbox_conf_softmax" + top: "mbox_conf_flatten" + flatten_param { + axis: 1 + } +} + +layer { + name: "detection_out" + type: "DetectionOutput" + bottom: "mbox_loc" + bottom: "mbox_conf_flatten" + bottom: "mbox_priorbox" + top: "detection_out" + include { + phase: TEST + } + detection_output_param { + num_classes: 2 + share_location: true + background_label_id: 0 + nms_param { + nms_threshold: 0.45 + top_k: 400 + } + code_type: CENTER_SIZE + keep_top_k: 200 + confidence_threshold: 0.01 + } +} diff --git a/samples/dnn/js_face_recognition.html b/samples/dnn/js_face_recognition.html index ded3550c59..27da6b5f4d 100644 --- a/samples/dnn/js_face_recognition.html +++ b/samples/dnn/js_face_recognition.html @@ -69,7 +69,7 @@ function recognize(face) { function loadModels(callback) { var utils = new Utils(''); - var proto = 'https://raw.githubusercontent.com/opencv/opencv/3.4/samples/dnn/face_detector/deploy.prototxt'; + var proto = 'https://raw.githubusercontent.com/opencv/opencv/3.4/samples/dnn/face_detector/deploy_lowres.prototxt'; var weights = 'https://raw.githubusercontent.com/opencv/opencv_3rdparty/dnn_samples_face_detector_20180205_fp16/res10_300x300_ssd_iter_140000_fp16.caffemodel'; var recognModel = 'https://raw.githubusercontent.com/pyannote/pyannote-data/master/openface.nn4.small2.v1.t7'; utils.createFileFromUrl('face_detector.prototxt', proto, () => { From 0db4fb18356d380ee9064c006c4b61b2236e0ddd Mon Sep 17 00:00:00 2001 From: Chip Kerchner <49959681+ChipKerchner@users.noreply.github.com> Date: Thu, 25 Jul 2019 14:21:32 -0400 Subject: [PATCH 7/8] Merge pull request #15136 from ChipKerchner:dotProd_unroll * Unroll multiply and add instructions in dotProd_32f - 35% faster. * Eliminate unnecessary v_reduce_sum instructions. --- modules/core/src/matmul.simd.hpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/modules/core/src/matmul.simd.hpp b/modules/core/src/matmul.simd.hpp index ef54bb037c..bb6b6c55d5 100644 --- a/modules/core/src/matmul.simd.hpp +++ b/modules/core/src/matmul.simd.hpp @@ -2511,6 +2511,27 @@ double dotProd_32f(const float* src1, const float* src2, int len) int j = 0; int cWidth = v_float32::nlanes; + +#if CV_ENABLE_UNROLLED + v_float32 v_sum1 = vx_setzero_f32(); + v_float32 v_sum2 = vx_setzero_f32(); + v_float32 v_sum3 = vx_setzero_f32(); + + for (; j <= blockSize - (cWidth * 4); j += (cWidth * 4)) + { + v_sum = v_muladd(vx_load(src1 + j), + vx_load(src2 + j), v_sum); + v_sum1 = v_muladd(vx_load(src1 + j + cWidth), + vx_load(src2 + j + cWidth), v_sum1); + v_sum2 = v_muladd(vx_load(src1 + j + (cWidth * 2)), + vx_load(src2 + j + (cWidth * 2)), v_sum2); + v_sum3 = v_muladd(vx_load(src1 + j + (cWidth * 3)), + vx_load(src2 + j + (cWidth * 3)), v_sum3); + } + + v_sum += v_sum1 + v_sum2 + v_sum3; +#endif + for (; j <= blockSize - cWidth; j += cWidth) v_sum = v_muladd(vx_load(src1 + j), vx_load(src2 + j), v_sum); @@ -2532,4 +2553,4 @@ double dotProd_64f(const double* src1, const double* src2, int len) #endif CV_CPU_OPTIMIZATION_NAMESPACE_END -} // namespace \ No newline at end of file +} // namespace From 4a7ca5a291038a773ea0b67eaf6fbed9ad72170b Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 25 Jul 2019 19:01:19 +0000 Subject: [PATCH 8/8] OpenCV version++ (3.4.7) OpenCV 3.4.7 --- 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 89d1d170e9..6d95c160ef 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 7 -#define CV_VERSION_STATUS "-pre" +#define CV_VERSION_STATUS "" #define CVAUX_STR_EXP(__A) #__A #define CVAUX_STR(__A) CVAUX_STR_EXP(__A)