mirror of
https://github.com/opencv/opencv.git
synced 2026-07-25 21:33:04 +04:00
Compare commits
153 Commits
4.1.0-openvino
...
4.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 371bba8f54 | |||
| 2eaf35eb63 | |||
| 0b9d53829f | |||
| dad2247b56 | |||
| 33b765d797 | |||
| 4368f04afa | |||
| b5961cc5d1 | |||
| c9fc27b337 | |||
| aa1359dc19 | |||
| 28925572f6 | |||
| 0c490accae | |||
| 4c2100e02c | |||
| 1b5a9c9718 | |||
| bd43e4f28b | |||
| ec41a4897a | |||
| 473941c341 | |||
| 1fb93b62c0 | |||
| d38869eb76 | |||
| ab21dc6d47 | |||
| aa167434e6 | |||
| ba5ddd6499 | |||
| 4001346a30 | |||
| d8b8c3b145 | |||
| ba6c2df15d | |||
| c300070b8a | |||
| 4bb6edf176 | |||
| cafa010389 | |||
| ee7255aac4 | |||
| 8bc8a94645 | |||
| 8483801eab | |||
| 5dc606097c | |||
| d4a96b699e | |||
| 14843679af | |||
| 4fa4bef41d | |||
| 785a540ebd | |||
| c4ec46c195 | |||
| d2854448c2 | |||
| 69ff7a76d6 | |||
| 3ca6a72457 | |||
| 7d2118e324 | |||
| 97548b01c7 | |||
| e3286c9055 | |||
| cd6d8048bb | |||
| 3d7a3a51a7 | |||
| df1f62b34c | |||
| 2f288f94e5 | |||
| 2a2d195240 | |||
| 07655c2b4d | |||
| a34c02a001 | |||
| b4e2c99346 | |||
| 33dde339fe | |||
| 341e2fa72d | |||
| 21f0146402 | |||
| 45169577ca | |||
| 2ece029fe0 | |||
| 06193f28ef | |||
| 144b1f4d9d | |||
| bda90dae77 | |||
| 1e583942b9 | |||
| 066c074b66 | |||
| 142a524d2f | |||
| 7142f46d1c | |||
| 6894651027 | |||
| 6dfb6a3016 | |||
| f2803aba07 | |||
| 45428b897f | |||
| 4b91dfd215 | |||
| ccb89a889a | |||
| 50a6f9d251 | |||
| 06a4c20f60 | |||
| fcb07c64f3 | |||
| 6316b3ed91 | |||
| de22442046 | |||
| 10ce935823 | |||
| 360758e8ae | |||
| 8afb2f0cb7 | |||
| 7442100caa | |||
| 52cd1dacbf | |||
| 7d3d6bc4e2 | |||
| 62775660d1 | |||
| 982e6fc721 | |||
| f75152a597 | |||
| b761ec0132 | |||
| 3cd6e3b304 | |||
| 1fb8dcb0de | |||
| 428ff431df | |||
| c7c987843c | |||
| 73191ad3ec | |||
| 769d2f4c44 | |||
| 8ce7d9a4d1 | |||
| e8c20bfae6 | |||
| d6b82dcd65 | |||
| 5368a4ac41 | |||
| 9cfd219d70 | |||
| 90df5e00b4 | |||
| 9340fc0c50 | |||
| f738e490a3 | |||
| 55366caecd | |||
| 212420516f | |||
| 3bcff7f941 | |||
| 6686559c70 | |||
| cedd78d526 | |||
| c443a3d657 | |||
| 5f88bbe3d5 | |||
| 41da3ef1d2 | |||
| 714b38360f | |||
| 097fc1a271 | |||
| 2bd0844be3 | |||
| 0fe17eeb68 | |||
| 8c25a8eb7b | |||
| f147ba16e2 | |||
| b82ecaf48c | |||
| c43371f190 | |||
| 65fc863d86 | |||
| 9cef78b685 | |||
| fbed33cc1f | |||
| 865bd7abff | |||
| a509ec0d91 | |||
| 49f43b03b1 | |||
| 58835eeb78 | |||
| 0df607e5dd | |||
| ea68f7ea1e | |||
| 40da61a314 | |||
| f473b61585 | |||
| e09a464242 | |||
| 4e60db9030 | |||
| 74e3403620 | |||
| a8e635f177 | |||
| 6501cb93a4 | |||
| 04fad57fc1 | |||
| f41359688b | |||
| 0d1a0b126b | |||
| 9a202c1522 | |||
| 6c862fae13 | |||
| ce1432e42d | |||
| e8a0bc5794 | |||
| 93a402d0f2 | |||
| e783e6677e | |||
| f4c2c4412b | |||
| 4fe2d9bdbc | |||
| 8518d078d7 | |||
| 3a1ccd5f43 | |||
| d43597c199 | |||
| 6e90b85cae | |||
| 5451b89aed | |||
| fdf6323942 | |||
| dd2823aaec | |||
| 032e458085 | |||
| a7c4ee9ae1 | |||
| ec25689b42 | |||
| 4fac12c8d3 | |||
| cae1859324 | |||
| 352f4fead6 |
+16
@@ -12,6 +12,22 @@ Write-Output ("=" * 120)
|
||||
Write-Output ""
|
||||
|
||||
if(![System.IO.File]::Exists($output)) {
|
||||
try {
|
||||
[io.file]::OpenWrite($output).close()
|
||||
} catch {
|
||||
Write-Warning "Unable to write: $output"
|
||||
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
|
||||
Write-Warning "Launching with 'Administrator' elevated privileges..."
|
||||
Pause
|
||||
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
|
||||
exit
|
||||
} else {
|
||||
Write-Output "FATAL: Unable to write with elevated privileges: $output"
|
||||
Pause
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Output ("Downloading: " + $output)
|
||||
Import-Module BitsTransfer
|
||||
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/**********************************************************************************
|
||||
* Copyright (c) 2008-2009 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.
|
||||
*
|
||||
* 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.
|
||||
**********************************************************************************/
|
||||
|
||||
#ifndef __OPENCL_CL_D3D11_EXT_H
|
||||
#define __OPENCL_CL_D3D11_EXT_H
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <CL/cl.h>
|
||||
#include <CL/cl_platform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* cl_nv_d3d11_sharing */
|
||||
|
||||
typedef cl_uint cl_d3d11_device_source_nv;
|
||||
typedef cl_uint cl_d3d11_device_set_nv;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// Error Codes
|
||||
#define CL_INVALID_D3D11_DEVICE_NV -1006
|
||||
#define CL_INVALID_D3D11_RESOURCE_NV -1007
|
||||
#define CL_D3D11_RESOURCE_ALREADY_ACQUIRED_NV -1008
|
||||
#define CL_D3D11_RESOURCE_NOT_ACQUIRED_NV -1009
|
||||
|
||||
// cl_d3d11_device_source_nv
|
||||
#define CL_D3D11_DEVICE_NV 0x4019
|
||||
#define CL_D3D11_DXGI_ADAPTER_NV 0x401A
|
||||
|
||||
// cl_d3d11_device_set_nv
|
||||
#define CL_PREFERRED_DEVICES_FOR_D3D11_NV 0x401B
|
||||
#define CL_ALL_DEVICES_FOR_D3D11_NV 0x401C
|
||||
|
||||
// cl_context_info
|
||||
#define CL_CONTEXT_D3D11_DEVICE_NV 0x401D
|
||||
|
||||
// cl_mem_info
|
||||
#define CL_MEM_D3D11_RESOURCE_NV 0x401E
|
||||
|
||||
// cl_image_info
|
||||
#define CL_IMAGE_D3D11_SUBRESOURCE_NV 0x401F
|
||||
|
||||
// cl_command_type
|
||||
#define CL_COMMAND_ACQUIRE_D3D11_OBJECTS_NV 0x4020
|
||||
#define CL_COMMAND_RELEASE_D3D11_OBJECTS_NV 0x4021
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromD3D11NV_fn)(
|
||||
cl_platform_id platform,
|
||||
cl_d3d11_device_source_nv d3d_device_source,
|
||||
void * d3d_object,
|
||||
cl_d3d11_device_set_nv d3d_device_set,
|
||||
cl_uint num_entries,
|
||||
cl_device_id * devices,
|
||||
cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_0;
|
||||
|
||||
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11BufferNV_fn)(
|
||||
cl_context context,
|
||||
cl_mem_flags flags,
|
||||
ID3D11Buffer * resource,
|
||||
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
|
||||
|
||||
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture2DNV_fn)(
|
||||
cl_context context,
|
||||
cl_mem_flags flags,
|
||||
ID3D11Texture2D * resource,
|
||||
UINT subresource,
|
||||
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
|
||||
|
||||
typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture3DNV_fn)(
|
||||
cl_context context,
|
||||
cl_mem_flags flags,
|
||||
ID3D11Texture3D * resource,
|
||||
UINT subresource,
|
||||
cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireD3D11ObjectsNV_fn)(
|
||||
cl_command_queue command_queue,
|
||||
cl_uint num_objects,
|
||||
const cl_mem * mem_objects,
|
||||
cl_uint num_events_in_wait_list,
|
||||
const cl_event * event_wait_list,
|
||||
cl_event * event) CL_API_SUFFIX__VERSION_1_0;
|
||||
|
||||
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseD3D11ObjectsNV_fn)(
|
||||
cl_command_queue command_queue,
|
||||
cl_uint num_objects,
|
||||
cl_mem * mem_objects,
|
||||
cl_uint num_events_in_wait_list,
|
||||
const cl_event * event_wait_list,
|
||||
cl_event * event) CL_API_SUFFIX__VERSION_1_0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __OPENCL_CL_D3D11_H
|
||||
|
||||
Vendored
+1
-1
@@ -84,4 +84,4 @@ 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)
|
||||
ocv_install_3rdparty_licenses(libpng LICENSE README)
|
||||
|
||||
Vendored
+2
-1
@@ -4588,7 +4588,8 @@ png_image_free(png_imagep image)
|
||||
if (image != NULL && image->opaque != NULL &&
|
||||
image->opaque->error_buf == NULL)
|
||||
{
|
||||
png_image_free_function(image);
|
||||
/* Ignore errors here: */
|
||||
(void)png_safe_execute(image, png_image_free_function, image);
|
||||
image->opaque = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -228,6 +228,7 @@ int stream_size;
|
||||
state->strm = strm;
|
||||
state->window = Z_NULL;
|
||||
state->mode = HEAD; /* to pass state test in inflateReset2() */
|
||||
state->check = 1L; /* 1L is the result of adler32() zero length data */
|
||||
ret = inflateReset2(strm, windowBits);
|
||||
if (ret != Z_OK) {
|
||||
ZFREE(strm, state);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
diff --git a/3rdparty/zlib/inflate.c b/3rdparty/zlib/inflate.c
|
||||
index ac333e8c2e..19a2cf2ed8 100644
|
||||
--- a/3rdparty/zlib/inflate.c
|
||||
+++ b/3rdparty/zlib/inflate.c
|
||||
@@ -228,6 +228,7 @@ int stream_size;
|
||||
state->strm = strm;
|
||||
state->window = Z_NULL;
|
||||
state->mode = HEAD; /* to pass state test in inflateReset2() */
|
||||
+ state->check = 1L; /* 1L is the result of adler32() zero length data */
|
||||
ret = inflateReset2(strm, windowBits);
|
||||
if (ret != Z_OK) {
|
||||
ZFREE(strm, state);
|
||||
+19
-2
@@ -108,6 +108,10 @@ if(POLICY CMP0067)
|
||||
cmake_policy(SET CMP0067 NEW)
|
||||
endif()
|
||||
|
||||
if(POLICY CMP0068)
|
||||
cmake_policy(SET CMP0068 NEW) # CMake 3.9+: `RPATH` settings on macOS do not affect `install_name`.
|
||||
endif()
|
||||
|
||||
include(cmake/OpenCVUtils.cmake)
|
||||
ocv_cmake_reset_hooks()
|
||||
ocv_check_environment_variables(OPENCV_CMAKE_HOOKS_DIR)
|
||||
@@ -368,6 +372,9 @@ OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON
|
||||
OCV_OPTION(WITH_DIRECTX "Include DirectX support" ON
|
||||
VISIBLE_IF WIN32 AND NOT WINRT
|
||||
VERIFY HAVE_DIRECTX)
|
||||
OCV_OPTION(WITH_OPENCL_D3D11_NV "Include NVIDIA OpenCL D3D11 support" WITH_DIRECTX
|
||||
VISIBLE_IF WIN32 AND NOT WINRT
|
||||
VERIFY HAVE_OPENCL_D3D11_NV)
|
||||
OCV_OPTION(WITH_LIBREALSENSE "Include Intel librealsense support" OFF
|
||||
VISIBLE_IF NOT WITH_INTELPERC
|
||||
VERIFY HAVE_LIBREALSENSE)
|
||||
@@ -410,6 +417,9 @@ OCV_OPTION(WITH_IMGCODEC_PFM "Include PFM formats support" ON
|
||||
OCV_OPTION(WITH_QUIRC "Include library QR-code decoding" ON
|
||||
VISIBLE_IF TRUE
|
||||
VERIFY HAVE_QUIRC)
|
||||
OCV_OPTION(WITH_ANDROID_MEDIANDK "Use Android Media NDK for Video I/O (Android)" (ANDROID_NATIVE_API_LEVEL GREATER 20)
|
||||
VISIBLE_IF ANDROID
|
||||
VERIFY HAVE_ANDROID_MEDIANDK)
|
||||
|
||||
# OpenCV build components
|
||||
# ===================================================
|
||||
@@ -712,7 +722,7 @@ if(UNIX)
|
||||
CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD)
|
||||
if(ANDROID)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} dl m log)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD|NetBSD|DragonFly|OpenBSD|Haiku")
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|NetBSD|DragonFly|OpenBSD|Haiku")
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} m pthread)
|
||||
elseif(EMSCRIPTEN)
|
||||
# no need to link to system libs with emscripten
|
||||
@@ -1175,7 +1185,13 @@ status(" 3rdparty dependencies:" ${deps_3rdparty})
|
||||
# ========================== OpenCV modules ==========================
|
||||
status("")
|
||||
status(" OpenCV modules:")
|
||||
string(REPLACE "opencv_" "" OPENCV_MODULES_BUILD_ST "${OPENCV_MODULES_BUILD}")
|
||||
set(OPENCV_MODULES_BUILD_ST "")
|
||||
foreach(the_module ${OPENCV_MODULES_BUILD})
|
||||
if(NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "INTERNAL" OR the_module STREQUAL "opencv_ts")
|
||||
list(APPEND OPENCV_MODULES_BUILD_ST "${the_module}")
|
||||
endif()
|
||||
endforeach()
|
||||
string(REPLACE "opencv_" "" OPENCV_MODULES_BUILD_ST "${OPENCV_MODULES_BUILD_ST}")
|
||||
string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_USER_ST "${OPENCV_MODULES_DISABLED_USER}")
|
||||
string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_AUTO_ST "${OPENCV_MODULES_DISABLED_AUTO}")
|
||||
string(REPLACE "opencv_" "" OPENCV_MODULES_DISABLED_FORCE_ST "${OPENCV_MODULES_DISABLED_FORCE}")
|
||||
@@ -1567,6 +1583,7 @@ if(WITH_OPENCL OR HAVE_OPENCL)
|
||||
IF HAVE_OPENCL_SVM THEN "SVM"
|
||||
IF HAVE_CLAMDFFT THEN "AMDFFT"
|
||||
IF HAVE_CLAMDBLAS THEN "AMDBLAS"
|
||||
IF HAVE_OPENCL_D3D11_NV THEN "NVD3D11"
|
||||
ELSE "no extra features")
|
||||
status("")
|
||||
status(" OpenCL:" HAVE_OPENCL THEN "YES (${opencl_features})" ELSE "NO")
|
||||
|
||||
@@ -296,11 +296,18 @@ endif()
|
||||
# workaround gcc bug for aligned ld/st
|
||||
# https://github.com/opencv/opencv/issues/13211
|
||||
if((PPC64LE AND NOT CMAKE_CROSSCOMPILING) OR OPENCV_FORCE_COMPILER_CHECK_VSX_ALIGNED)
|
||||
ocv_check_runtime_flag("${CPU_BASELINE_FLAGS}" "OPENCV_CHECK_VSX_ALIGNED" "${OpenCV_SOURCE_DIR}/cmake/checks/runtime/cpu_vsx_aligned.cpp")
|
||||
ocv_check_runtime_flag("${CPU_BASELINE_FLAGS}" OPENCV_CHECK_VSX_ALIGNED "${OpenCV_SOURCE_DIR}/cmake/checks/runtime/cpu_vsx_aligned.cpp")
|
||||
if(NOT OPENCV_CHECK_VSX_ALIGNED)
|
||||
add_extra_compiler_option_force(-DCV_COMPILER_VSX_BROKEN_ALIGNED)
|
||||
endif()
|
||||
endif()
|
||||
# validate inline asm with fixes register number and constraints wa, wd, wf
|
||||
if(PPC64LE)
|
||||
ocv_check_compiler_flag(CXX "${CPU_BASELINE_FLAGS}" OPENCV_CHECK_VSX_ASM "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_vsx_asm.cpp")
|
||||
if(NOT OPENCV_CHECK_VSX_ASM)
|
||||
add_extra_compiler_option_force(-DCV_COMPILER_VSX_BROKEN_ASM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# combine all "extra" options
|
||||
if(NOT OPENCV_SKIP_EXTRA_COMPILER_FLAGS)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# The script detects Intel(R) Inference Engine installation
|
||||
#
|
||||
# Cache variables:
|
||||
# INF_ENGINE_OMP_DIR - directory with OpenMP library to link with (needed by some versions of IE)
|
||||
# INF_ENGINE_RELEASE - a number reflecting IE source interface (linked with OpenVINO release)
|
||||
#
|
||||
# Detect parameters:
|
||||
@@ -11,8 +10,8 @@
|
||||
# - INF_ENGINE_INCLUDE_DIRS - headers search location
|
||||
# - INF_ENGINE_LIB_DIRS - library search location
|
||||
# 3. OpenVINO location:
|
||||
# - environment variable INTEL_CVSDK_DIR is set to location of OpenVINO installation dir
|
||||
# - INF_ENGINE_PLATFORM - part of name of library directory representing its platform (default ubuntu_16.04)
|
||||
# - environment variable INTEL_OPENVINO_DIR is set to location of OpenVINO installation dir
|
||||
# - INF_ENGINE_PLATFORM - part of name of library directory representing its platform
|
||||
#
|
||||
# Result:
|
||||
# INF_ENGINE_TARGET - set to name of imported library target representing InferenceEngine
|
||||
@@ -36,11 +35,13 @@ function(add_custom_ie_build _inc _lib _lib_rel _lib_dbg _msg)
|
||||
IMPORTED_IMPLIB_DEBUG "${_lib_dbg}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_inc}"
|
||||
)
|
||||
find_library(omp_lib iomp5 PATHS "${INF_ENGINE_OMP_DIR}" NO_DEFAULT_PATH)
|
||||
if(NOT omp_lib)
|
||||
message(WARNING "OpenMP for IE have not been found. Set INF_ENGINE_OMP_DIR variable if you experience build errors.")
|
||||
else()
|
||||
set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${omp_lib}")
|
||||
if(NOT INF_ENGINE_RELEASE VERSION_GREATER "2018050000")
|
||||
find_library(INF_ENGINE_OMP_LIBRARY iomp5 PATHS "${INF_ENGINE_OMP_DIR}" NO_DEFAULT_PATH)
|
||||
if(NOT INF_ENGINE_OMP_LIBRARY)
|
||||
message(WARNING "OpenMP for IE have not been found. Set INF_ENGINE_OMP_DIR variable if you experience build errors.")
|
||||
else()
|
||||
set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${INF_ENGINE_OMP_LIBRARY}")
|
||||
endif()
|
||||
endif()
|
||||
set(INF_ENGINE_VERSION "Unknown" CACHE STRING "")
|
||||
set(INF_ENGINE_TARGET inference_engine PARENT_SCOPE)
|
||||
@@ -64,9 +65,17 @@ if(NOT INF_ENGINE_TARGET AND INF_ENGINE_LIB_DIRS AND INF_ENGINE_INCLUDE_DIRS)
|
||||
add_custom_ie_build("${ie_custom_inc}" "${ie_custom_lib}" "${ie_custom_lib_rel}" "${ie_custom_lib_dbg}" "INF_ENGINE_{INCLUDE,LIB}_DIRS")
|
||||
endif()
|
||||
|
||||
set(_loc "$ENV{INTEL_CVSDK_DIR}")
|
||||
set(_loc "$ENV{INTEL_OPENVINO_DIR}")
|
||||
if(NOT _loc AND DEFINED ENV{INTEL_CVSDK_DIR})
|
||||
set(_loc "$ENV{INTEL_CVSDK_DIR}") # OpenVINO 2018.x
|
||||
endif()
|
||||
if(NOT INF_ENGINE_TARGET AND _loc)
|
||||
set(INF_ENGINE_PLATFORM "ubuntu_16.04" CACHE STRING "InferenceEngine platform (library dir)")
|
||||
if(NOT INF_ENGINE_RELEASE VERSION_GREATER "2018050000")
|
||||
set(INF_ENGINE_PLATFORM_DEFAULT "ubuntu_16.04")
|
||||
else()
|
||||
set(INF_ENGINE_PLATFORM_DEFAULT "")
|
||||
endif()
|
||||
set(INF_ENGINE_PLATFORM "${INF_ENGINE_PLATFORM_DEFAULT}" CACHE STRING "InferenceEngine platform (library dir)")
|
||||
find_path(ie_custom_env_inc "inference_engine.hpp" PATHS "${_loc}/deployment_tools/inference_engine/include" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/${INF_ENGINE_PLATFORM}/intel64" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib_rel "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Release" NO_DEFAULT_PATH)
|
||||
@@ -78,9 +87,9 @@ endif()
|
||||
|
||||
if(INF_ENGINE_TARGET)
|
||||
if(NOT INF_ENGINE_RELEASE)
|
||||
message(WARNING "InferenceEngine version have not been set, 2018R5 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
message(WARNING "InferenceEngine version have not been set, 2019R1 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
endif()
|
||||
set(INF_ENGINE_RELEASE "2018050000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
|
||||
set(INF_ENGINE_RELEASE "2019010000" 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}"
|
||||
)
|
||||
|
||||
@@ -2,14 +2,19 @@ set(OPENCL_FOUND ON CACHE BOOL "OpenCL library is found")
|
||||
if(APPLE)
|
||||
set(OPENCL_LIBRARY "-framework OpenCL" CACHE STRING "OpenCL library")
|
||||
set(OPENCL_INCLUDE_DIR "" CACHE PATH "OpenCL include directory")
|
||||
else(APPLE)
|
||||
else()
|
||||
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)
|
||||
endif()
|
||||
mark_as_advanced(OPENCL_INCLUDE_DIR OPENCL_LIBRARY)
|
||||
|
||||
if(OPENCL_FOUND)
|
||||
|
||||
if(WITH_OPENCL_D3D11_NV AND EXISTS "${OPENCL_INCLUDE_DIR}/CL/cl_d3d11_ext.h")
|
||||
set(HAVE_OPENCL_D3D11_NV ON)
|
||||
endif()
|
||||
|
||||
if(OPENCL_LIBRARY)
|
||||
set(HAVE_OPENCL_STATIC ON)
|
||||
set(OPENCL_LIBRARIES "${OPENCL_LIBRARY}")
|
||||
|
||||
@@ -245,7 +245,12 @@ if(NOT DEFINED IPPROOT)
|
||||
return()
|
||||
endif()
|
||||
set(IPPROOT "${ICV_PACKAGE_ROOT}/icv")
|
||||
ocv_install_3rdparty_licenses(ippicv "${IPPROOT}/readme.htm" "${ICV_PACKAGE_ROOT}/EULA.txt")
|
||||
ocv_install_3rdparty_licenses(ippicv "${IPPROOT}/readme.htm")
|
||||
if(WIN32)
|
||||
ocv_install_3rdparty_licenses(ippicv "${ICV_PACKAGE_ROOT}/EULA.rtf")
|
||||
else()
|
||||
ocv_install_3rdparty_licenses(ippicv "${ICV_PACKAGE_ROOT}/EULA.txt")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
file(TO_CMAKE_PATH "${IPPROOT}" __IPPROOT)
|
||||
|
||||
@@ -148,9 +148,13 @@ if(BUILD_IPP_IW)
|
||||
|
||||
set(IPPIW_ROOT "${IPPROOT}/../iw")
|
||||
ocv_install_3rdparty_licenses(ippiw
|
||||
"${IPPIW_ROOT}/../EULA.txt"
|
||||
"${IPPIW_ROOT}/../support.txt"
|
||||
"${IPPIW_ROOT}/../third-party-programs.txt")
|
||||
if(WIN32)
|
||||
ocv_install_3rdparty_licenses(ippiw "${IPPIW_ROOT}/../EULA.rtf")
|
||||
else()
|
||||
ocv_install_3rdparty_licenses(ippiw "${IPPIW_ROOT}/../EULA.txt")
|
||||
endif()
|
||||
|
||||
# Package sources
|
||||
get_filename_component(__PATH "${IPPROOT}/../iw/" ABSOLUTE)
|
||||
|
||||
@@ -1148,7 +1148,7 @@ function(ocv_add_perf_tests)
|
||||
|
||||
source_group("Src" FILES "${${the_target}_pch}")
|
||||
ocv_add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch})
|
||||
ocv_target_include_modules(${the_target} ${perf_deps} "${perf_path}")
|
||||
ocv_target_include_modules(${the_target} ${perf_deps})
|
||||
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${perf_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_PERF_${the_module}_DEPS})
|
||||
add_dependencies(opencv_perf_tests ${the_target})
|
||||
|
||||
@@ -1239,7 +1239,7 @@ function(ocv_add_accuracy_tests)
|
||||
|
||||
source_group("Src" FILES "${${the_target}_pch}")
|
||||
ocv_add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
|
||||
ocv_target_include_modules(${the_target} ${test_deps} "${test_path}")
|
||||
ocv_target_include_modules(${the_target} ${test_deps})
|
||||
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/test")
|
||||
ocv_target_include_directories(${the_target} "${CMAKE_CURRENT_BINARY_DIR}/test")
|
||||
endif()
|
||||
|
||||
@@ -261,6 +261,7 @@ MACRO(ADD_PRECOMPILED_HEADER _targetName _input)
|
||||
)
|
||||
|
||||
_PCH_GET_COMPILE_FLAGS(_compile_FLAGS)
|
||||
list(APPEND _compile_FLAGS "${_PCH_include_prefix}\"${_path}\"")
|
||||
|
||||
get_target_property(type ${_targetName} TYPE)
|
||||
if(type STREQUAL "SHARED_LIBRARY")
|
||||
|
||||
+11
-2
@@ -822,6 +822,11 @@ function(ocv_output_status msg)
|
||||
message(STATUS "${msg}")
|
||||
string(REPLACE "\\" "\\\\" msg "${msg}")
|
||||
string(REPLACE "\"" "\\\"" msg "${msg}")
|
||||
string(REGEX REPLACE "^\n+|\n+$" "" msg "${msg}")
|
||||
if(msg MATCHES "\n")
|
||||
message(WARNING "String to be inserted to version_string.inc has an unexpected line break: '${msg}'")
|
||||
string(REPLACE "\n" "\\n" msg "${msg}")
|
||||
endif()
|
||||
set(OPENCV_BUILD_INFO_STR "${OPENCV_BUILD_INFO_STR}\"${msg}\\n\"\n" CACHE INTERNAL "")
|
||||
endfunction()
|
||||
|
||||
@@ -1195,13 +1200,17 @@ endfunction()
|
||||
# ocv_install_3rdparty_licenses(<library-name> <filename1> [<filename2> ..])
|
||||
function(ocv_install_3rdparty_licenses library)
|
||||
foreach(filename ${ARGN})
|
||||
set(filepath "${filename}")
|
||||
if(NOT IS_ABSOLUTE "${filepath}")
|
||||
set(filepath "${CMAKE_CURRENT_LIST_DIR}/${filepath}")
|
||||
endif()
|
||||
get_filename_component(name "${filename}" NAME)
|
||||
install(
|
||||
FILES "${filename}"
|
||||
FILES "${filepath}"
|
||||
DESTINATION "${OPENCV_LICENSES_INSTALL_PATH}"
|
||||
COMPONENT licenses
|
||||
RENAME "${library}-${name}"
|
||||
OPTIONAL)
|
||||
)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#if defined(__VSX__)
|
||||
#if defined(__PPC64__) && defined(__LITTLE_ENDIAN__)
|
||||
#include <altivec.h>
|
||||
#else
|
||||
#error "OpenCV only supports little-endian mode"
|
||||
#endif
|
||||
#else
|
||||
#error "VSX is not supported"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xlc and wide versions of clang don't support %x<n> in the inline asm template which fixes register number
|
||||
* when using any of the register constraints wa, wd, wf
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
__vector float vf;
|
||||
__vector signed int vi;
|
||||
__asm__ __volatile__ ("xvcvsxwsp %x0,%x1" : "=wf" (vf) : "wa" (vi));
|
||||
return 0;
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// https://github.com/opencv/opencv/issues/13211
|
||||
|
||||
#include <altivec.h>
|
||||
#undef bool
|
||||
|
||||
#define vsx_ld vec_vsx_ld
|
||||
#define vsx_st vec_vsx_st
|
||||
|
||||
@@ -100,6 +100,9 @@
|
||||
#cmakedefine HAVE_OPENCL_STATIC
|
||||
#cmakedefine HAVE_OPENCL_SVM
|
||||
|
||||
/* NVIDIA OpenCL D3D Extensions support */
|
||||
#cmakedefine HAVE_OPENCL_D3D11_NV
|
||||
|
||||
/* OpenEXR codec */
|
||||
#cmakedefine HAVE_OPENEXR
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ if(DOXYGEN_FOUND)
|
||||
foreach(m ${OPENCV_MODULES_MAIN} ${OPENCV_MODULES_EXTRA})
|
||||
list(FIND blacklist ${m} _pos)
|
||||
if(${_pos} EQUAL -1)
|
||||
list(APPEND CMAKE_DOXYGEN_ENABLED_SECTIONS "HAVE_opencv_${m}")
|
||||
# include folder
|
||||
set(header_dir "${OPENCV_MODULE_opencv_${m}_LOCATION}/include")
|
||||
if(EXISTS "${header_dir}")
|
||||
|
||||
+1
-2
@@ -41,8 +41,7 @@ you need 256 values to show the above histogram. But consider, what if you need
|
||||
of pixels for all pixel values separately, but number of pixels in a interval of pixel values? say
|
||||
for example, you need to find the number of pixels lying between 0 to 15, then 16 to 31, ..., 240 to 255.
|
||||
You will need only 16 values to represent the histogram. And that is what is shown in example
|
||||
given in [OpenCV Tutorials on
|
||||
histograms](http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html#histogram-calculation).
|
||||
given in @ref tutorial_histogram_calculation "OpenCV Tutorials on histograms".
|
||||
|
||||
So what you do is simply split the whole histogram to 16 sub-parts and value of each sub-part is the
|
||||
sum of all pixel count in it. This each sub-part is called "BIN". In first case, number of bins
|
||||
|
||||
@@ -4,20 +4,21 @@ Image Thresholding {#tutorial_py_thresholding}
|
||||
Goal
|
||||
----
|
||||
|
||||
- In this tutorial, you will learn Simple thresholding, Adaptive thresholding, Otsu's thresholding
|
||||
etc.
|
||||
- You will learn these functions : **cv.threshold**, **cv.adaptiveThreshold** etc.
|
||||
- In this tutorial, you will learn Simple thresholding, Adaptive thresholding and Otsu's thresholding.
|
||||
- You will learn the functions **cv.threshold** and **cv.adaptiveThreshold**.
|
||||
|
||||
Simple Thresholding
|
||||
-------------------
|
||||
|
||||
Here, the matter is straight forward. If pixel value is greater than a threshold value, it is
|
||||
assigned one value (may be white), else it is assigned another value (may be black). The function
|
||||
used is **cv.threshold**. First argument is the source image, which **should be a grayscale
|
||||
image**. Second argument is the threshold value which is used to classify the pixel values. Third
|
||||
argument is the maxVal which represents the value to be given if pixel value is more than (sometimes
|
||||
less than) the threshold value. OpenCV provides different styles of thresholding and it is decided
|
||||
by the fourth parameter of the function. Different types are:
|
||||
Here, the matter is straight forward. For every pixel, the same threshold value is applied.
|
||||
If the pixel value is smaller than the threshold, it is set to 0, otherwise it is set to a maximum value.
|
||||
The function **cv.threshold** is used to apply the thresholding.
|
||||
The first argument is the source image, which **should be a grayscale image**.
|
||||
The second argument is the threshold value which is used to classify the pixel values.
|
||||
The third argument is the maximum value which is assigned to pixel values exceeding the threshold.
|
||||
OpenCV provides different types of thresholding which is given by the fourth parameter of the function.
|
||||
Basic thresholding as described above is done by using the type cv.THRESH_BINARY.
|
||||
All simple thresholding types are:
|
||||
|
||||
- cv.THRESH_BINARY
|
||||
- cv.THRESH_BINARY_INV
|
||||
@@ -25,12 +26,12 @@ by the fourth parameter of the function. Different types are:
|
||||
- cv.THRESH_TOZERO
|
||||
- cv.THRESH_TOZERO_INV
|
||||
|
||||
Documentation clearly explain what each type is meant for. Please check out the documentation.
|
||||
See the documentation of the types for the differences.
|
||||
|
||||
Two outputs are obtained. First one is a **retval** which will be explained later. Second output is
|
||||
our **thresholded image**.
|
||||
The method returns two outputs.
|
||||
The first is the threshold that was used and the second output is the **thresholded image**.
|
||||
|
||||
Code :
|
||||
This code compares the different simple thresholding types:
|
||||
@code{.py}
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
@@ -53,34 +54,31 @@ for i in xrange(6):
|
||||
|
||||
plt.show()
|
||||
@endcode
|
||||
@note To plot multiple images, we have used plt.subplot() function. Please checkout Matplotlib docs
|
||||
for more details.
|
||||
@note To plot multiple images, we have used the plt.subplot() function. Please checkout the matplotlib docs for more details.
|
||||
|
||||
Result is given below :
|
||||
The code yields this result:
|
||||
|
||||

|
||||
|
||||
Adaptive Thresholding
|
||||
---------------------
|
||||
|
||||
In the previous section, we used a global value as threshold value. But it may not be good in all
|
||||
the conditions where image has different lighting conditions in different areas. In that case, we go
|
||||
for adaptive thresholding. In this, the algorithm calculate the threshold for a small regions of the
|
||||
image. So we get different thresholds for different regions of the same image and it gives us better
|
||||
results for images with varying illumination.
|
||||
In the previous section, we used one global value as a threshold.
|
||||
But this might not be good in all cases, e.g. if an image has different lighting conditions in different areas.
|
||||
In that case, adaptive thresholding thresholding can help.
|
||||
Here, the algorithm determines the threshold for a pixel based on a small region around it.
|
||||
So we get different thresholds for different regions of the same image which gives better results for images with varying illumination.
|
||||
|
||||
It has three ‘special’ input params and only one output argument.
|
||||
Additionally to the parameters described above, the method cv.adaptiveThreshold three input parameters:
|
||||
|
||||
**Adaptive Method** - It decides how thresholding value is calculated.
|
||||
- cv.ADAPTIVE_THRESH_MEAN_C : threshold value is the mean of neighbourhood area.
|
||||
- cv.ADAPTIVE_THRESH_GAUSSIAN_C : threshold value is the weighted sum of neighbourhood
|
||||
values where weights are a gaussian window.
|
||||
The **adaptiveMethod** decides how the threshold value is calculated:
|
||||
- cv.ADAPTIVE_THRESH_MEAN_C: The threshold value is the mean of the neighbourhood area minus the constant **C**.
|
||||
- cv.ADAPTIVE_THRESH_GAUSSIAN_C: The threshold value is a gaussian-weighted sum of the neighbourhood
|
||||
values minus the constant **C**.
|
||||
|
||||
**Block Size** - It decides the size of neighbourhood area.
|
||||
The **blockSize** determines the size of the neighbourhood area and **C** is a constant that is subtracted from the mean or weighted sum of the neighbourhood pixels.
|
||||
|
||||
**C** - It is just a constant which is subtracted from the mean or weighted mean calculated.
|
||||
|
||||
Below piece of code compares global thresholding and adaptive thresholding for an image with varying
|
||||
The code below compares global thresholding and adaptive thresholding for an image with varying
|
||||
illumination:
|
||||
@code{.py}
|
||||
import cv2 as cv
|
||||
@@ -106,33 +104,30 @@ for i in xrange(4):
|
||||
plt.xticks([]),plt.yticks([])
|
||||
plt.show()
|
||||
@endcode
|
||||
Result :
|
||||
Result:
|
||||
|
||||

|
||||
|
||||
Otsu’s Binarization
|
||||
Otsu's Binarization
|
||||
-------------------
|
||||
|
||||
In the first section, I told you there is a second parameter **retVal**. Its use comes when we go
|
||||
for Otsu’s Binarization. So what is it?
|
||||
In global thresholding, we used an arbitrary chosen value as a threshold.
|
||||
In contrast, Otsu's method avoids having to choose a value and determines it automatically.
|
||||
|
||||
In global thresholding, we used an arbitrary value for threshold value, right? So, how can we know a
|
||||
value we selected is good or not? Answer is, trial and error method. But consider a **bimodal
|
||||
image** (*In simple words, bimodal image is an image whose histogram has two peaks*). For that
|
||||
image, we can approximately take a value in the middle of those peaks as threshold value, right ?
|
||||
That is what Otsu binarization does. So in simple words, it automatically calculates a threshold
|
||||
value from image histogram for a bimodal image. (For images which are not bimodal, binarization
|
||||
won’t be accurate.)
|
||||
Consider an image with only two distinct image values (*bimodal image*), where the histogram would only consist of two peaks.
|
||||
A good threshold would be in the middle of those two values.
|
||||
Similarly, Otsu's method determines an optimal global threshold value from the image histogram.
|
||||
|
||||
For this, our cv.threshold() function is used, but pass an extra flag, cv.THRESH_OTSU. **For
|
||||
threshold value, simply pass zero**. Then the algorithm finds the optimal threshold value and
|
||||
returns you as the second output, retVal. If Otsu thresholding is not used, retVal is same as the
|
||||
threshold value you used.
|
||||
In order to do so, the cv.threshold() function is used, where cv.THRESH_OTSU is passed as an extra flag.
|
||||
The threshold value can be chosen arbitrary.
|
||||
The algorithm then finds the optimal threshold value which is returned as the first output.
|
||||
|
||||
Check out below example. Input image is a noisy image. In first case, I applied global thresholding
|
||||
for a value of 127. In second case, I applied Otsu’s thresholding directly. In third case, I
|
||||
filtered image with a 5x5 gaussian kernel to remove the noise, then applied Otsu thresholding. See
|
||||
how noise filtering improves the result.
|
||||
Check out the example below.
|
||||
The input image is a noisy image.
|
||||
In the first case, global thresholding with a value of 127 is applied.
|
||||
In the second case, Otsu's thresholding is applied directly.
|
||||
In the third case, the image is first filtered with a 5x5 gaussian kernel to remove the noise, then Otsu thresholding is applied.
|
||||
See how noise filtering improves the result.
|
||||
@code{.py}
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
@@ -167,17 +162,17 @@ for i in xrange(3):
|
||||
plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
|
||||
plt.show()
|
||||
@endcode
|
||||
Result :
|
||||
Result:
|
||||
|
||||

|
||||
|
||||
### How Otsu's Binarization Works?
|
||||
### How does Otsu's Binarization work?
|
||||
|
||||
This section demonstrates a Python implementation of Otsu's binarization to show how it works
|
||||
actually. If you are not interested, you can skip this.
|
||||
|
||||
Since we are working with bimodal images, Otsu's algorithm tries to find a threshold value (t) which
|
||||
minimizes the **weighted within-class variance** given by the relation :
|
||||
minimizes the **weighted within-class variance** given by the relation:
|
||||
|
||||
\f[\sigma_w^2(t) = q_1(t)\sigma_1^2(t)+q_2(t)\sigma_2^2(t)\f]
|
||||
|
||||
@@ -186,7 +181,7 @@ where
|
||||
\f[q_1(t) = \sum_{i=1}^{t} P(i) \quad \& \quad q_2(t) = \sum_{i=t+1}^{I} P(i)\f]\f[\mu_1(t) = \sum_{i=1}^{t} \frac{iP(i)}{q_1(t)} \quad \& \quad \mu_2(t) = \sum_{i=t+1}^{I} \frac{iP(i)}{q_2(t)}\f]\f[\sigma_1^2(t) = \sum_{i=1}^{t} [i-\mu_1(t)]^2 \frac{P(i)}{q_1(t)} \quad \& \quad \sigma_2^2(t) = \sum_{i=t+1}^{I} [i-\mu_2(t)]^2 \frac{P(i)}{q_2(t)}\f]
|
||||
|
||||
It actually finds a value of t which lies in between two peaks such that variances to both classes
|
||||
are minimum. It can be simply implemented in Python as follows:
|
||||
are minimal. It can be simply implemented in Python as follows:
|
||||
@code{.py}
|
||||
img = cv.imread('noisy2.png',0)
|
||||
blur = cv.GaussianBlur(img,(5,5),0)
|
||||
@@ -220,7 +215,6 @@ for i in xrange(1,256):
|
||||
ret, otsu = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
|
||||
print( "{} {}".format(thresh,ret) )
|
||||
@endcode
|
||||
*(Some of the functions may be new here, but we will cover them in coming chapters)*
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
@@ -15,18 +15,18 @@ Installing OpenCV from prebuilt binaries
|
||||
|
||||
-# Below Python packages are to be downloaded and installed to their default locations.
|
||||
|
||||
-# [Python-2.7.x](http://www.python.org/ftp/python/2.7.13/python-2.7.13.msi).
|
||||
-# Python 3.x (3.4+) or Python 2.7.x from [here](https://www.python.org/downloads/).
|
||||
|
||||
-# [Numpy](https://sourceforge.net/projects/numpy/files/NumPy/1.10.2/numpy-1.10.2-win32-superpack-python2.7.exe/download).
|
||||
-# Numpy package (for example, using `pip install numpy` command).
|
||||
|
||||
-# [Matplotlib](https://sourceforge.net/projects/matplotlib/files/matplotlib/matplotlib-1.5.0/windows/matplotlib-1.5.0.win32-py2.7.exe/download) (*Matplotlib is optional, but recommended since we use it a lot in our tutorials*).
|
||||
-# Matplotlib (`pip install matplotlib`) (*Matplotlib is optional, but recommended since we use it a lot in our tutorials*).
|
||||
|
||||
-# Install all packages into their default locations. Python will be installed to `C:/Python27/`.
|
||||
-# Install all packages into their default locations. Python will be installed to `C:/Python27/` in case of Python 2.7.
|
||||
|
||||
-# After installation, open Python IDLE. Enter **import numpy** and make sure Numpy is working fine.
|
||||
|
||||
-# Download latest OpenCV release from [sourceforge
|
||||
site](http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.6/OpenCV-2.4.6.0.exe/download)
|
||||
-# Download latest OpenCV release from [GitHub](https://github.com/opencv/opencv/releases) or
|
||||
[SourceForge site](https://sourceforge.net/projects/opencvlibrary/files/)
|
||||
and double-click to extract it.
|
||||
|
||||
-# Goto **opencv/build/python/2.7** folder.
|
||||
@@ -49,16 +49,13 @@ Building OpenCV from source
|
||||
|
||||
-# [Visual Studio 2012](http://go.microsoft.com/?linkid=9816768)
|
||||
|
||||
-# [CMake](http://www.cmake.org/files/v2.8/cmake-2.8.11.2-win32-x86.exe)
|
||||
-# [CMake](https://cmake.org/download/)
|
||||
|
||||
-# Download and install necessary Python packages to their default locations
|
||||
|
||||
-# [Python 2.7.x](http://python.org/ftp/python/2.7.5/python-2.7.5.msi)
|
||||
-# Python
|
||||
|
||||
-# [Numpy](http://sourceforge.net/projects/numpy/files/NumPy/1.7.1/numpy-1.7.1-win32-superpack-python2.7.exe/download)
|
||||
|
||||
-# [Matplotlib](https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-1.3.0/matplotlib-1.3.0.win32-py2.7.exe)
|
||||
(*Matplotlib is optional, but recommended since we use it a lot in our tutorials.*)
|
||||
-# Numpy
|
||||
|
||||
@note In this case, we are using 32-bit binaries of Python packages. But if you want to use
|
||||
OpenCV for x64, 64-bit binaries of Python packages are to be installed. Problem is that, there
|
||||
|
||||
+6
-1
@@ -30,4 +30,9 @@ If you want to change unit use -u option (mm inches, px, m)
|
||||
|
||||
If you want to change page size use -w and -h options
|
||||
|
||||
If you want to create a ChArUco board read tutorial Detection of ChArUco Corners in opencv_contrib tutorial(https://docs.opencv.org/3.4/df/d4a/tutorial_charuco_detection.html)
|
||||
@cond HAVE_opencv_aruco
|
||||
If you want to create a ChArUco board read @ref tutorial_charuco_detection "tutorial Detection of ChArUco Corners" in opencv_contrib tutorial.
|
||||
@endcond
|
||||
@cond !HAVE_opencv_aruco
|
||||
If you want to create a ChArUco board read tutorial Detection of ChArUco Corners in opencv_contrib tutorial.
|
||||
@endcond
|
||||
|
||||
@@ -25,7 +25,7 @@ Explanation
|
||||
[bvlc_googlenet.caffemodel](http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel)
|
||||
|
||||
Also you need file with names of [ILSVRC2012](http://image-net.org/challenges/LSVRC/2012/browse-synsets) classes:
|
||||
[classification_classes_ILSVRC2012.txt](https://github.com/opencv/opencv/tree/master/samples/dnn/classification_classes_ILSVRC2012.txt).
|
||||
[classification_classes_ILSVRC2012.txt](https://github.com/opencv/opencv/blob/master/samples/data/dnn/classification_classes_ILSVRC2012.txt).
|
||||
|
||||
Put these files into working dir of this program example.
|
||||
|
||||
|
||||
@@ -97,9 +97,7 @@ I1 = gI1; // Download, gI1.download(I1) will work too
|
||||
@endcode
|
||||
Once you have your data up in the GPU memory you may call GPU enabled functions of OpenCV. Most of
|
||||
the functions keep the same name just as on the CPU, with the difference that they only accept
|
||||
*GpuMat* inputs. A full list of these you will find in the documentation: [online
|
||||
here](http://docs.opencv.org/modules/gpu/doc/gpu.html) or the OpenCV reference manual that comes
|
||||
with the source code.
|
||||
*GpuMat* inputs.
|
||||
|
||||
Another thing to keep in mind is that not for all channel numbers you can make efficient algorithms
|
||||
on the GPU. Generally, I found that the input images for the GPU images need to be either one or
|
||||
|
||||
+46
-6
@@ -1,6 +1,9 @@
|
||||
Anisotropic image segmentation by a gradient structure tensor {#tutorial_anisotropic_image_segmentation_by_a_gst}
|
||||
==========================
|
||||
|
||||
@prev_tutorial{tutorial_motion_deblur_filter}
|
||||
@next_tutorial{tutorial_periodic_noise_removing_filter}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -45,28 +48,65 @@ The orientation of an anisotropic image:
|
||||
Coherency:
|
||||
\f[C = \frac{\lambda_1 - \lambda_2}{\lambda_1 + \lambda_2}\f]
|
||||
|
||||
The coherency ranges from 0 to 1. For ideal local orientation (\f$\lambda_2\f$ = 0, \f$\lambda_1\f$ > 0) it is one, for an isotropic gray value structure (\f$\lambda_1\f$ = \f$\lambda_2\f$ > 0) it is zero.
|
||||
The coherency ranges from 0 to 1. For ideal local orientation (\f$\lambda_2\f$ = 0, \f$\lambda_1\f$ > 0) it is one, for an isotropic gray value structure (\f$\lambda_1\f$ = \f$\lambda_2\f$ \> 0) it is zero.
|
||||
|
||||
Source code
|
||||
-----------
|
||||
|
||||
You can find source code in the `samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp` of the OpenCV source code library.
|
||||
|
||||
@include cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp
|
||||
@add_toggle_cpp
|
||||
@include cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@include samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py
|
||||
@end_toggle
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
An anisotropic image segmentation algorithm consists of a gradient structure tensor calculation, an orientation calculation, a coherency calculation and an orientation and coherency thresholding:
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp main
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp main
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py main
|
||||
@end_toggle
|
||||
|
||||
A function calcGST() calculates orientation and coherency by using a gradient structure tensor. An input parameter w defines a window size:
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp calcGST
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp calcGST
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py calcGST
|
||||
@end_toggle
|
||||
|
||||
|
||||
The below code applies a thresholds LowThr and HighThr to image orientation and a threshold C_Thr to image coherency calculated by the previous function. LowThr and HighThr define orientation range:
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp thresholding
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp thresholding
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py thresholding
|
||||
@end_toggle
|
||||
|
||||
|
||||
And finally we combine thresholding results:
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp combining
|
||||
|
||||
@add_toggle_cpp
|
||||
@snippet samples/cpp/tutorial_code/ImgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.cpp combining
|
||||
@end_toggle
|
||||
|
||||
@add_toggle_python
|
||||
@snippet samples/python/tutorial_code/imgProc/anisotropic_image_segmentation/anisotropic_image_segmentation.py combining
|
||||
@end_toggle
|
||||
|
||||
|
||||
Result
|
||||
------
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
Motion Deblur Filter {#tutorial_motion_deblur_filter}
|
||||
==========================
|
||||
|
||||
@prev_tutorial{tutorial_out_of_focus_deblur_filter}
|
||||
@next_tutorial{tutorial_anisotropic_image_segmentation_by_a_gst}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ Out-of-focus Deblur Filter {#tutorial_out_of_focus_deblur_filter}
|
||||
==========================
|
||||
|
||||
@prev_tutorial{tutorial_distance_transform}
|
||||
@next_tutorial{tutorial_motion_deblur_filter}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
+2
@@ -1,6 +1,8 @@
|
||||
Periodic Noise Removing Filter {#tutorial_periodic_noise_removing_filter}
|
||||
==========================
|
||||
|
||||
@prev_tutorial{tutorial_anisotropic_image_segmentation_by_a_gst}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ The structure of package contents looks as follows:
|
||||
|
||||
- `doc` folder contains various OpenCV documentation in PDF format. It's also available online at
|
||||
<http://docs.opencv.org>.
|
||||
@note The most recent docs (nightly build) are at <http://docs.opencv.org/2.4>. Generally, it's more
|
||||
@note The most recent docs (nightly build) are at <http://docs.opencv.org/master>. Generally, it's more
|
||||
up-to-date, but can refer to not-yet-released functionality.
|
||||
@todo I'm not sure that this is the best place to talk about OpenCV Manager
|
||||
|
||||
@@ -85,10 +85,6 @@ applications developers:
|
||||
- Automatic updates and bug fixes;
|
||||
- Trusted OpenCV library source. All packages with OpenCV are published on Google Play;
|
||||
|
||||
For additional information on OpenCV Manager see the:
|
||||
|
||||
- [Slides](https://docs.google.com/a/itseez.com/presentation/d/1EO_1kijgBg_BsjNp2ymk-aarg-0K279_1VZRcPplSuk/present#slide=id.p)
|
||||
- [Reference Manual](http://docs.opencv.org/android/refman.html)
|
||||
|
||||
Manual OpenCV4Android SDK setup
|
||||
-------------------------------
|
||||
@@ -96,8 +92,8 @@ Manual OpenCV4Android SDK setup
|
||||
### Get the OpenCV4Android SDK
|
||||
|
||||
-# Go to the [OpenCV download page on
|
||||
SourceForge](http://sourceforge.net/projects/opencvlibrary/files/opencv-android/) and download
|
||||
the latest available version. Currently it's [OpenCV-2.4.9-android-sdk.zip](http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.9/OpenCV-2.4.9-android-sdk.zip/download).
|
||||
SourceForge](http://sourceforge.net/projects/opencvlibrary/files/) and download
|
||||
the latest available version. This tutorial is based on this package: [OpenCV-2.4.9-android-sdk.zip](http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.9/OpenCV-2.4.9-android-sdk.zip/download).
|
||||
-# Create a new folder for Android with OpenCV development. For this tutorial we have unpacked
|
||||
OpenCV SDK to the `C:\Work\OpenCV4Android\` directory.
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ lein run
|
||||
Preamble
|
||||
--------
|
||||
|
||||
For detailed instruction on installing OpenCV with desktop Java support refer to the [corresponding
|
||||
tutorial](http://docs.opencv.org/2.4.4-beta/doc/tutorials/introduction/desktop_java/java_dev_intro.html).
|
||||
For detailed instruction on installing OpenCV with desktop Java support refer to the @ref tutorial_java_dev_intro "corresponding
|
||||
tutorial".
|
||||
|
||||
If you are in hurry, here is a minimum quick start guide to install OpenCV on Mac OS X:
|
||||
|
||||
@@ -302,7 +302,7 @@ Then you can start interacting with OpenCV by just referencing the fully qualifi
|
||||
classes.
|
||||
|
||||
@note
|
||||
[Here](http://docs.opencv.org/java/) you can find the full OpenCV Java API.
|
||||
[Here](https://docs.opencv.org/master/javadoc/index.html) you can find the full OpenCV Java API.
|
||||
|
||||
@code{.clojure}
|
||||
user=> (org.opencv.core.Point. 0 0)
|
||||
@@ -387,8 +387,7 @@ user=> (javadoc Rect)
|
||||
@endcode
|
||||
### Mimic the OpenCV Java Tutorial Sample in the REPL
|
||||
|
||||
Let's now try to port to Clojure the [opencv java tutorial
|
||||
sample](http://docs.opencv.org/2.4.4-beta/doc/tutorials/introduction/desktop_java/java_dev_intro.html).
|
||||
Let's now try to port to Clojure the @ref tutorial_java_dev_intro "OpenCV Java tutorial sample".
|
||||
Instead of writing it in a source file we're going to evaluate it at the REPL.
|
||||
|
||||
Following is the original Java source code of the cited sample.
|
||||
|
||||
@@ -94,8 +94,6 @@ the weight vector \f$\beta\f$ and the bias \f$\beta_{0}\f$ of the optimal hyperp
|
||||
Source Code
|
||||
-----------
|
||||
|
||||
@note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html#introductiontosvms)
|
||||
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/introduction_to_svm/introduction_to_svm.cpp)
|
||||
|
||||
@@ -89,9 +89,6 @@ Source Code
|
||||
You may also find the source code in `samples/cpp/tutorial_code/ml/non_linear_svms` folder of the OpenCV source library or
|
||||
[download it from here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp).
|
||||
|
||||
@note The following code has been implemented with OpenCV 3.0 classes and functions. An equivalent version of the code
|
||||
using OpenCV 2.4 can be found in [this page.](http://docs.opencv.org/2.4/doc/tutorials/ml/non_linear_svms/non_linear_svms.html#nonlinearsvms)
|
||||
|
||||
@add_toggle_cpp
|
||||
- **Downloadable code**: Click
|
||||
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp)
|
||||
|
||||
@@ -177,8 +177,6 @@ pattern (every view is described by several 3D-2D point correspondences).
|
||||
opencv_source_code/samples/cpp/calibration.cpp
|
||||
- A calibration sample in order to do 3D reconstruction can be found at
|
||||
opencv_source_code/samples/cpp/build3dmodel.cpp
|
||||
- A calibration sample of an artificially generated camera and chessboard patterns can be
|
||||
found at opencv_source_code/samples/cpp/calibration_artificial.cpp
|
||||
- A calibration example on stereo calibration can be found at
|
||||
opencv_source_code/samples/cpp/stereo_calib.cpp
|
||||
- A calibration example on stereo matching can be found at
|
||||
|
||||
@@ -833,6 +833,13 @@ Mat estimateAffine2D(InputArray _from, InputArray _to, OutputArray _inliers,
|
||||
to.convertTo(tmp2, CV_32FC2);
|
||||
to = tmp2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// avoid changing of inputs in compressElems() call
|
||||
from = from.clone();
|
||||
to = to.clone();
|
||||
}
|
||||
|
||||
// convert to N x 1 vectors
|
||||
from = from.reshape(2, count);
|
||||
to = to.reshape(2, count);
|
||||
@@ -900,6 +907,13 @@ Mat estimateAffinePartial2D(InputArray _from, InputArray _to, OutputArray _inlie
|
||||
to.convertTo(tmp2, CV_32FC2);
|
||||
to = tmp2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// avoid changing of inputs in compressElems() call
|
||||
from = from.clone();
|
||||
to = to.clone();
|
||||
}
|
||||
|
||||
// convert to N x 1 vectors
|
||||
from = from.reshape(2, count);
|
||||
to = to.reshape(2, count);
|
||||
|
||||
@@ -152,4 +152,46 @@ TEST_P(EstimateAffine2D, testConversion)
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffine2D, Method::all());
|
||||
|
||||
|
||||
// https://github.com/opencv/opencv/issues/14259
|
||||
TEST(EstimateAffine2D, issue_14259_dont_change_inputs)
|
||||
{
|
||||
/*const static*/ float pts0_[10] = {
|
||||
0.0f, 0.0f,
|
||||
0.0f, 8.0f,
|
||||
4.0f, 0.0f, // outlier
|
||||
8.0f, 8.0f,
|
||||
8.0f, 0.0f
|
||||
};
|
||||
/*const static*/ float pts1_[10] = {
|
||||
0.1f, 0.1f,
|
||||
0.1f, 8.1f,
|
||||
0.0f, 4.0f, // outlier
|
||||
8.1f, 8.1f,
|
||||
8.1f, 0.1f
|
||||
};
|
||||
|
||||
Mat pts0(Size(1, 5), CV_32FC2, (void*)pts0_);
|
||||
Mat pts1(Size(1, 5), CV_32FC2, (void*)pts1_);
|
||||
|
||||
Mat pts0_copy = pts0.clone();
|
||||
Mat pts1_copy = pts1.clone();
|
||||
|
||||
Mat inliers;
|
||||
|
||||
cv::Mat A = cv::estimateAffine2D(pts0, pts1, inliers);
|
||||
|
||||
for(int i = 0; i < pts0.rows; ++i)
|
||||
{
|
||||
EXPECT_EQ(pts0_copy.at<Vec2f>(i), pts0.at<Vec2f>(i)) << "pts0: i=" << i;
|
||||
}
|
||||
|
||||
for(int i = 0; i < pts1.rows; ++i)
|
||||
{
|
||||
EXPECT_EQ(pts1_copy.at<Vec2f>(i), pts1.at<Vec2f>(i)) << "pts1: i=" << i;
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, (int)inliers.at<uchar>(2));
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -161,4 +161,46 @@ TEST_P(EstimateAffinePartial2D, testConversion)
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Calib3d, EstimateAffinePartial2D, Method::all());
|
||||
|
||||
|
||||
// https://github.com/opencv/opencv/issues/14259
|
||||
TEST(EstimateAffinePartial2D, issue_14259_dont_change_inputs)
|
||||
{
|
||||
/*const static*/ float pts0_[10] = {
|
||||
0.0f, 0.0f,
|
||||
0.0f, 8.0f,
|
||||
4.0f, 0.0f, // outlier
|
||||
8.0f, 8.0f,
|
||||
8.0f, 0.0f
|
||||
};
|
||||
/*const static*/ float pts1_[10] = {
|
||||
0.1f, 0.1f,
|
||||
0.1f, 8.1f,
|
||||
0.0f, 4.0f, // outlier
|
||||
8.1f, 8.1f,
|
||||
8.1f, 0.1f
|
||||
};
|
||||
|
||||
Mat pts0(Size(1, 5), CV_32FC2, (void*)pts0_);
|
||||
Mat pts1(Size(1, 5), CV_32FC2, (void*)pts1_);
|
||||
|
||||
Mat pts0_copy = pts0.clone();
|
||||
Mat pts1_copy = pts1.clone();
|
||||
|
||||
Mat inliers;
|
||||
|
||||
cv::Mat A = cv::estimateAffinePartial2D(pts0, pts1, inliers);
|
||||
|
||||
for(int i = 0; i < pts0.rows; ++i)
|
||||
{
|
||||
EXPECT_EQ(pts0_copy.at<Vec2f>(i), pts0.at<Vec2f>(i)) << "pts0: i=" << i;
|
||||
}
|
||||
|
||||
for(int i = 0; i < pts1.rows; ++i)
|
||||
{
|
||||
EXPECT_EQ(pts1_copy.at<Vec2f>(i), pts1.at<Vec2f>(i)) << "pts1: i=" << i;
|
||||
}
|
||||
|
||||
EXPECT_EQ(0, (int)inliers.at<uchar>(2));
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -3,7 +3,7 @@ set(the_description "The Core Functionality")
|
||||
ocv_add_dispatched_file(mathfuncs_core SSE2 AVX AVX2)
|
||||
ocv_add_dispatched_file(stat SSE4_2 AVX2)
|
||||
ocv_add_dispatched_file(arithm SSE2 SSE4_1 AVX2 VSX3)
|
||||
ocv_add_dispatched_file(convert SSE2 AVX2)
|
||||
ocv_add_dispatched_file(convert SSE2 AVX2 VSX3)
|
||||
ocv_add_dispatched_file(convert_scale SSE2 AVX2)
|
||||
ocv_add_dispatched_file(count_non_zero SSE2 AVX2)
|
||||
ocv_add_dispatched_file(matmul SSE2 AVX2)
|
||||
@@ -35,6 +35,9 @@ if(DEFINED WINRT AND NOT DEFINED ENABLE_WINRT_MODE_NATIVE)
|
||||
endif()
|
||||
|
||||
if(HAVE_CUDA)
|
||||
if(NOT HAVE_opencv_cudev)
|
||||
message(FATAL_ERROR "CUDA: OpenCV requires enabled 'cudev' module from 'opencv_contrib' repository: https://github.com/opencv/opencv_contrib")
|
||||
endif()
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wenum-compare -Wunused-function -Wshadow)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -691,7 +691,7 @@ __CV_ENUM_FLAGS_BITWISE_XOR_EQ (EnumType, EnumType)
|
||||
# endif
|
||||
#endif
|
||||
#ifndef CV_CONSTEXPR
|
||||
# define CV_CONSTEXPR const
|
||||
# define CV_CONSTEXPR
|
||||
#endif
|
||||
|
||||
// Integer types portatibility
|
||||
|
||||
@@ -2022,7 +2022,7 @@ inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b
|
||||
b = v_uint64x4(b0);
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& b, v_uint8x32& g, v_uint8x32& r )
|
||||
inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& a, v_uint8x32& b, v_uint8x32& c )
|
||||
{
|
||||
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
|
||||
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 32));
|
||||
@@ -2051,12 +2051,12 @@ inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& b, v_uint8x32& g,
|
||||
g0 = _mm256_shuffle_epi8(g0, sh_g);
|
||||
r0 = _mm256_shuffle_epi8(r0, sh_r);
|
||||
|
||||
b = v_uint8x32(b0);
|
||||
g = v_uint8x32(g0);
|
||||
r = v_uint8x32(r0);
|
||||
a = v_uint8x32(b0);
|
||||
b = v_uint8x32(g0);
|
||||
c = v_uint8x32(r0);
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& b, v_uint16x16& g, v_uint16x16& r )
|
||||
inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& a, v_uint16x16& b, v_uint16x16& c )
|
||||
{
|
||||
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
|
||||
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 16));
|
||||
@@ -2082,12 +2082,12 @@ inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& b, v_uint16x16&
|
||||
g0 = _mm256_shuffle_epi8(g0, sh_g);
|
||||
r0 = _mm256_shuffle_epi8(r0, sh_r);
|
||||
|
||||
b = v_uint16x16(b0);
|
||||
g = v_uint16x16(g0);
|
||||
r = v_uint16x16(r0);
|
||||
a = v_uint16x16(b0);
|
||||
b = v_uint16x16(g0);
|
||||
c = v_uint16x16(r0);
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& b, v_uint32x8& g, v_uint32x8& r )
|
||||
inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& a, v_uint32x8& b, v_uint32x8& c )
|
||||
{
|
||||
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
|
||||
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 8));
|
||||
@@ -2104,12 +2104,12 @@ inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& b, v_uint32x8&
|
||||
g0 = _mm256_shuffle_epi32(g0, 0xb1);
|
||||
r0 = _mm256_shuffle_epi32(r0, 0xc6);
|
||||
|
||||
b = v_uint32x8(b0);
|
||||
g = v_uint32x8(g0);
|
||||
r = v_uint32x8(r0);
|
||||
a = v_uint32x8(b0);
|
||||
b = v_uint32x8(g0);
|
||||
c = v_uint32x8(r0);
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& b, v_uint64x4& g, v_uint64x4& r )
|
||||
inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b, v_uint64x4& c )
|
||||
{
|
||||
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
|
||||
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 4));
|
||||
@@ -2122,12 +2122,12 @@ inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& b, v_uint64x4& g
|
||||
__m256i g0 = _mm256_alignr_epi8(s12, s01, 8);
|
||||
__m256i r0 = _mm256_unpackhi_epi64(s20r, s12);
|
||||
|
||||
b = v_uint64x4(b0);
|
||||
g = v_uint64x4(g0);
|
||||
r = v_uint64x4(r0);
|
||||
a = v_uint64x4(b0);
|
||||
b = v_uint64x4(g0);
|
||||
c = v_uint64x4(r0);
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& b, v_uint8x32& g, v_uint8x32& r, v_uint8x32& a )
|
||||
inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& a, v_uint8x32& b, v_uint8x32& c, v_uint8x32& d )
|
||||
{
|
||||
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
|
||||
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 32));
|
||||
@@ -2156,13 +2156,13 @@ inline void v_load_deinterleave( const uchar* ptr, v_uint8x32& b, v_uint8x32& g,
|
||||
__m256i r0 = _mm256_unpacklo_epi32(phl, phh);
|
||||
__m256i a0 = _mm256_unpackhi_epi32(phl, phh);
|
||||
|
||||
b = v_uint8x32(b0);
|
||||
g = v_uint8x32(g0);
|
||||
r = v_uint8x32(r0);
|
||||
a = v_uint8x32(a0);
|
||||
a = v_uint8x32(b0);
|
||||
b = v_uint8x32(g0);
|
||||
c = v_uint8x32(r0);
|
||||
d = v_uint8x32(a0);
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& b, v_uint16x16& g, v_uint16x16& r, v_uint16x16& a )
|
||||
inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& a, v_uint16x16& b, v_uint16x16& c, v_uint16x16& d )
|
||||
{
|
||||
__m256i bgr0 = _mm256_loadu_si256((const __m256i*)ptr);
|
||||
__m256i bgr1 = _mm256_loadu_si256((const __m256i*)(ptr + 16));
|
||||
@@ -2190,13 +2190,13 @@ inline void v_load_deinterleave( const ushort* ptr, v_uint16x16& b, v_uint16x16&
|
||||
__m256i r0 = _mm256_unpacklo_epi32(phl, phh);
|
||||
__m256i a0 = _mm256_unpackhi_epi32(phl, phh);
|
||||
|
||||
b = v_uint16x16(b0);
|
||||
g = v_uint16x16(g0);
|
||||
r = v_uint16x16(r0);
|
||||
a = v_uint16x16(a0);
|
||||
a = v_uint16x16(b0);
|
||||
b = v_uint16x16(g0);
|
||||
c = v_uint16x16(r0);
|
||||
d = v_uint16x16(a0);
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& b, v_uint32x8& g, v_uint32x8& r, v_uint32x8& a )
|
||||
inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& a, v_uint32x8& b, v_uint32x8& c, v_uint32x8& d )
|
||||
{
|
||||
__m256i p0 = _mm256_loadu_si256((const __m256i*)ptr);
|
||||
__m256i p1 = _mm256_loadu_si256((const __m256i*)(ptr + 8));
|
||||
@@ -2218,13 +2218,13 @@ inline void v_load_deinterleave( const unsigned* ptr, v_uint32x8& b, v_uint32x8&
|
||||
__m256i r0 = _mm256_unpacklo_epi32(phl, phh);
|
||||
__m256i a0 = _mm256_unpackhi_epi32(phl, phh);
|
||||
|
||||
b = v_uint32x8(b0);
|
||||
g = v_uint32x8(g0);
|
||||
r = v_uint32x8(r0);
|
||||
a = v_uint32x8(a0);
|
||||
a = v_uint32x8(b0);
|
||||
b = v_uint32x8(g0);
|
||||
c = v_uint32x8(r0);
|
||||
d = v_uint32x8(a0);
|
||||
}
|
||||
|
||||
inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& b, v_uint64x4& g, v_uint64x4& r, v_uint64x4& a )
|
||||
inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& a, v_uint64x4& b, v_uint64x4& c, v_uint64x4& d )
|
||||
{
|
||||
__m256i bgra0 = _mm256_loadu_si256((const __m256i*)ptr);
|
||||
__m256i bgra1 = _mm256_loadu_si256((const __m256i*)(ptr + 4));
|
||||
@@ -2241,10 +2241,10 @@ inline void v_load_deinterleave( const uint64* ptr, v_uint64x4& b, v_uint64x4& g
|
||||
__m256i r0 = _mm256_unpacklo_epi64(h02, h13);
|
||||
__m256i a0 = _mm256_unpackhi_epi64(h02, h13);
|
||||
|
||||
b = v_uint64x4(b0);
|
||||
g = v_uint64x4(g0);
|
||||
r = v_uint64x4(r0);
|
||||
a = v_uint64x4(a0);
|
||||
a = v_uint64x4(b0);
|
||||
b = v_uint64x4(g0);
|
||||
c = v_uint64x4(r0);
|
||||
d = v_uint64x4(a0);
|
||||
}
|
||||
|
||||
///////////////////////////// store interleave /////////////////////////////////////
|
||||
@@ -2353,7 +2353,7 @@ inline void v_store_interleave( uint64* ptr, const v_uint64x4& x, const v_uint64
|
||||
}
|
||||
}
|
||||
|
||||
inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x32& g, const v_uint8x32& r,
|
||||
inline void v_store_interleave( uchar* ptr, const v_uint8x32& a, const v_uint8x32& b, const v_uint8x32& c,
|
||||
hal::StoreMode mode=hal::STORE_UNALIGNED )
|
||||
{
|
||||
const __m256i sh_b = _mm256_setr_epi8(
|
||||
@@ -2366,9 +2366,9 @@ inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x3
|
||||
10, 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15,
|
||||
10, 5, 0, 11, 6, 1, 12, 7, 2, 13, 8, 3, 14, 9, 4, 15);
|
||||
|
||||
__m256i b0 = _mm256_shuffle_epi8(b.val, sh_b);
|
||||
__m256i g0 = _mm256_shuffle_epi8(g.val, sh_g);
|
||||
__m256i r0 = _mm256_shuffle_epi8(r.val, sh_r);
|
||||
__m256i b0 = _mm256_shuffle_epi8(a.val, sh_b);
|
||||
__m256i g0 = _mm256_shuffle_epi8(b.val, sh_g);
|
||||
__m256i r0 = _mm256_shuffle_epi8(c.val, sh_r);
|
||||
|
||||
const __m256i m0 = _mm256_setr_epi8(0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
|
||||
0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0);
|
||||
@@ -2403,7 +2403,7 @@ inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x3
|
||||
}
|
||||
}
|
||||
|
||||
inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint16x16& g, const v_uint16x16& r,
|
||||
inline void v_store_interleave( ushort* ptr, const v_uint16x16& a, const v_uint16x16& b, const v_uint16x16& c,
|
||||
hal::StoreMode mode=hal::STORE_UNALIGNED )
|
||||
{
|
||||
const __m256i sh_b = _mm256_setr_epi8(
|
||||
@@ -2416,9 +2416,9 @@ inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint1
|
||||
4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15,
|
||||
4, 5, 10, 11, 0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15);
|
||||
|
||||
__m256i b0 = _mm256_shuffle_epi8(b.val, sh_b);
|
||||
__m256i g0 = _mm256_shuffle_epi8(g.val, sh_g);
|
||||
__m256i r0 = _mm256_shuffle_epi8(r.val, sh_r);
|
||||
__m256i b0 = _mm256_shuffle_epi8(a.val, sh_b);
|
||||
__m256i g0 = _mm256_shuffle_epi8(b.val, sh_g);
|
||||
__m256i r0 = _mm256_shuffle_epi8(c.val, sh_r);
|
||||
|
||||
const __m256i m0 = _mm256_setr_epi8(0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1,
|
||||
0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0);
|
||||
@@ -2453,12 +2453,12 @@ inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint1
|
||||
}
|
||||
}
|
||||
|
||||
inline void v_store_interleave( unsigned* ptr, const v_uint32x8& b, const v_uint32x8& g, const v_uint32x8& r,
|
||||
inline void v_store_interleave( unsigned* ptr, const v_uint32x8& a, const v_uint32x8& b, const v_uint32x8& c,
|
||||
hal::StoreMode mode=hal::STORE_UNALIGNED )
|
||||
{
|
||||
__m256i b0 = _mm256_shuffle_epi32(b.val, 0x6c);
|
||||
__m256i g0 = _mm256_shuffle_epi32(g.val, 0xb1);
|
||||
__m256i r0 = _mm256_shuffle_epi32(r.val, 0xc6);
|
||||
__m256i b0 = _mm256_shuffle_epi32(a.val, 0x6c);
|
||||
__m256i g0 = _mm256_shuffle_epi32(b.val, 0xb1);
|
||||
__m256i r0 = _mm256_shuffle_epi32(c.val, 0xc6);
|
||||
|
||||
__m256i p0 = _mm256_blend_epi32(_mm256_blend_epi32(b0, g0, 0x92), r0, 0x24);
|
||||
__m256i p1 = _mm256_blend_epi32(_mm256_blend_epi32(g0, r0, 0x92), b0, 0x24);
|
||||
@@ -2488,12 +2488,12 @@ inline void v_store_interleave( unsigned* ptr, const v_uint32x8& b, const v_uint
|
||||
}
|
||||
}
|
||||
|
||||
inline void v_store_interleave( uint64* ptr, const v_uint64x4& b, const v_uint64x4& g, const v_uint64x4& r,
|
||||
inline void v_store_interleave( uint64* ptr, const v_uint64x4& a, const v_uint64x4& b, const v_uint64x4& c,
|
||||
hal::StoreMode mode=hal::STORE_UNALIGNED )
|
||||
{
|
||||
__m256i s01 = _mm256_unpacklo_epi64(b.val, g.val);
|
||||
__m256i s12 = _mm256_unpackhi_epi64(g.val, r.val);
|
||||
__m256i s20 = _mm256_blend_epi32(r.val, b.val, 0xcc);
|
||||
__m256i s01 = _mm256_unpacklo_epi64(a.val, b.val);
|
||||
__m256i s12 = _mm256_unpackhi_epi64(b.val, c.val);
|
||||
__m256i s20 = _mm256_blend_epi32(c.val, a.val, 0xcc);
|
||||
|
||||
__m256i bgr0 = _mm256_permute2x128_si256(s01, s20, 0 + 2*16);
|
||||
__m256i bgr1 = _mm256_blend_epi32(s01, s12, 0x0f);
|
||||
@@ -2519,14 +2519,14 @@ inline void v_store_interleave( uint64* ptr, const v_uint64x4& b, const v_uint64
|
||||
}
|
||||
}
|
||||
|
||||
inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x32& g,
|
||||
const v_uint8x32& r, const v_uint8x32& a,
|
||||
inline void v_store_interleave( uchar* ptr, const v_uint8x32& a, const v_uint8x32& b,
|
||||
const v_uint8x32& c, const v_uint8x32& d,
|
||||
hal::StoreMode mode=hal::STORE_UNALIGNED )
|
||||
{
|
||||
__m256i bg0 = _mm256_unpacklo_epi8(b.val, g.val);
|
||||
__m256i bg1 = _mm256_unpackhi_epi8(b.val, g.val);
|
||||
__m256i ra0 = _mm256_unpacklo_epi8(r.val, a.val);
|
||||
__m256i ra1 = _mm256_unpackhi_epi8(r.val, a.val);
|
||||
__m256i bg0 = _mm256_unpacklo_epi8(a.val, b.val);
|
||||
__m256i bg1 = _mm256_unpackhi_epi8(a.val, b.val);
|
||||
__m256i ra0 = _mm256_unpacklo_epi8(c.val, d.val);
|
||||
__m256i ra1 = _mm256_unpackhi_epi8(c.val, d.val);
|
||||
|
||||
__m256i bgra0_ = _mm256_unpacklo_epi16(bg0, ra0);
|
||||
__m256i bgra1_ = _mm256_unpackhi_epi16(bg0, ra0);
|
||||
@@ -2561,14 +2561,14 @@ inline void v_store_interleave( uchar* ptr, const v_uint8x32& b, const v_uint8x3
|
||||
}
|
||||
}
|
||||
|
||||
inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint16x16& g,
|
||||
const v_uint16x16& r, const v_uint16x16& a,
|
||||
inline void v_store_interleave( ushort* ptr, const v_uint16x16& a, const v_uint16x16& b,
|
||||
const v_uint16x16& c, const v_uint16x16& d,
|
||||
hal::StoreMode mode=hal::STORE_UNALIGNED )
|
||||
{
|
||||
__m256i bg0 = _mm256_unpacklo_epi16(b.val, g.val);
|
||||
__m256i bg1 = _mm256_unpackhi_epi16(b.val, g.val);
|
||||
__m256i ra0 = _mm256_unpacklo_epi16(r.val, a.val);
|
||||
__m256i ra1 = _mm256_unpackhi_epi16(r.val, a.val);
|
||||
__m256i bg0 = _mm256_unpacklo_epi16(a.val, b.val);
|
||||
__m256i bg1 = _mm256_unpackhi_epi16(a.val, b.val);
|
||||
__m256i ra0 = _mm256_unpacklo_epi16(c.val, d.val);
|
||||
__m256i ra1 = _mm256_unpackhi_epi16(c.val, d.val);
|
||||
|
||||
__m256i bgra0_ = _mm256_unpacklo_epi32(bg0, ra0);
|
||||
__m256i bgra1_ = _mm256_unpackhi_epi32(bg0, ra0);
|
||||
@@ -2603,14 +2603,14 @@ inline void v_store_interleave( ushort* ptr, const v_uint16x16& b, const v_uint1
|
||||
}
|
||||
}
|
||||
|
||||
inline void v_store_interleave( unsigned* ptr, const v_uint32x8& b, const v_uint32x8& g,
|
||||
const v_uint32x8& r, const v_uint32x8& a,
|
||||
inline void v_store_interleave( unsigned* ptr, const v_uint32x8& a, const v_uint32x8& b,
|
||||
const v_uint32x8& c, const v_uint32x8& d,
|
||||
hal::StoreMode mode=hal::STORE_UNALIGNED )
|
||||
{
|
||||
__m256i bg0 = _mm256_unpacklo_epi32(b.val, g.val);
|
||||
__m256i bg1 = _mm256_unpackhi_epi32(b.val, g.val);
|
||||
__m256i ra0 = _mm256_unpacklo_epi32(r.val, a.val);
|
||||
__m256i ra1 = _mm256_unpackhi_epi32(r.val, a.val);
|
||||
__m256i bg0 = _mm256_unpacklo_epi32(a.val, b.val);
|
||||
__m256i bg1 = _mm256_unpackhi_epi32(a.val, b.val);
|
||||
__m256i ra0 = _mm256_unpacklo_epi32(c.val, d.val);
|
||||
__m256i ra1 = _mm256_unpackhi_epi32(c.val, d.val);
|
||||
|
||||
__m256i bgra0_ = _mm256_unpacklo_epi64(bg0, ra0);
|
||||
__m256i bgra1_ = _mm256_unpackhi_epi64(bg0, ra0);
|
||||
@@ -2645,14 +2645,14 @@ inline void v_store_interleave( unsigned* ptr, const v_uint32x8& b, const v_uint
|
||||
}
|
||||
}
|
||||
|
||||
inline void v_store_interleave( uint64* ptr, const v_uint64x4& b, const v_uint64x4& g,
|
||||
const v_uint64x4& r, const v_uint64x4& a,
|
||||
inline void v_store_interleave( uint64* ptr, const v_uint64x4& a, const v_uint64x4& b,
|
||||
const v_uint64x4& c, const v_uint64x4& d,
|
||||
hal::StoreMode mode=hal::STORE_UNALIGNED )
|
||||
{
|
||||
__m256i bg0 = _mm256_unpacklo_epi64(b.val, g.val);
|
||||
__m256i bg1 = _mm256_unpackhi_epi64(b.val, g.val);
|
||||
__m256i ra0 = _mm256_unpacklo_epi64(r.val, a.val);
|
||||
__m256i ra1 = _mm256_unpackhi_epi64(r.val, a.val);
|
||||
__m256i bg0 = _mm256_unpacklo_epi64(a.val, b.val);
|
||||
__m256i bg1 = _mm256_unpackhi_epi64(a.val, b.val);
|
||||
__m256i ra0 = _mm256_unpacklo_epi64(c.val, d.val);
|
||||
__m256i ra1 = _mm256_unpackhi_epi64(c.val, d.val);
|
||||
|
||||
__m256i bgra0 = _mm256_permute2x128_si256(bg0, ra0, 0 + 2*16);
|
||||
__m256i bgra1 = _mm256_permute2x128_si256(bg1, ra1, 0 + 2*16);
|
||||
|
||||
@@ -11,11 +11,6 @@
|
||||
#define CV_SIMD128 1
|
||||
#define CV_SIMD128_64F 1
|
||||
|
||||
/**
|
||||
* todo: supporting half precision for power9
|
||||
* convert instractions xvcvhpsp, xvcvsphp
|
||||
**/
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -1077,117 +1072,188 @@ inline v_float64x2 v_lut_pairs(const double* tab, const int* idx) { return v_loa
|
||||
|
||||
inline v_int32x4 v_lut(const int* tab, const v_int32x4& idxvec)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[4];
|
||||
v_store_aligned(idx, idxvec);
|
||||
const int idx[4] = {
|
||||
vec_extract(idxvec.val, 0),
|
||||
vec_extract(idxvec.val, 1),
|
||||
vec_extract(idxvec.val, 2),
|
||||
vec_extract(idxvec.val, 3)
|
||||
};
|
||||
return v_int32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
|
||||
}
|
||||
|
||||
inline v_uint32x4 v_lut(const unsigned* tab, const v_int32x4& idxvec)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[4];
|
||||
v_store_aligned(idx, idxvec);
|
||||
const int idx[4] = {
|
||||
vec_extract(idxvec.val, 0),
|
||||
vec_extract(idxvec.val, 1),
|
||||
vec_extract(idxvec.val, 2),
|
||||
vec_extract(idxvec.val, 3)
|
||||
};
|
||||
return v_uint32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
|
||||
}
|
||||
|
||||
inline v_float32x4 v_lut(const float* tab, const v_int32x4& idxvec)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[4];
|
||||
v_store_aligned(idx, idxvec);
|
||||
const int idx[4] = {
|
||||
vec_extract(idxvec.val, 0),
|
||||
vec_extract(idxvec.val, 1),
|
||||
vec_extract(idxvec.val, 2),
|
||||
vec_extract(idxvec.val, 3)
|
||||
};
|
||||
return v_float32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
|
||||
}
|
||||
|
||||
inline v_float64x2 v_lut(const double* tab, const v_int32x4& idxvec)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[4];
|
||||
v_store_aligned(idx, idxvec);
|
||||
const int idx[2] = {
|
||||
vec_extract(idxvec.val, 0),
|
||||
vec_extract(idxvec.val, 1)
|
||||
};
|
||||
return v_float64x2(tab[idx[0]], tab[idx[1]]);
|
||||
}
|
||||
|
||||
inline void v_lut_deinterleave(const float* tab, const v_int32x4& idxvec, v_float32x4& x, v_float32x4& y)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[4];
|
||||
v_store_aligned(idx, idxvec);
|
||||
x = v_float32x4(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]);
|
||||
y = v_float32x4(tab[idx[0]+1], tab[idx[1]+1], tab[idx[2]+1], tab[idx[3]+1]);
|
||||
vec_float4 xy0 = vec_ld_l8(tab + vec_extract(idxvec.val, 0));
|
||||
vec_float4 xy1 = vec_ld_l8(tab + vec_extract(idxvec.val, 1));
|
||||
vec_float4 xy2 = vec_ld_l8(tab + vec_extract(idxvec.val, 2));
|
||||
vec_float4 xy3 = vec_ld_l8(tab + vec_extract(idxvec.val, 3));
|
||||
vec_float4 xy02 = vec_mergeh(xy0, xy2); // x0, x2, y0, y2
|
||||
vec_float4 xy13 = vec_mergeh(xy1, xy3); // x1, x3, y1, y3
|
||||
x.val = vec_mergeh(xy02, xy13);
|
||||
y.val = vec_mergel(xy02, xy13);
|
||||
}
|
||||
|
||||
inline void v_lut_deinterleave(const double* tab, const v_int32x4& idxvec, v_float64x2& x, v_float64x2& y)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[4];
|
||||
v_store_aligned(idx, idxvec);
|
||||
x = v_float64x2(tab[idx[0]], tab[idx[1]]);
|
||||
y = v_float64x2(tab[idx[0]+1], tab[idx[1]+1]);
|
||||
vec_double2 xy0 = vsx_ld(vec_extract(idxvec.val, 0), tab);
|
||||
vec_double2 xy1 = vsx_ld(vec_extract(idxvec.val, 1), tab);
|
||||
x.val = vec_mergeh(xy0, xy1);
|
||||
y.val = vec_mergel(xy0, xy1);
|
||||
}
|
||||
|
||||
inline v_int8x16 v_interleave_pairs(const v_int8x16& vec)
|
||||
{
|
||||
vec_short8 vec0 = vec_mergeh((vec_short8)vec.val, (vec_short8)vec_mergesql(vec.val, vec.val));
|
||||
vec0 = vec_mergeh(vec0, vec_mergesql(vec0, vec0));
|
||||
return v_int8x16(vec_mergeh((vec_char16)vec0, (vec_char16)vec_mergesql(vec0, vec0)));
|
||||
static const vec_uchar16 perm = {0, 2, 1, 3, 4, 6, 5, 7, 8, 10, 9, 11, 12, 14, 13, 15};
|
||||
return v_int8x16(vec_perm(vec.val, vec.val, perm));
|
||||
}
|
||||
inline v_uint8x16 v_interleave_pairs(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); }
|
||||
inline v_uint8x16 v_interleave_pairs(const v_uint8x16& vec)
|
||||
{ return v_reinterpret_as_u8(v_interleave_pairs(v_reinterpret_as_s8(vec))); }
|
||||
|
||||
inline v_int8x16 v_interleave_quads(const v_int8x16& vec)
|
||||
{
|
||||
vec_char16 vec0 = (vec_char16)vec_mergeh((vec_int4)vec.val, (vec_int4)vec_mergesql(vec.val, vec.val));
|
||||
return v_int8x16(vec_mergeh(vec0, vec_mergesql(vec0, vec0)));
|
||||
static const vec_uchar16 perm = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15};
|
||||
return v_int8x16(vec_perm(vec.val, vec.val, perm));
|
||||
}
|
||||
inline v_uint8x16 v_interleave_quads(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); }
|
||||
inline v_uint8x16 v_interleave_quads(const v_uint8x16& vec)
|
||||
{ return v_reinterpret_as_u8(v_interleave_quads(v_reinterpret_as_s8(vec))); }
|
||||
|
||||
inline v_int16x8 v_interleave_pairs(const v_int16x8& vec)
|
||||
{
|
||||
vec_short8 vec0 = (vec_short8)vec_mergeh((vec_int4)vec.val, (vec_int4)vec_mergesql(vec.val, vec.val));
|
||||
return v_int16x8(vec_mergeh(vec0, vec_mergesql(vec0, vec0)));
|
||||
static const vec_uchar16 perm = {0,1, 4,5, 2,3, 6,7, 8,9, 12,13, 10,11, 14,15};
|
||||
return v_int16x8(vec_perm(vec.val, vec.val, perm));
|
||||
}
|
||||
inline v_uint16x8 v_interleave_pairs(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); }
|
||||
inline v_uint16x8 v_interleave_pairs(const v_uint16x8& vec)
|
||||
{ return v_reinterpret_as_u16(v_interleave_pairs(v_reinterpret_as_s16(vec))); }
|
||||
|
||||
inline v_int16x8 v_interleave_quads(const v_int16x8& vec)
|
||||
{
|
||||
return v_int16x8(vec_mergeh(vec.val, vec_mergesql(vec.val, vec.val)));
|
||||
static const vec_uchar16 perm = {0,1, 8,9, 2,3, 10,11, 4,5, 12,13, 6,7, 14,15};
|
||||
return v_int16x8(vec_perm(vec.val, vec.val, perm));
|
||||
}
|
||||
inline v_uint16x8 v_interleave_quads(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); }
|
||||
inline v_uint16x8 v_interleave_quads(const v_uint16x8& vec)
|
||||
{ return v_reinterpret_as_u16(v_interleave_quads(v_reinterpret_as_s16(vec))); }
|
||||
|
||||
inline v_int32x4 v_interleave_pairs(const v_int32x4& vec)
|
||||
{
|
||||
return v_int32x4(vec_mergeh(vec.val, vec_mergesql(vec.val, vec.val)));
|
||||
static const vec_uchar16 perm = {0,1,2,3, 8,9,10,11, 4,5,6,7, 12,13,14,15};
|
||||
return v_int32x4(vec_perm(vec.val, vec.val, perm));
|
||||
}
|
||||
inline v_uint32x4 v_interleave_pairs(const v_uint32x4& vec) { return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); }
|
||||
inline v_float32x4 v_interleave_pairs(const v_float32x4& vec) { return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); }
|
||||
inline v_uint32x4 v_interleave_pairs(const v_uint32x4& vec)
|
||||
{ return v_reinterpret_as_u32(v_interleave_pairs(v_reinterpret_as_s32(vec))); }
|
||||
inline v_float32x4 v_interleave_pairs(const v_float32x4& vec)
|
||||
{ return v_reinterpret_as_f32(v_interleave_pairs(v_reinterpret_as_s32(vec))); }
|
||||
|
||||
inline v_int8x16 v_pack_triplets(const v_int8x16& vec)
|
||||
{
|
||||
schar CV_DECL_ALIGNED(32) val[16];
|
||||
v_store_aligned(val, vec);
|
||||
return v_int8x16(val[0], val[1], val[2], val[4], val[5], val[6], val[8], val[9], val[10], val[12], val[13], val[14], val[15], val[15], val[15], val[15]);
|
||||
static const vec_uchar16 perm = {0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 15, 15, 15};
|
||||
return v_int8x16(vec_perm(vec.val, vec.val, perm));
|
||||
}
|
||||
inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec) { return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); }
|
||||
inline v_uint8x16 v_pack_triplets(const v_uint8x16& vec)
|
||||
{ return v_reinterpret_as_u8(v_pack_triplets(v_reinterpret_as_s8(vec))); }
|
||||
|
||||
inline v_int16x8 v_pack_triplets(const v_int16x8& vec)
|
||||
{
|
||||
short CV_DECL_ALIGNED(32) val[8];
|
||||
v_store_aligned(val, vec);
|
||||
return v_int16x8(val[0], val[1], val[2], val[4], val[5], val[6], val[7], val[7]);
|
||||
static const vec_uchar16 perm = {0,1, 2,3, 4,5, 8,9, 10,11, 12,13, 14,15, 14,15};
|
||||
return v_int16x8(vec_perm(vec.val, vec.val, perm));
|
||||
}
|
||||
inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec) { return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); }
|
||||
inline v_uint16x8 v_pack_triplets(const v_uint16x8& vec)
|
||||
{ return v_reinterpret_as_u16(v_pack_triplets(v_reinterpret_as_s16(vec))); }
|
||||
|
||||
inline v_int32x4 v_pack_triplets(const v_int32x4& vec) { return vec; }
|
||||
inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec) { return vec; }
|
||||
inline v_float32x4 v_pack_triplets(const v_float32x4& vec) { return vec; }
|
||||
inline v_int32x4 v_pack_triplets(const v_int32x4& vec)
|
||||
{ return vec; }
|
||||
inline v_uint32x4 v_pack_triplets(const v_uint32x4& vec)
|
||||
{ return vec; }
|
||||
inline v_float32x4 v_pack_triplets(const v_float32x4& vec)
|
||||
{ return vec; }
|
||||
|
||||
/////// FP16 support ////////
|
||||
|
||||
// [TODO] implement these 2 using VSX or universal intrinsics (copy from intrin_sse.cpp and adopt)
|
||||
inline v_float32x4 v_load_expand(const float16_t* ptr)
|
||||
{
|
||||
return v_float32x4((float)ptr[0], (float)ptr[1], (float)ptr[2], (float)ptr[3]);
|
||||
vec_ushort8 vf16 = vec_ld_l8((const ushort*)ptr);
|
||||
#if CV_VSX3 && defined(vec_extract_fp_from_shorth)
|
||||
return v_float32x4(vec_extract_fp_from_shorth(vf16));
|
||||
#elif CV_VSX3 && !defined(CV_COMPILER_VSX_BROKEN_ASM)
|
||||
vec_float4 vf32;
|
||||
__asm__ __volatile__ ("xvcvhpsp %x0,%x1" : "=wf" (vf32) : "wa" (vec_mergeh(vf16, vf16)));
|
||||
return v_float32x4(vf32);
|
||||
#else
|
||||
const vec_int4 z = vec_int4_z, delta = vec_int4_sp(0x38000000);
|
||||
const vec_int4 signmask = vec_int4_sp(0x80000000);
|
||||
const vec_int4 maxexp = vec_int4_sp(0x7c000000);
|
||||
const vec_float4 deltaf = vec_float4_c(vec_int4_sp(0x38800000));
|
||||
|
||||
vec_int4 bits = vec_int4_c(vec_mergeh(vec_short8_c(z), vec_short8_c(vf16)));
|
||||
vec_int4 e = vec_and(bits, maxexp), sign = vec_and(bits, signmask);
|
||||
vec_int4 t = vec_add(vec_sr(vec_xor(bits, sign), vec_uint4_sp(3)), delta); // ((h & 0x7fff) << 13) + delta
|
||||
vec_int4 zt = vec_int4_c(vec_sub(vec_float4_c(vec_add(t, vec_int4_sp(1 << 23))), deltaf));
|
||||
|
||||
t = vec_add(t, vec_and(delta, vec_cmpeq(maxexp, e)));
|
||||
vec_bint4 zmask = vec_cmpeq(e, z);
|
||||
vec_int4 ft = vec_sel(t, zt, zmask);
|
||||
return v_float32x4(vec_float4_c(vec_or(ft, sign)));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void v_pack_store(float16_t* ptr, const v_float32x4& v)
|
||||
{
|
||||
float CV_DECL_ALIGNED(32) f[4];
|
||||
v_store_aligned(f, v);
|
||||
ptr[0] = float16_t(f[0]);
|
||||
ptr[1] = float16_t(f[1]);
|
||||
ptr[2] = float16_t(f[2]);
|
||||
ptr[3] = float16_t(f[3]);
|
||||
// fixme: Is there any buitin op or intrinsic that cover "xvcvsphp"?
|
||||
#if CV_VSX3 && !defined(CV_COMPILER_VSX_BROKEN_ASM)
|
||||
vec_ushort8 vf16;
|
||||
__asm__ __volatile__ ("xvcvsphp %x0,%x1" : "=wa" (vf16) : "wf" (v.val));
|
||||
vec_st_l8(vec_mergesqe(vf16, vf16), ptr);
|
||||
#else
|
||||
const vec_int4 signmask = vec_int4_sp(0x80000000);
|
||||
const vec_int4 rval = vec_int4_sp(0x3f000000);
|
||||
|
||||
vec_int4 t = vec_int4_c(v.val);
|
||||
vec_int4 sign = vec_sra(vec_and(t, signmask), vec_uint4_sp(16));
|
||||
t = vec_and(vec_nor(signmask, signmask), t);
|
||||
|
||||
vec_bint4 finitemask = vec_cmpgt(vec_int4_sp(0x47800000), t);
|
||||
vec_bint4 isnan = vec_cmpgt(t, vec_int4_sp(0x7f800000));
|
||||
vec_int4 naninf = vec_sel(vec_int4_sp(0x7c00), vec_int4_sp(0x7e00), isnan);
|
||||
vec_bint4 tinymask = vec_cmpgt(vec_int4_sp(0x38800000), t);
|
||||
vec_int4 tt = vec_int4_c(vec_add(vec_float4_c(t), vec_float4_c(rval)));
|
||||
tt = vec_sub(tt, rval);
|
||||
vec_int4 odd = vec_and(vec_sr(t, vec_uint4_sp(13)), vec_int4_sp(1));
|
||||
vec_int4 nt = vec_add(t, vec_int4_sp(0xc8000fff));
|
||||
nt = vec_sr(vec_add(nt, odd), vec_uint4_sp(13));
|
||||
t = vec_sel(nt, tt, tinymask);
|
||||
t = vec_sel(naninf, t, finitemask);
|
||||
t = vec_or(t, sign);
|
||||
vec_st_l8(vec_packs(t, t), ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void v_cleanup() {}
|
||||
|
||||
@@ -163,7 +163,7 @@ public:
|
||||
template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
|
||||
|
||||
//! extract part of the matrix
|
||||
template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
|
||||
template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int base_row, int base_col) const;
|
||||
|
||||
//! extract the matrix row
|
||||
Matx<_Tp, 1, n> row(int i) const;
|
||||
@@ -191,8 +191,8 @@ public:
|
||||
Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const;
|
||||
|
||||
//! element access
|
||||
const _Tp& operator ()(int i, int j) const;
|
||||
_Tp& operator ()(int i, int j);
|
||||
const _Tp& operator ()(int row, int col) const;
|
||||
_Tp& operator ()(int row, int col);
|
||||
|
||||
//! 1D element access
|
||||
const _Tp& operator ()(int i) const;
|
||||
@@ -742,13 +742,13 @@ Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
|
||||
|
||||
template<typename _Tp, int m, int n>
|
||||
template<int m1, int n1> inline
|
||||
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
|
||||
Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int base_row, int base_col) const
|
||||
{
|
||||
CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
|
||||
CV_DbgAssert(0 <= base_row && base_row+m1 <= m && 0 <= base_col && base_col+n1 <= n);
|
||||
Matx<_Tp, m1, n1> s;
|
||||
for( int di = 0; di < m1; di++ )
|
||||
for( int dj = 0; dj < n1; dj++ )
|
||||
s(di, dj) = (*this)(i+di, j+dj);
|
||||
s(di, dj) = (*this)(base_row+di, base_col+dj);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -779,17 +779,17 @@ typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
const _Tp& Matx<_Tp, m, n>::operator()(int i, int j) const
|
||||
const _Tp& Matx<_Tp, m, n>::operator()(int row_idx, int col_idx) const
|
||||
{
|
||||
CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
|
||||
return this->val[i*n + j];
|
||||
CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n );
|
||||
return this->val[row_idx*n + col_idx];
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
_Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
|
||||
_Tp& Matx<_Tp, m, n>::operator ()(int row_idx, int col_idx)
|
||||
{
|
||||
CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
|
||||
return val[i*n + j];
|
||||
CV_DbgAssert( (unsigned)row_idx < (unsigned)m && (unsigned)col_idx < (unsigned)n );
|
||||
return val[row_idx*n + col_idx];
|
||||
}
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
|
||||
@@ -96,6 +96,7 @@
|
||||
#define clWaitForEvents clWaitForEvents_
|
||||
|
||||
#if defined __APPLE__
|
||||
#define CL_SILENCE_DEPRECATION
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define CV_VERSION_MAJOR 4
|
||||
#define CV_VERSION_MINOR 1
|
||||
#define CV_VERSION_REVISION 0
|
||||
#define CV_VERSION_STATUS "-openvino"
|
||||
#define CV_VERSION_STATUS ""
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||
|
||||
@@ -291,6 +291,8 @@ VSX_IMPL_1RG(vec_udword2, wi, vec_float4, wf, xvcvspuxds, vec_ctulo)
|
||||
*
|
||||
* So we're not able to use inline asm and only use built-in functions that CLANG supports
|
||||
* and use __builtin_convertvector if clang missng any of vector conversions built-in functions
|
||||
*
|
||||
* todo: clang asm template bug is fixed, need to reconsider the current workarounds.
|
||||
*/
|
||||
|
||||
// convert vector helper
|
||||
|
||||
@@ -918,7 +918,13 @@ int cv::borderInterpolate( int p, int len, int borderType )
|
||||
{
|
||||
CV_TRACE_FUNCTION_VERBOSE();
|
||||
|
||||
CV_DbgAssert(len > 0);
|
||||
|
||||
#ifdef CV_STATIC_ANALYSIS
|
||||
if(p >= 0 && p < len)
|
||||
#else
|
||||
if( (unsigned)p < (unsigned)len )
|
||||
#endif
|
||||
;
|
||||
else if( borderType == BORDER_REPLICATE )
|
||||
p = p < 0 ? 0 : len - 1;
|
||||
@@ -934,7 +940,11 @@ int cv::borderInterpolate( int p, int len, int borderType )
|
||||
else
|
||||
p = len - 1 - (p - len) - delta;
|
||||
}
|
||||
#ifdef CV_STATIC_ANALYSIS
|
||||
while(p < 0 || p >= len);
|
||||
#else
|
||||
while( (unsigned)p >= (unsigned)len );
|
||||
#endif
|
||||
}
|
||||
else if( borderType == BORDER_WRAP )
|
||||
{
|
||||
|
||||
+469
-86
@@ -48,13 +48,13 @@
|
||||
|
||||
#ifdef HAVE_DIRECTX
|
||||
#include <vector>
|
||||
# include "directx.inc.hpp"
|
||||
#include "directx.inc.hpp"
|
||||
#else // HAVE_DIRECTX
|
||||
#define NO_DIRECTX_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without DirectX support")
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_OPENCL
|
||||
# define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
|
||||
#define NO_OPENCL_SUPPORT_ERROR CV_Error(cv::Error::StsBadFunc, "OpenCV was build without OpenCL support")
|
||||
#endif // HAVE_OPENCL
|
||||
|
||||
namespace cv { namespace directx {
|
||||
@@ -168,7 +168,7 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
|
||||
//case DXGI_FORMAT_BC7_TYPELESS:
|
||||
//case DXGI_FORMAT_BC7_UNORM:
|
||||
//case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
#ifdef HAVE_DIRECTX_NV12 //D3DX11 should support DXGI_FORMAT_NV12.
|
||||
case DXGI_FORMAT_NV12: return CV_8UC3;
|
||||
#endif
|
||||
default: break;
|
||||
@@ -256,75 +256,70 @@ Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available platforms");
|
||||
|
||||
std::vector<cl_platform_id> platforms(numPlatforms);
|
||||
status = clGetPlatformIDs(numPlatforms, &platforms[0], NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
|
||||
|
||||
// TODO Filter platforms by name from OPENCV_OPENCL_DEVICE
|
||||
size_t exts_len;
|
||||
cv::AutoBuffer<char> extensions;
|
||||
bool is_support_cl_khr_d3d11_sharing = false;
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
bool is_support_cl_nv_d3d11_sharing = false;
|
||||
#endif
|
||||
for (int i = 0; i < (int)numPlatforms; i++)
|
||||
{
|
||||
status = clGetPlatformIDs(numPlatforms, &platforms[i], NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get number of platforms");
|
||||
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, 0, NULL, &exts_len);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get length of CL_PLATFORM_EXTENSIONS");
|
||||
extensions.resize(exts_len);
|
||||
status = clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS, exts_len, static_cast<void*>(extensions.data()), NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available CL_PLATFORM_EXTENSIONS");
|
||||
if (strstr(extensions.data(), "cl_khr_d3d11_sharing"))
|
||||
is_support_cl_khr_d3d11_sharing = true;
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
if (strstr(extensions.data(), "cl_nv_d3d11_sharing"))
|
||||
is_support_cl_nv_d3d11_sharing = true;
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
if (!is_support_cl_nv_d3d11_sharing && !is_support_cl_khr_d3d11_sharing)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
|
||||
#else
|
||||
if (!is_support_cl_khr_d3d11_sharing)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
|
||||
#endif
|
||||
|
||||
int found = -1;
|
||||
cl_device_id device = NULL;
|
||||
cl_uint numDevices = 0;
|
||||
cl_context context = NULL;
|
||||
|
||||
// try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
|
||||
for (int i = 0; i < (int)numPlatforms; i++)
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
if (is_support_cl_nv_d3d11_sharing)
|
||||
{
|
||||
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
|
||||
if (!clGetDeviceIDsFromD3D11KHR)
|
||||
continue;
|
||||
|
||||
device = NULL;
|
||||
numDevices = 0;
|
||||
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
|
||||
CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
|
||||
if (status != CL_SUCCESS)
|
||||
continue;
|
||||
if (numDevices > 0)
|
||||
{
|
||||
cl_context_properties properties[] = {
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
|
||||
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
|
||||
CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
|
||||
NULL, NULL
|
||||
};
|
||||
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
{
|
||||
clReleaseDevice(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found < 0)
|
||||
{
|
||||
// try with CL_ALL_DEVICES_FOR_D3D11_KHR
|
||||
// try with CL_PREFERRED_DEVICES_FOR_D3D11_NV
|
||||
for (int i = 0; i < (int)numPlatforms; i++)
|
||||
{
|
||||
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
|
||||
if (!clGetDeviceIDsFromD3D11KHR)
|
||||
clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = (clGetDeviceIDsFromD3D11NV_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11NV");
|
||||
if (!clGetDeviceIDsFromD3D11NV)
|
||||
continue;
|
||||
|
||||
device = NULL;
|
||||
numDevices = 0;
|
||||
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
|
||||
CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
|
||||
status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
|
||||
CL_PREFERRED_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
|
||||
if (status != CL_SUCCESS)
|
||||
continue;
|
||||
if (numDevices > 0)
|
||||
{
|
||||
cl_context_properties properties[] = {
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
|
||||
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
|
||||
CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
|
||||
NULL, NULL
|
||||
CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)(pD3D11Device),
|
||||
//CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
|
||||
0
|
||||
};
|
||||
|
||||
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
{
|
||||
@@ -338,9 +333,127 @@ Context& initializeContextFromD3D11Device(ID3D11Device* pD3D11Device)
|
||||
}
|
||||
}
|
||||
if (found < 0)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
|
||||
}
|
||||
{
|
||||
// try with CL_ALL_DEVICES_FOR_D3D11_NV
|
||||
for (int i = 0; i < (int)numPlatforms; i++)
|
||||
{
|
||||
clGetDeviceIDsFromD3D11NV_fn clGetDeviceIDsFromD3D11NV = (clGetDeviceIDsFromD3D11NV_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11NV");
|
||||
if (!clGetDeviceIDsFromD3D11NV)
|
||||
continue;
|
||||
|
||||
device = NULL;
|
||||
numDevices = 0;
|
||||
status = clGetDeviceIDsFromD3D11NV(platforms[i], CL_D3D11_DEVICE_NV, pD3D11Device,
|
||||
CL_ALL_DEVICES_FOR_D3D11_NV, 1, &device, &numDevices);
|
||||
if (status != CL_SUCCESS)
|
||||
continue;
|
||||
if (numDevices > 0)
|
||||
{
|
||||
cl_context_properties properties[] = {
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
|
||||
CL_CONTEXT_D3D11_DEVICE_NV, (cl_context_properties)(pD3D11Device),
|
||||
//CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
|
||||
0
|
||||
};
|
||||
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
{
|
||||
clReleaseDevice(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (is_support_cl_khr_d3d11_sharing)
|
||||
{
|
||||
if (found < 0)
|
||||
{
|
||||
// try with CL_PREFERRED_DEVICES_FOR_D3D11_KHR
|
||||
for (int i = 0; i < (int)numPlatforms; i++)
|
||||
{
|
||||
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
|
||||
if (!clGetDeviceIDsFromD3D11KHR)
|
||||
continue;
|
||||
|
||||
device = NULL;
|
||||
numDevices = 0;
|
||||
|
||||
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
|
||||
CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
|
||||
|
||||
if (status != CL_SUCCESS)
|
||||
continue;
|
||||
if (numDevices > 0)
|
||||
{
|
||||
cl_context_properties properties[] = {
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
|
||||
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
|
||||
CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
|
||||
NULL, NULL
|
||||
};
|
||||
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
{
|
||||
clReleaseDevice(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found < 0)
|
||||
{
|
||||
// try with CL_ALL_DEVICES_FOR_D3D11_KHR
|
||||
for (int i = 0; i < (int)numPlatforms; i++)
|
||||
{
|
||||
clGetDeviceIDsFromD3D11KHR_fn clGetDeviceIDsFromD3D11KHR = (clGetDeviceIDsFromD3D11KHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platforms[i], "clGetDeviceIDsFromD3D11KHR");
|
||||
if (!clGetDeviceIDsFromD3D11KHR)
|
||||
continue;
|
||||
|
||||
device = NULL;
|
||||
numDevices = 0;
|
||||
status = clGetDeviceIDsFromD3D11KHR(platforms[i], CL_D3D11_DEVICE_KHR, pD3D11Device,
|
||||
CL_ALL_DEVICES_FOR_D3D11_KHR, 1, &device, &numDevices);
|
||||
if (status != CL_SUCCESS)
|
||||
continue;
|
||||
if (numDevices > 0)
|
||||
{
|
||||
cl_context_properties properties[] = {
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[i],
|
||||
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(pD3D11Device),
|
||||
CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE,
|
||||
NULL, NULL
|
||||
};
|
||||
context = clCreateContext(properties, 1, &device, NULL, NULL, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
{
|
||||
clReleaseDevice(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
found = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found < 0)
|
||||
{
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't create context for DirectX interop");
|
||||
}
|
||||
|
||||
Context& ctx = Context::getDefault(false);
|
||||
initializeContextFromHandle(ctx, platforms[found], context, device);
|
||||
@@ -679,29 +792,85 @@ Context& initializeContextFromDirect3DDevice9(IDirect3DDevice9* pDirect3DDevice9
|
||||
} // namespace cv::ocl
|
||||
|
||||
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
|
||||
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
clCreateFromD3D11Texture2DNV_fn clCreateFromD3D11Texture2DNV = NULL;
|
||||
clEnqueueAcquireD3D11ObjectsNV_fn clEnqueueAcquireD3D11ObjectsNV = NULL;
|
||||
clEnqueueReleaseD3D11ObjectsNV_fn clEnqueueReleaseD3D11ObjectsNV = NULL;
|
||||
#endif
|
||||
clCreateFromD3D11Texture2DKHR_fn clCreateFromD3D11Texture2DKHR = NULL;
|
||||
clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11ObjectsKHR = NULL;
|
||||
clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11ObjectsKHR = NULL;
|
||||
|
||||
static void __OpenCLinitializeD3D11()
|
||||
static bool __OpenCLinitializeD3D11()
|
||||
{
|
||||
using namespace cv::ocl;
|
||||
static cl_platform_id initializedPlatform = NULL;
|
||||
cl_platform_id platform = (cl_platform_id)Platform::getDefault().ptr();
|
||||
if (initializedPlatform != platform)
|
||||
|
||||
bool useCLNVEXT = false;
|
||||
size_t exts_len;
|
||||
cl_int status = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, 0, NULL, &exts_len);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't get length of CL_PLATFORM_EXTENSIONS");
|
||||
cv::AutoBuffer<char> extensions(exts_len);
|
||||
status = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS, exts_len, static_cast<void*>(extensions.data()), NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No available CL_PLATFORM_EXTENSIONS");
|
||||
bool is_support_cl_khr_d3d11_sharing = false;
|
||||
if (strstr(extensions.data(), "cl_khr_d3d11_sharing"))
|
||||
is_support_cl_khr_d3d11_sharing = true;
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
bool is_support_cl_nv_d3d11_sharing = false;
|
||||
if (strstr(extensions.data(), "cl_nv_d3d11_sharing"))
|
||||
is_support_cl_nv_d3d11_sharing = true;
|
||||
if (!is_support_cl_nv_d3d11_sharing && !is_support_cl_khr_d3d11_sharing)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
|
||||
#else
|
||||
if (!is_support_cl_khr_d3d11_sharing)
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: No supported extensions");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
if (is_support_cl_nv_d3d11_sharing)
|
||||
{
|
||||
clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
|
||||
clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
|
||||
clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
|
||||
initializedPlatform = platform;
|
||||
if (initializedPlatform != platform)
|
||||
{
|
||||
clCreateFromD3D11Texture2DNV = (clCreateFromD3D11Texture2DNV_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DNV");
|
||||
clEnqueueAcquireD3D11ObjectsNV = (clEnqueueAcquireD3D11ObjectsNV_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsNV");
|
||||
clEnqueueReleaseD3D11ObjectsNV = (clEnqueueReleaseD3D11ObjectsNV_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsNV");
|
||||
initializedPlatform = platform;
|
||||
}
|
||||
if (clCreateFromD3D11Texture2DNV && clEnqueueAcquireD3D11ObjectsNV && clEnqueueReleaseD3D11ObjectsNV)
|
||||
{
|
||||
useCLNVEXT = true;
|
||||
}
|
||||
}
|
||||
if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
|
||||
if (is_support_cl_khr_d3d11_sharing)
|
||||
{
|
||||
if (initializedPlatform != platform)
|
||||
{
|
||||
clCreateFromD3D11Texture2DKHR = (clCreateFromD3D11Texture2DKHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clCreateFromD3D11Texture2DKHR");
|
||||
clEnqueueAcquireD3D11ObjectsKHR = (clEnqueueAcquireD3D11ObjectsKHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueAcquireD3D11ObjectsKHR");
|
||||
clEnqueueReleaseD3D11ObjectsKHR = (clEnqueueReleaseD3D11ObjectsKHR_fn)
|
||||
clGetExtensionFunctionAddressForPlatform(platform, "clEnqueueReleaseD3D11ObjectsKHR");
|
||||
initializedPlatform = platform;
|
||||
}
|
||||
if (!clCreateFromD3D11Texture2DKHR || !clEnqueueAcquireD3D11ObjectsKHR || !clEnqueueReleaseD3D11ObjectsKHR)
|
||||
{
|
||||
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Can't find functions for D3D11");
|
||||
}
|
||||
}
|
||||
}
|
||||
return useCLNVEXT;
|
||||
}
|
||||
#endif // defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
|
||||
|
||||
@@ -762,14 +931,9 @@ bool ocl_convert_bgr_to_nv12(
|
||||
|
||||
namespace directx {
|
||||
|
||||
void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
|
||||
static void __convertToD3D11Texture2DKHR(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
{
|
||||
CV_UNUSED(src); CV_UNUSED(pD3D11Texture2D);
|
||||
#if !defined(HAVE_DIRECTX)
|
||||
NO_DIRECTX_SUPPORT_ERROR;
|
||||
#elif defined(HAVE_OPENCL)
|
||||
__OpenCLinitializeD3D11();
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc = { 0 };
|
||||
pD3D11Texture2D->GetDesc(&desc);
|
||||
|
||||
@@ -797,7 +961,6 @@ void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
cl_mem clImageUV = 0;
|
||||
#endif
|
||||
|
||||
clImage = clCreateFromD3D11Texture2DKHR(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DKHR failed");
|
||||
@@ -863,22 +1026,108 @@ void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
// TODO memcpy
|
||||
NO_OPENCL_SUPPORT_ERROR;
|
||||
#if defined(HAVE_OPENCL_D3D11_NV)
|
||||
static void __convertToD3D11Texture2DNV(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc = { 0 };
|
||||
pD3D11Texture2D->GetDesc(&desc);
|
||||
|
||||
int srcType = src.type();
|
||||
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
|
||||
CV_Assert(textureType == srcType);
|
||||
|
||||
Size srcSize = src.size();
|
||||
CV_Assert(srcSize.width == (int)desc.Width && srcSize.height == (int)desc.Height);
|
||||
|
||||
UMat u = src.getUMat();
|
||||
|
||||
// TODO Add support for roi
|
||||
CV_Assert(u.offset == 0);
|
||||
CV_Assert(u.isContinuous());
|
||||
|
||||
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
|
||||
|
||||
using namespace cv::ocl;
|
||||
Context& ctx = Context::getDefault();
|
||||
cl_context context = (cl_context)ctx.ptr();
|
||||
|
||||
cl_int status = 0;
|
||||
cl_mem clImage = 0;
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
cl_mem clImageUV = 0;
|
||||
#endif
|
||||
clImage = clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 0, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
|
||||
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
if (DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
clImageUV = clCreateFromD3D11Texture2DNV(context, CL_MEM_WRITE_ONLY, pD3D11Texture2D, 1, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
|
||||
}
|
||||
#endif
|
||||
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
|
||||
status = clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
|
||||
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
status = clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
|
||||
|
||||
if(!ocl::ocl_convert_bgr_to_nv12(clBuffer, (int)u.step[0], u.cols, u.rows, clImage, clImageUV))
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_bgr_to_nv12 failed");
|
||||
|
||||
status = clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
size_t offset = 0; // TODO
|
||||
size_t origin[3] = { 0, 0, 0 };
|
||||
size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
|
||||
|
||||
status = clEnqueueCopyBufferToImage(q, clBuffer, clImage, offset, origin, region, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyBufferToImage failed");
|
||||
}
|
||||
|
||||
status = clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
|
||||
|
||||
status = clFinish(q); // TODO Use events
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
|
||||
|
||||
status = clReleaseMemObject(clImage); // TODO RAII
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
status = clReleaseMemObject(clImageUV);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
|
||||
#if defined(HAVE_DIRECTX) && defined(HAVE_OPENCL)
|
||||
static void __convertFromD3D11Texture2DKHR(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
|
||||
{
|
||||
CV_UNUSED(pD3D11Texture2D); CV_UNUSED(dst);
|
||||
#if !defined(HAVE_DIRECTX)
|
||||
NO_DIRECTX_SUPPORT_ERROR;
|
||||
#elif defined(HAVE_OPENCL)
|
||||
__OpenCLinitializeD3D11();
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc = { 0 };
|
||||
pD3D11Texture2D->GetDesc(&desc);
|
||||
|
||||
@@ -968,10 +1217,144 @@ void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
// TODO memcpy
|
||||
#if defined(HAVE_OPENCL_D3D11_NV)
|
||||
static void __convertFromD3D11Texture2DNV(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc = { 0 };
|
||||
pD3D11Texture2D->GetDesc(&desc);
|
||||
|
||||
int textureType = getTypeFromDXGI_FORMAT(desc.Format);
|
||||
CV_Assert(textureType >= 0);
|
||||
|
||||
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
|
||||
dst.create(Size(desc.Width, desc.Height), textureType);
|
||||
UMat u = dst.getUMat();
|
||||
|
||||
// TODO Add support for roi
|
||||
CV_Assert(u.offset == 0);
|
||||
CV_Assert(u.isContinuous());
|
||||
|
||||
cl_mem clBuffer = (cl_mem)u.handle(ACCESS_READ);
|
||||
|
||||
using namespace cv::ocl;
|
||||
Context& ctx = Context::getDefault();
|
||||
cl_context context = (cl_context)ctx.ptr();
|
||||
|
||||
cl_int status = 0;
|
||||
cl_mem clImage = 0;
|
||||
|
||||
clImage = clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 0, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
|
||||
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
cl_mem clImageUV = 0;
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
clImageUV = clCreateFromD3D11Texture2DNV(context, CL_MEM_READ_ONLY, pD3D11Texture2D, 1, &status);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clCreateFromD3D11Texture2DNV failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
cl_command_queue q = (cl_command_queue)Queue::getDefault().ptr();
|
||||
status = clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
|
||||
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
if (DXGI_FORMAT::DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
status = clEnqueueAcquireD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueAcquireD3D11ObjectsNV failed");
|
||||
|
||||
if (!ocl::ocl_convert_nv12_to_bgr(clImage, clImageUV, clBuffer, (int)u.step[0], u.cols, u.rows))
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: ocl_convert_nv12_to_bgr failed");
|
||||
|
||||
status = clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImageUV, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
size_t offset = 0; // TODO
|
||||
size_t origin[3] = { 0, 0, 0 };
|
||||
size_t region[3] = { (size_t)u.cols, (size_t)u.rows, 1 };
|
||||
|
||||
status = clEnqueueCopyImageToBuffer(q, clImage, clBuffer, origin, region, offset, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueCopyImageToBuffer failed");
|
||||
}
|
||||
|
||||
status = clEnqueueReleaseD3D11ObjectsNV(q, 1, &clImage, 0, NULL, NULL);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clEnqueueReleaseD3D11ObjectsNV failed");
|
||||
|
||||
status = clFinish(q); // TODO Use events
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clFinish failed");
|
||||
|
||||
status = clReleaseMemObject(clImage); // TODO RAII
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
|
||||
#ifdef HAVE_DIRECTX_NV12
|
||||
if(DXGI_FORMAT_NV12 == desc.Format)
|
||||
{
|
||||
status = clReleaseMemObject(clImageUV);
|
||||
if (status != CL_SUCCESS)
|
||||
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void convertToD3D11Texture2D(InputArray src, ID3D11Texture2D* pD3D11Texture2D)
|
||||
{
|
||||
CV_UNUSED(src); CV_UNUSED(pD3D11Texture2D);
|
||||
#if !defined(HAVE_DIRECTX)
|
||||
NO_DIRECTX_SUPPORT_ERROR;
|
||||
#elif !defined(HAVE_OPENCL)
|
||||
NO_OPENCL_SUPPORT_ERROR;
|
||||
#else
|
||||
|
||||
bool useCLNVEXT = __OpenCLinitializeD3D11();
|
||||
if(!useCLNVEXT){
|
||||
__convertToD3D11Texture2DKHR(src,pD3D11Texture2D);
|
||||
}
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
else
|
||||
{
|
||||
__convertToD3D11Texture2DNV(src,pD3D11Texture2D);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void convertFromD3D11Texture2D(ID3D11Texture2D* pD3D11Texture2D, OutputArray dst)
|
||||
{
|
||||
CV_UNUSED(pD3D11Texture2D); CV_UNUSED(dst);
|
||||
#if !defined(HAVE_DIRECTX)
|
||||
NO_DIRECTX_SUPPORT_ERROR;
|
||||
#elif !defined(HAVE_OPENCL)
|
||||
NO_OPENCL_SUPPORT_ERROR;
|
||||
#else
|
||||
|
||||
bool useCLNVEXT = __OpenCLinitializeD3D11();
|
||||
if(!useCLNVEXT){
|
||||
__convertFromD3D11Texture2DKHR(pD3D11Texture2D,dst);
|
||||
}
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
else
|
||||
{
|
||||
__convertFromD3D11Texture2DNV(pD3D11Texture2D,dst);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
#include "opencv2/core/opencl/runtime/opencl_core.hpp"
|
||||
|
||||
#include <CL/cl_d3d11.h>
|
||||
#ifdef HAVE_OPENCL_D3D11_NV
|
||||
#include <CL/cl_d3d11_ext.h>
|
||||
#endif
|
||||
#include <CL/cl_d3d10.h>
|
||||
#include <CL/cl_dx9_media_sharing.h>
|
||||
#endif // HAVE_OPENCL
|
||||
|
||||
+114
-101
@@ -248,9 +248,6 @@ private:
|
||||
// Holds the data dimension.
|
||||
int n;
|
||||
|
||||
// Stores real/imag part of a complex division.
|
||||
double cdivr, cdivi;
|
||||
|
||||
// Pointer to internal memory.
|
||||
double *d, *e, *ort;
|
||||
double **V, **H;
|
||||
@@ -297,8 +294,9 @@ private:
|
||||
return arr;
|
||||
}
|
||||
|
||||
void cdiv(double xr, double xi, double yr, double yi) {
|
||||
static void complex_div(double xr, double xi, double yr, double yi, double& cdivr, double& cdivi) {
|
||||
double r, dv;
|
||||
CV_DbgAssert(std::abs(yr) + std::abs(yi) > 0.0);
|
||||
if (std::abs(yr) > std::abs(yi)) {
|
||||
r = yi / yr;
|
||||
dv = yr + r * yi;
|
||||
@@ -322,24 +320,27 @@ private:
|
||||
// Fortran subroutine in EISPACK.
|
||||
|
||||
// Initialize
|
||||
int nn = this->n;
|
||||
const int max_iters_count = 1000 * this->n;
|
||||
|
||||
const int nn = this->n; CV_Assert(nn > 0);
|
||||
int n1 = nn - 1;
|
||||
int low = 0;
|
||||
int high = nn - 1;
|
||||
double eps = std::pow(2.0, -52.0);
|
||||
const int low = 0;
|
||||
const int high = nn - 1;
|
||||
const double eps = std::numeric_limits<double>::epsilon();
|
||||
double exshift = 0.0;
|
||||
double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y;
|
||||
|
||||
// Store roots isolated by balanc and compute matrix norm
|
||||
|
||||
double norm = 0.0;
|
||||
for (int i = 0; i < nn; i++) {
|
||||
#if 0 // 'if' condition is always false
|
||||
if (i < low || i > high) {
|
||||
d[i] = H[i][i];
|
||||
e[i] = 0.0;
|
||||
}
|
||||
#endif
|
||||
for (int j = std::max(i - 1, 0); j < nn; j++) {
|
||||
norm = norm + std::abs(H[i][j]);
|
||||
norm += std::abs(H[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +354,7 @@ private:
|
||||
if (norm < FLT_EPSILON) {
|
||||
break;
|
||||
}
|
||||
s = std::abs(H[l - 1][l - 1]) + std::abs(H[l][l]);
|
||||
double s = std::abs(H[l - 1][l - 1]) + std::abs(H[l][l]);
|
||||
if (s == 0.0) {
|
||||
s = norm;
|
||||
}
|
||||
@@ -364,29 +365,26 @@ private:
|
||||
}
|
||||
|
||||
// Check for convergence
|
||||
// One root found
|
||||
|
||||
if (l == n1) {
|
||||
// One root found
|
||||
H[n1][n1] = H[n1][n1] + exshift;
|
||||
d[n1] = H[n1][n1];
|
||||
e[n1] = 0.0;
|
||||
n1--;
|
||||
iter = 0;
|
||||
|
||||
// Two roots found
|
||||
|
||||
} else if (l == n1 - 1) {
|
||||
w = H[n1][n1 - 1] * H[n1 - 1][n1];
|
||||
p = (H[n1 - 1][n1 - 1] - H[n1][n1]) / 2.0;
|
||||
q = p * p + w;
|
||||
z = std::sqrt(std::abs(q));
|
||||
// Two roots found
|
||||
double w = H[n1][n1 - 1] * H[n1 - 1][n1];
|
||||
double p = (H[n1 - 1][n1 - 1] - H[n1][n1]) * 0.5;
|
||||
double q = p * p + w;
|
||||
double z = std::sqrt(std::abs(q));
|
||||
H[n1][n1] = H[n1][n1] + exshift;
|
||||
H[n1 - 1][n1 - 1] = H[n1 - 1][n1 - 1] + exshift;
|
||||
x = H[n1][n1];
|
||||
|
||||
// Real pair
|
||||
double x = H[n1][n1];
|
||||
|
||||
if (q >= 0) {
|
||||
// Real pair
|
||||
if (p >= 0) {
|
||||
z = p + z;
|
||||
} else {
|
||||
@@ -400,10 +398,10 @@ private:
|
||||
e[n1 - 1] = 0.0;
|
||||
e[n1] = 0.0;
|
||||
x = H[n1][n1 - 1];
|
||||
s = std::abs(x) + std::abs(z);
|
||||
double s = std::abs(x) + std::abs(z);
|
||||
p = x / s;
|
||||
q = z / s;
|
||||
r = std::sqrt(p * p + q * q);
|
||||
double r = std::sqrt(p * p + q * q);
|
||||
p = p / r;
|
||||
q = q / r;
|
||||
|
||||
@@ -431,9 +429,8 @@ private:
|
||||
V[i][n1] = q * V[i][n1] - p * z;
|
||||
}
|
||||
|
||||
// Complex pair
|
||||
|
||||
} else {
|
||||
// Complex pair
|
||||
d[n1 - 1] = x + p;
|
||||
d[n1] = x + p;
|
||||
e[n1 - 1] = z;
|
||||
@@ -442,28 +439,25 @@ private:
|
||||
n1 = n1 - 2;
|
||||
iter = 0;
|
||||
|
||||
} else {
|
||||
// No convergence yet
|
||||
|
||||
} else {
|
||||
|
||||
// Form shift
|
||||
|
||||
x = H[n1][n1];
|
||||
y = 0.0;
|
||||
w = 0.0;
|
||||
double x = H[n1][n1];
|
||||
double y = 0.0;
|
||||
double w = 0.0;
|
||||
if (l < n1) {
|
||||
y = H[n1 - 1][n1 - 1];
|
||||
w = H[n1][n1 - 1] * H[n1 - 1][n1];
|
||||
}
|
||||
|
||||
// Wilkinson's original ad hoc shift
|
||||
|
||||
if (iter == 10) {
|
||||
exshift += x;
|
||||
for (int i = low; i <= n1; i++) {
|
||||
H[i][i] -= x;
|
||||
}
|
||||
s = std::abs(H[n1][n1 - 1]) + std::abs(H[n1 - 1][n1 - 2]);
|
||||
double s = std::abs(H[n1][n1 - 1]) + std::abs(H[n1 - 1][n1 - 2]);
|
||||
x = y = 0.75 * s;
|
||||
w = -0.4375 * s * s;
|
||||
}
|
||||
@@ -471,14 +465,14 @@ private:
|
||||
// MATLAB's new ad hoc shift
|
||||
|
||||
if (iter == 30) {
|
||||
s = (y - x) / 2.0;
|
||||
double s = (y - x) * 0.5;
|
||||
s = s * s + w;
|
||||
if (s > 0) {
|
||||
s = std::sqrt(s);
|
||||
if (y < x) {
|
||||
s = -s;
|
||||
}
|
||||
s = x - w / ((y - x) / 2.0 + s);
|
||||
s = x - w / ((y - x) * 0.5 + s);
|
||||
for (int i = low; i <= n1; i++) {
|
||||
H[i][i] -= s;
|
||||
}
|
||||
@@ -487,14 +481,20 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
iter = iter + 1; // (Could check iteration count here.)
|
||||
iter = iter + 1;
|
||||
if (iter > max_iters_count)
|
||||
CV_Error(Error::StsNoConv, "Algorithm doesn't converge (complex eigen values?)");
|
||||
|
||||
double p = std::numeric_limits<double>::quiet_NaN();
|
||||
double q = std::numeric_limits<double>::quiet_NaN();
|
||||
double r = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
// Look for two consecutive small sub-diagonal elements
|
||||
int m = n1 - 2;
|
||||
while (m >= l) {
|
||||
z = H[m][m];
|
||||
double z = H[m][m];
|
||||
r = x - z;
|
||||
s = y - z;
|
||||
double s = y - z;
|
||||
p = (r * s - w) / H[m + 1][m] + H[m][m + 1];
|
||||
q = H[m + 1][m + 1] - z - r - s;
|
||||
r = H[m + 2][m + 1];
|
||||
@@ -523,6 +523,7 @@ private:
|
||||
// Double QR step involving rows l:n and columns m:n
|
||||
|
||||
for (int k = m; k < n1; k++) {
|
||||
|
||||
bool notlast = (k != n1 - 1);
|
||||
if (k != m) {
|
||||
p = H[k][k - 1];
|
||||
@@ -538,7 +539,7 @@ private:
|
||||
if (x == 0.0) {
|
||||
break;
|
||||
}
|
||||
s = std::sqrt(p * p + q * q + r * r);
|
||||
double s = std::sqrt(p * p + q * q + r * r);
|
||||
if (p < 0) {
|
||||
s = -s;
|
||||
}
|
||||
@@ -551,7 +552,7 @@ private:
|
||||
p = p + s;
|
||||
x = p / s;
|
||||
y = q / s;
|
||||
z = r / s;
|
||||
double z = r / s;
|
||||
q = q / p;
|
||||
r = r / p;
|
||||
|
||||
@@ -563,8 +564,8 @@ private:
|
||||
p = p + r * H[k + 2][j];
|
||||
H[k + 2][j] = H[k + 2][j] - p * z;
|
||||
}
|
||||
H[k][j] = H[k][j] - p * x;
|
||||
H[k + 1][j] = H[k + 1][j] - p * y;
|
||||
H[k][j] -= p * x;
|
||||
H[k + 1][j] -= p * y;
|
||||
}
|
||||
|
||||
// Column modification
|
||||
@@ -575,8 +576,8 @@ private:
|
||||
p = p + z * H[i][k + 2];
|
||||
H[i][k + 2] = H[i][k + 2] - p * r;
|
||||
}
|
||||
H[i][k] = H[i][k] - p;
|
||||
H[i][k + 1] = H[i][k + 1] - p * q;
|
||||
H[i][k] -= p;
|
||||
H[i][k + 1] -= p * q;
|
||||
}
|
||||
|
||||
// Accumulate transformations
|
||||
@@ -602,17 +603,19 @@ private:
|
||||
}
|
||||
|
||||
for (n1 = nn - 1; n1 >= 0; n1--) {
|
||||
p = d[n1];
|
||||
q = e[n1];
|
||||
|
||||
// Real vector
|
||||
double p = d[n1];
|
||||
double q = e[n1];
|
||||
|
||||
if (q == 0) {
|
||||
// Real vector
|
||||
double z = std::numeric_limits<double>::quiet_NaN();
|
||||
double s = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
int l = n1;
|
||||
H[n1][n1] = 1.0;
|
||||
for (int i = n1 - 1; i >= 0; i--) {
|
||||
w = H[i][i] - p;
|
||||
r = 0.0;
|
||||
double w = H[i][i] - p;
|
||||
double r = 0.0;
|
||||
for (int j = l; j <= n1; j++) {
|
||||
r = r + H[i][j] * H[j][n1];
|
||||
}
|
||||
@@ -627,34 +630,38 @@ private:
|
||||
} else {
|
||||
H[i][n1] = -r / (eps * norm);
|
||||
}
|
||||
|
||||
// Solve real equations
|
||||
|
||||
} else {
|
||||
x = H[i][i + 1];
|
||||
y = H[i + 1][i];
|
||||
// Solve real equations
|
||||
CV_DbgAssert(!cvIsNaN(z));
|
||||
double x = H[i][i + 1];
|
||||
double y = H[i + 1][i];
|
||||
q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
|
||||
t = (x * s - z * r) / q;
|
||||
double t = (x * s - z * r) / q;
|
||||
H[i][n1] = t;
|
||||
if (std::abs(x) > std::abs(z)) {
|
||||
H[i + 1][n1] = (-r - w * t) / x;
|
||||
} else {
|
||||
CV_DbgAssert(z != 0.0);
|
||||
H[i + 1][n1] = (-s - y * t) / z;
|
||||
}
|
||||
}
|
||||
|
||||
// Overflow control
|
||||
|
||||
t = std::abs(H[i][n1]);
|
||||
double t = std::abs(H[i][n1]);
|
||||
if ((eps * t) * t > 1) {
|
||||
double inv_t = 1.0 / t;
|
||||
for (int j = i; j <= n1; j++) {
|
||||
H[j][n1] = H[j][n1] / t;
|
||||
H[j][n1] *= inv_t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Complex vector
|
||||
} else if (q < 0) {
|
||||
// Complex vector
|
||||
double z = std::numeric_limits<double>::quiet_NaN();
|
||||
double r = std::numeric_limits<double>::quiet_NaN();
|
||||
double s = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
int l = n1 - 1;
|
||||
|
||||
// Last vector component imaginary so matrix is triangular
|
||||
@@ -663,9 +670,11 @@ private:
|
||||
H[n1 - 1][n1 - 1] = q / H[n1][n1 - 1];
|
||||
H[n1 - 1][n1] = -(H[n1][n1] - p) / H[n1][n1 - 1];
|
||||
} else {
|
||||
cdiv(0.0, -H[n1 - 1][n1], H[n1 - 1][n1 - 1] - p, q);
|
||||
H[n1 - 1][n1 - 1] = cdivr;
|
||||
H[n1 - 1][n1] = cdivi;
|
||||
complex_div(
|
||||
0.0, -H[n1 - 1][n1],
|
||||
H[n1 - 1][n1 - 1] - p, q,
|
||||
H[n1 - 1][n1 - 1], H[n1 - 1][n1]
|
||||
);
|
||||
}
|
||||
H[n1][n1 - 1] = 0.0;
|
||||
H[n1][n1] = 1.0;
|
||||
@@ -677,7 +686,7 @@ private:
|
||||
ra = ra + H[i][j] * H[j][n1 - 1];
|
||||
sa = sa + H[i][j] * H[j][n1];
|
||||
}
|
||||
w = H[i][i] - p;
|
||||
double w = H[i][i] - p;
|
||||
|
||||
if (e[i] < 0.0) {
|
||||
z = w;
|
||||
@@ -686,41 +695,42 @@ private:
|
||||
} else {
|
||||
l = i;
|
||||
if (e[i] == 0) {
|
||||
cdiv(-ra, -sa, w, q);
|
||||
H[i][n1 - 1] = cdivr;
|
||||
H[i][n1] = cdivi;
|
||||
complex_div(
|
||||
-ra, -sa,
|
||||
w, q,
|
||||
H[i][n1 - 1], H[i][n1]
|
||||
);
|
||||
} else {
|
||||
|
||||
// Solve complex equations
|
||||
|
||||
x = H[i][i + 1];
|
||||
y = H[i + 1][i];
|
||||
double x = H[i][i + 1];
|
||||
double y = H[i + 1][i];
|
||||
vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
|
||||
vi = (d[i] - p) * 2.0 * q;
|
||||
if (vr == 0.0 && vi == 0.0) {
|
||||
vr = eps * norm * (std::abs(w) + std::abs(q) + std::abs(x)
|
||||
+ std::abs(y) + std::abs(z));
|
||||
}
|
||||
cdiv(x * r - z * ra + q * sa,
|
||||
x * s - z * sa - q * ra, vr, vi);
|
||||
H[i][n1 - 1] = cdivr;
|
||||
H[i][n1] = cdivi;
|
||||
complex_div(
|
||||
x * r - z * ra + q * sa, x * s - z * sa - q * ra,
|
||||
vr, vi,
|
||||
H[i][n1 - 1], H[i][n1]);
|
||||
if (std::abs(x) > (std::abs(z) + std::abs(q))) {
|
||||
H[i + 1][n1 - 1] = (-ra - w * H[i][n1 - 1] + q
|
||||
* H[i][n1]) / x;
|
||||
H[i + 1][n1] = (-sa - w * H[i][n1] - q * H[i][n1
|
||||
- 1]) / x;
|
||||
} else {
|
||||
cdiv(-r - y * H[i][n1 - 1], -s - y * H[i][n1], z,
|
||||
q);
|
||||
H[i + 1][n1 - 1] = cdivr;
|
||||
H[i + 1][n1] = cdivi;
|
||||
complex_div(
|
||||
-r - y * H[i][n1 - 1], -s - y * H[i][n1],
|
||||
z, q,
|
||||
H[i + 1][n1 - 1], H[i + 1][n1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Overflow control
|
||||
|
||||
t = std::max(std::abs(H[i][n1 - 1]), std::abs(H[i][n1]));
|
||||
double t = std::max(std::abs(H[i][n1 - 1]), std::abs(H[i][n1]));
|
||||
if ((eps * t) * t > 1) {
|
||||
for (int j = i; j <= n1; j++) {
|
||||
H[j][n1 - 1] = H[j][n1 - 1] / t;
|
||||
@@ -734,6 +744,7 @@ private:
|
||||
|
||||
// Vectors of isolated roots
|
||||
|
||||
#if 0 // 'if' condition is always false
|
||||
for (int i = 0; i < nn; i++) {
|
||||
if (i < low || i > high) {
|
||||
for (int j = i; j < nn; j++) {
|
||||
@@ -741,14 +752,15 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Back transformation to get eigenvectors of original matrix
|
||||
|
||||
for (int j = nn - 1; j >= low; j--) {
|
||||
for (int i = low; i <= high; i++) {
|
||||
z = 0.0;
|
||||
double z = 0.0;
|
||||
for (int k = low; k <= std::min(j, high); k++) {
|
||||
z = z + V[i][k] * H[k][j];
|
||||
z += V[i][k] * H[k][j];
|
||||
}
|
||||
V[i][j] = z;
|
||||
}
|
||||
@@ -848,15 +860,15 @@ private:
|
||||
// Releases all internal working memory.
|
||||
void release() {
|
||||
// releases the working data
|
||||
delete[] d;
|
||||
delete[] e;
|
||||
delete[] ort;
|
||||
delete[] d; d = NULL;
|
||||
delete[] e; e = NULL;
|
||||
delete[] ort; ort = NULL;
|
||||
for (int i = 0; i < n; i++) {
|
||||
delete[] H[i];
|
||||
delete[] V[i];
|
||||
if (H) delete[] H[i];
|
||||
if (V) delete[] V[i];
|
||||
}
|
||||
delete[] H;
|
||||
delete[] V;
|
||||
delete[] H; H = NULL;
|
||||
delete[] V; V = NULL;
|
||||
}
|
||||
|
||||
// Computes the Eigenvalue Decomposition for a matrix given in H.
|
||||
@@ -866,7 +878,7 @@ private:
|
||||
d = alloc_1d<double> (n);
|
||||
e = alloc_1d<double> (n);
|
||||
ort = alloc_1d<double> (n);
|
||||
try {
|
||||
{
|
||||
// Reduce to Hessenberg form.
|
||||
orthes();
|
||||
// Reduce Hessenberg to real Schur form.
|
||||
@@ -884,11 +896,6 @@ private:
|
||||
// Deallocate the memory by releasing all internal working data.
|
||||
release();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
release();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -896,15 +903,19 @@ public:
|
||||
// given in src. This function is a port of the EigenvalueSolver in JAMA,
|
||||
// which has been released to public domain by The MathWorks and the
|
||||
// National Institute of Standards and Technology (NIST).
|
||||
EigenvalueDecomposition(InputArray src, bool fallbackSymmetric = true) {
|
||||
compute(src, fallbackSymmetric);
|
||||
EigenvalueDecomposition() :
|
||||
n(0),
|
||||
d(NULL), e(NULL), ort(NULL),
|
||||
V(NULL), H(NULL)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
// This function computes the Eigenvalue Decomposition for a general matrix
|
||||
// given in src. This function is a port of the EigenvalueSolver in JAMA,
|
||||
// which has been released to public domain by The MathWorks and the
|
||||
// National Institute of Standards and Technology (NIST).
|
||||
void compute(InputArray src, bool fallbackSymmetric)
|
||||
void compute(InputArray src, bool fallbackSymmetric = true)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
@@ -934,7 +945,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
~EigenvalueDecomposition() {}
|
||||
~EigenvalueDecomposition() { release(); }
|
||||
|
||||
// Returns the eigenvalues of the Eigenvalue Decomposition.
|
||||
Mat eigenvalues() const { return _eigenvalues; }
|
||||
@@ -959,7 +970,8 @@ void eigenNonSymmetric(InputArray _src, OutputArray _evals, OutputArray _evects)
|
||||
else
|
||||
src64f = src;
|
||||
|
||||
EigenvalueDecomposition eigensystem(src64f, false);
|
||||
EigenvalueDecomposition eigensystem;
|
||||
eigensystem.compute(src64f, false);
|
||||
|
||||
// EigenvalueDecomposition returns transposed and non-sorted eigenvalues
|
||||
std::vector<double> eigenvalues64f;
|
||||
@@ -1135,7 +1147,8 @@ void LDA::lda(InputArrayOfArrays _src, InputArray _lbls) {
|
||||
// M = inv(Sw)*Sb
|
||||
Mat M;
|
||||
gemm(Swi, Sb, 1.0, Mat(), 0.0, M);
|
||||
EigenvalueDecomposition es(M);
|
||||
EigenvalueDecomposition es;
|
||||
es.compute(M);
|
||||
_eigenvalues = es.eigenvalues();
|
||||
_eigenvectors = es.eigenvectors();
|
||||
// reshape eigenvalues, so they are stored by column
|
||||
|
||||
+164
-180
@@ -1451,115 +1451,82 @@ transform_( const T* src, T* dst, const WT* m, int len, int scn, int dcn )
|
||||
}
|
||||
}
|
||||
|
||||
#if CV_SIMD128 && !defined(__aarch64__)
|
||||
static inline void
|
||||
load3x3Matrix(const float* m, v_float32x4& m0, v_float32x4& m1, v_float32x4& m2, v_float32x4& m3)
|
||||
{
|
||||
m0 = v_float32x4(m[0], m[4], m[8], 0);
|
||||
m1 = v_float32x4(m[1], m[5], m[9], 0);
|
||||
m2 = v_float32x4(m[2], m[6], m[10], 0);
|
||||
m3 = v_float32x4(m[3], m[7], m[11], 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CV_SIMD128
|
||||
static inline v_int16x8
|
||||
v_matmulvec(const v_int16x8 &v0, const v_int16x8 &m0, const v_int16x8 &m1, const v_int16x8 &m2, const v_int32x4 &m3, const int BITS)
|
||||
{
|
||||
// v0 : 0 b0 g0 r0 b1 g1 r1 ?
|
||||
v_int32x4 t0 = v_dotprod(v0, m0); // a0 b0 a1 b1
|
||||
v_int32x4 t1 = v_dotprod(v0, m1); // c0 d0 c1 d1
|
||||
v_int32x4 t2 = v_dotprod(v0, m2); // e0 f0 e1 f1
|
||||
v_int32x4 t3 = v_setzero_s32();
|
||||
v_int32x4 s0, s1, s2, s3;
|
||||
v_transpose4x4(t0, t1, t2, t3, s0, s1, s2, s3);
|
||||
s0 = s0 + s1 + m3; // B0 G0 R0 ?
|
||||
s2 = s2 + s3 + m3; // B1 G1 R1 ?
|
||||
|
||||
s0 = s0 >> BITS;
|
||||
s2 = s2 >> BITS;
|
||||
|
||||
v_int16x8 result = v_pack(s0, v_setzero_s32()); // B0 G0 R0 0 0 0 0 0
|
||||
result = v_reinterpret_as_s16(v_reinterpret_as_s64(result) << 16); // 0 B0 G0 R0 0 0 0 0
|
||||
result = result | v_pack(v_setzero_s32(), s2); // 0 B0 G0 R0 B1 G1 R1 0
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
transform_8u( const uchar* src, uchar* dst, const float* m, int len, int scn, int dcn )
|
||||
{
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD
|
||||
const int BITS = 10, SCALE = 1 << BITS;
|
||||
const float MAX_M = (float)(1 << (15 - BITS));
|
||||
|
||||
if( hasSIMD128() && scn == 3 && dcn == 3 &&
|
||||
std::abs(m[0]) < MAX_M && std::abs(m[1]) < MAX_M && std::abs(m[2]) < MAX_M && std::abs(m[3]) < MAX_M*256 &&
|
||||
std::abs(m[4]) < MAX_M && std::abs(m[5]) < MAX_M && std::abs(m[6]) < MAX_M && std::abs(m[7]) < MAX_M*256 &&
|
||||
std::abs(m[8]) < MAX_M && std::abs(m[9]) < MAX_M && std::abs(m[10]) < MAX_M && std::abs(m[11]) < MAX_M*256 )
|
||||
if( scn == 3 && dcn == 3 &&
|
||||
std::abs(m[0]) < MAX_M && std::abs(m[1]) < MAX_M && std::abs(m[ 2]) < MAX_M*256 && std::abs(m[ 3]) < MAX_M*256 &&
|
||||
std::abs(m[4]) < MAX_M && std::abs(m[5]) < MAX_M && std::abs(m[ 6]) < MAX_M*256 && std::abs(m[ 7]) < MAX_M*256 &&
|
||||
std::abs(m[8]) < MAX_M && std::abs(m[9]) < MAX_M && std::abs(m[10]) < MAX_M*256 && std::abs(m[11]) < MAX_M*256 )
|
||||
{
|
||||
const int nChannels = 3;
|
||||
const int cWidth = v_int16x8::nlanes;
|
||||
// faster fixed-point transformation
|
||||
short m00 = saturate_cast<short>(m[0]*SCALE), m01 = saturate_cast<short>(m[1]*SCALE),
|
||||
m02 = saturate_cast<short>(m[2]*SCALE), m10 = saturate_cast<short>(m[4]*SCALE),
|
||||
m11 = saturate_cast<short>(m[5]*SCALE), m12 = saturate_cast<short>(m[6]*SCALE),
|
||||
m20 = saturate_cast<short>(m[8]*SCALE), m21 = saturate_cast<short>(m[9]*SCALE),
|
||||
m22 = saturate_cast<short>(m[10]*SCALE);
|
||||
int m03 = saturate_cast<int>((m[3]+0.5f)*SCALE), m13 = saturate_cast<int>((m[7]+0.5f)*SCALE ),
|
||||
m23 = saturate_cast<int>((m[11]+0.5f)*SCALE);
|
||||
|
||||
v_int16x8 m0 = v_int16x8(0, m00, m01, m02, m00, m01, m02, 0);
|
||||
v_int16x8 m1 = v_int16x8(0, m10, m11, m12, m10, m11, m12, 0);
|
||||
v_int16x8 m2 = v_int16x8(0, m20, m21, m22, m20, m21, m22, 0);
|
||||
v_int32x4 m3 = v_int32x4(m03, m13, m23, 0);
|
||||
union {
|
||||
short s[6];
|
||||
int p[3];
|
||||
} m16;
|
||||
m16.s[0] = saturate_cast<short>(m[0] * SCALE); m16.s[1] = saturate_cast<short>(m[1] * SCALE);
|
||||
m16.s[2] = saturate_cast<short>(m[4] * SCALE); m16.s[3] = saturate_cast<short>(m[5] * SCALE);
|
||||
m16.s[4] = saturate_cast<short>(m[8] * SCALE); m16.s[5] = saturate_cast<short>(m[9] * SCALE);
|
||||
int m32[] = {saturate_cast<int>(m[ 2] * SCALE), saturate_cast<int>(m[ 3] * SCALE),
|
||||
saturate_cast<int>(m[ 6] * SCALE), saturate_cast<int>(m[ 7] * SCALE),
|
||||
saturate_cast<int>(m[10] * SCALE), saturate_cast<int>(m[11] * SCALE)};
|
||||
v_int16 m01 = v_reinterpret_as_s16(vx_setall_s32(m16.p[0]));
|
||||
v_int32 m2 = vx_setall_s32(m32[0]);
|
||||
v_int32 m3 = vx_setall_s32(m32[1]);
|
||||
v_int16 m45 = v_reinterpret_as_s16(vx_setall_s32(m16.p[1]));
|
||||
v_int32 m6 = vx_setall_s32(m32[2]);
|
||||
v_int32 m7 = vx_setall_s32(m32[3]);
|
||||
v_int16 m89 = v_reinterpret_as_s16(vx_setall_s32(m16.p[2]));
|
||||
v_int32 m10 = vx_setall_s32(m32[4]);
|
||||
v_int32 m11 = vx_setall_s32(m32[5]);
|
||||
int x = 0;
|
||||
|
||||
for (; x <= (len - cWidth) * nChannels; x += cWidth * nChannels)
|
||||
for (; x <= (len - v_uint8::nlanes) * nChannels; x += v_uint8::nlanes * nChannels)
|
||||
{
|
||||
// load 8 pixels
|
||||
v_int16x8 v0 = v_reinterpret_as_s16(v_load_expand(src + x));
|
||||
v_int16x8 v1 = v_reinterpret_as_s16(v_load_expand(src + x + cWidth));
|
||||
v_int16x8 v2 = v_reinterpret_as_s16(v_load_expand(src + x + cWidth * 2));
|
||||
v_int16x8 v3;
|
||||
v_uint8 b, g, r;
|
||||
v_load_deinterleave(src + x, b, g, r);
|
||||
v_uint8 bgl, bgh;
|
||||
v_zip(b, g, bgl, bgh);
|
||||
v_uint16 rl, rh;
|
||||
v_expand(r, rl, rh);
|
||||
|
||||
// rotate and pack
|
||||
v3 = v_rotate_right<1>(v2); // 0 b6 g6 r6 b7 g7 r7 0
|
||||
v2 = v_rotate_left <5>(v2, v1); // 0 b4 g4 r4 b5 g5 r5 0
|
||||
v1 = v_rotate_left <3>(v1, v0); // 0 b2 g2 r2 b3 g3 r3 0
|
||||
v0 = v_rotate_left <1>(v0); // 0 b0 g0 r0 b1 g1 r1 0
|
||||
|
||||
// multiply with matrix and normalize
|
||||
v0 = v_matmulvec(v0, m0, m1, m2, m3, BITS); // 0 B0 G0 R0 B1 G1 R1 0
|
||||
v1 = v_matmulvec(v1, m0, m1, m2, m3, BITS); // 0 B2 G2 R2 B3 G3 R3 0
|
||||
v2 = v_matmulvec(v2, m0, m1, m2, m3, BITS); // 0 B4 G4 R4 B5 G5 R5 0
|
||||
v3 = v_matmulvec(v3, m0, m1, m2, m3, BITS); // 0 B6 G6 R6 B7 G7 R7 0
|
||||
|
||||
// narrow down as uint8x16
|
||||
v_uint8x16 z0 = v_pack_u(v0, v_setzero_s16()); // 0 B0 G0 R0 B1 G1 R1 0 0 0 0 0 0 0 0 0
|
||||
v_uint8x16 z1 = v_pack_u(v1, v_setzero_s16()); // 0 B2 G2 R2 B3 G3 R3 0 0 0 0 0 0 0 0 0
|
||||
v_uint8x16 z2 = v_pack_u(v2, v_setzero_s16()); // 0 B4 G4 R4 B5 G5 R5 0 0 0 0 0 0 0 0 0
|
||||
v_uint8x16 z3 = v_pack_u(v3, v_setzero_s16()); // 0 B6 G6 R6 B7 G7 R7 0 0 0 0 0 0 0 0 0
|
||||
|
||||
// rotate and pack
|
||||
z0 = v_reinterpret_as_u8(v_reinterpret_as_u64(z0) >> 8) | v_reinterpret_as_u8(v_reinterpret_as_u64(z1) << 40); // B0 G0 R0 B1 G1 R1 B2 G2 0 0 0 0 0 0 0 0
|
||||
z1 = v_reinterpret_as_u8(v_reinterpret_as_u64(z1) >> 24) | v_reinterpret_as_u8(v_reinterpret_as_u64(z2) << 24); // R2 B3 G3 R3 B4 G4 R4 B5 0 0 0 0 0 0 0 0
|
||||
z2 = v_reinterpret_as_u8(v_reinterpret_as_u64(z2) >> 40) | v_reinterpret_as_u8(v_reinterpret_as_u64(z3) << 8); // G5 R6 B6 G6 R6 B7 G7 R7 0 0 0 0 0 0 0 0
|
||||
|
||||
// store on memory
|
||||
v_store_low(dst + x, z0);
|
||||
v_store_low(dst + x + cWidth, z1);
|
||||
v_store_low(dst + x + cWidth * 2, z2);
|
||||
v_int16 dbl, dbh, dgl, dgh, drl, drh;
|
||||
v_uint16 p0, p2;
|
||||
v_int32 p1, p3;
|
||||
v_expand(bgl, p0, p2);
|
||||
v_expand(v_reinterpret_as_s16(rl), p1, p3);
|
||||
dbl = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m01) + p1 * m2 + m3,
|
||||
v_dotprod(v_reinterpret_as_s16(p2), m01) + p3 * m2 + m3);
|
||||
dgl = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m45) + p1 * m6 + m7,
|
||||
v_dotprod(v_reinterpret_as_s16(p2), m45) + p3 * m6 + m7);
|
||||
drl = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m89) + p1 * m10 + m11,
|
||||
v_dotprod(v_reinterpret_as_s16(p2), m89) + p3 * m10 + m11);
|
||||
v_expand(bgh, p0, p2);
|
||||
v_expand(v_reinterpret_as_s16(rh), p1, p3);
|
||||
dbh = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m01) + p1 * m2 + m3,
|
||||
v_dotprod(v_reinterpret_as_s16(p2), m01) + p3 * m2 + m3);
|
||||
dgh = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m45) + p1 * m6 + m7,
|
||||
v_dotprod(v_reinterpret_as_s16(p2), m45) + p3 * m6 + m7);
|
||||
drh = v_rshr_pack<BITS>(v_dotprod(v_reinterpret_as_s16(p0), m89) + p1 * m10 + m11,
|
||||
v_dotprod(v_reinterpret_as_s16(p2), m89) + p3 * m10 + m11);
|
||||
v_store_interleave(dst + x, v_pack_u(dbl, dbh), v_pack_u(dgl, dgh), v_pack_u(drl, drh));
|
||||
}
|
||||
|
||||
m32[1] = saturate_cast<int>((m[3] + 0.5f)*SCALE);
|
||||
m32[3] = saturate_cast<int>((m[7] + 0.5f)*SCALE);
|
||||
m32[5] = saturate_cast<int>((m[11] + 0.5f)*SCALE);
|
||||
for( ; x < len * nChannels; x += nChannels )
|
||||
{
|
||||
int v0 = src[x], v1 = src[x+1], v2 = src[x+2];
|
||||
uchar t0 = saturate_cast<uchar>((m00*v0 + m01*v1 + m02*v2 + m03)>>BITS);
|
||||
uchar t1 = saturate_cast<uchar>((m10*v0 + m11*v1 + m12*v2 + m13)>>BITS);
|
||||
uchar t2 = saturate_cast<uchar>((m20*v0 + m21*v1 + m22*v2 + m23)>>BITS);
|
||||
uchar t0 = saturate_cast<uchar>((m16.s[0] * v0 + m16.s[1] * v1 + m32[0] * v2 + m32[1]) >> BITS);
|
||||
uchar t1 = saturate_cast<uchar>((m16.s[2] * v0 + m16.s[3] * v1 + m32[2] * v2 + m32[3]) >> BITS);
|
||||
uchar t2 = saturate_cast<uchar>((m16.s[4] * v0 + m16.s[5] * v1 + m32[4] * v2 + m32[5]) >> BITS);
|
||||
dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
|
||||
}
|
||||
vx_cleanup();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -1570,64 +1537,65 @@ transform_8u( const uchar* src, uchar* dst, const float* m, int len, int scn, in
|
||||
static void
|
||||
transform_16u( const ushort* src, ushort* dst, const float* m, int len, int scn, int dcn )
|
||||
{
|
||||
#if CV_SIMD128 && !defined(__aarch64__)
|
||||
if( hasSIMD128() && scn == 3 && dcn == 3 )
|
||||
#if CV_SIMD && !defined(__aarch64__)
|
||||
if( scn == 3 && dcn == 3 )
|
||||
{
|
||||
const int nChannels = 3;
|
||||
const int cWidth = v_float32x4::nlanes;
|
||||
v_int16x8 delta = v_int16x8(0, -32768, -32768, -32768, -32768, -32768, -32768, 0);
|
||||
v_float32x4 m0, m1, m2, m3;
|
||||
load3x3Matrix(m, m0, m1, m2, m3);
|
||||
m3 -= v_float32x4(32768.f, 32768.f, 32768.f, 0.f);
|
||||
|
||||
int x = 0;
|
||||
for( ; x <= (len - cWidth) * nChannels; x += cWidth * nChannels )
|
||||
#if CV_SIMD_WIDTH > 16
|
||||
v_float32 m0 = vx_setall_f32(m[ 0]);
|
||||
v_float32 m1 = vx_setall_f32(m[ 1]);
|
||||
v_float32 m2 = vx_setall_f32(m[ 2]);
|
||||
v_float32 m3 = vx_setall_f32(m[ 3] - 32768.f);
|
||||
v_float32 m4 = vx_setall_f32(m[ 4]);
|
||||
v_float32 m5 = vx_setall_f32(m[ 5]);
|
||||
v_float32 m6 = vx_setall_f32(m[ 6]);
|
||||
v_float32 m7 = vx_setall_f32(m[ 7] - 32768.f);
|
||||
v_float32 m8 = vx_setall_f32(m[ 8]);
|
||||
v_float32 m9 = vx_setall_f32(m[ 9]);
|
||||
v_float32 m10 = vx_setall_f32(m[10]);
|
||||
v_float32 m11 = vx_setall_f32(m[11] - 32768.f);
|
||||
v_int16 delta = vx_setall_s16(-32768);
|
||||
for (; x <= (len - v_uint16::nlanes)*3; x += v_uint16::nlanes*3)
|
||||
{
|
||||
// load 4 pixels
|
||||
v_uint16x8 v0_16 = v_load(src + x); // b0 g0 r0 b1 g1 r1 b2 g2
|
||||
v_uint16x8 v2_16 = v_load_low(src + x + cWidth * 2); // r2 b3 g3 r3 ? ? ? ?
|
||||
v_uint16 b, g, r;
|
||||
v_load_deinterleave(src + x, b, g, r);
|
||||
v_uint32 bl, bh, gl, gh, rl, rh;
|
||||
v_expand(b, bl, bh);
|
||||
v_expand(g, gl, gh);
|
||||
v_expand(r, rl, rh);
|
||||
|
||||
// expand to 4 vectors
|
||||
v_uint32x4 v0_32, v1_32, v2_32, v3_32, dummy_32;
|
||||
v_expand(v_rotate_right<3>(v0_16), v1_32, dummy_32); // b1 g1 r1
|
||||
v_expand(v_rotate_right<1>(v2_16), v3_32, dummy_32); // b3 g3 r3
|
||||
v_expand(v_rotate_right<6>(v0_16, v2_16), v2_32, dummy_32); // b2 g2 r2
|
||||
v_expand(v0_16, v0_32, dummy_32); // b0 g0 r0
|
||||
|
||||
// convert to float32x4
|
||||
v_float32x4 x0 = v_cvt_f32(v_reinterpret_as_s32(v0_32)); // b0 g0 r0
|
||||
v_float32x4 x1 = v_cvt_f32(v_reinterpret_as_s32(v1_32)); // b1 g1 r1
|
||||
v_float32x4 x2 = v_cvt_f32(v_reinterpret_as_s32(v2_32)); // b2 g2 r2
|
||||
v_float32x4 x3 = v_cvt_f32(v_reinterpret_as_s32(v3_32)); // b3 g3 r3
|
||||
|
||||
// multiply and convert back to int32x4
|
||||
v_int32x4 y0, y1, y2, y3;
|
||||
y0 = v_round(v_matmuladd(x0, m0, m1, m2, m3)); // B0 G0 R0
|
||||
y1 = v_round(v_matmuladd(x1, m0, m1, m2, m3)); // B1 G1 R1
|
||||
y2 = v_round(v_matmuladd(x2, m0, m1, m2, m3)); // B2 G2 R2
|
||||
y3 = v_round(v_matmuladd(x3, m0, m1, m2, m3)); // B3 G3 R3
|
||||
|
||||
// narrow down to int16x8
|
||||
v_int16x8 v0 = v_add_wrap(v_pack(v_rotate_left<1>(y0), y1), delta); // 0 B0 G0 R0 B1 G1 R1 0
|
||||
v_int16x8 v2 = v_add_wrap(v_pack(v_rotate_left<1>(y2), y3), delta); // 0 B2 G2 R2 B3 G3 R3 0
|
||||
|
||||
// rotate and pack
|
||||
v0 = v_rotate_right<1>(v0) | v_rotate_left<5>(v2); // B0 G0 R0 B1 G1 R1 B2 G2
|
||||
v2 = v_rotate_right<3>(v2); // R2 B3 G3 R3 0 0 0 0
|
||||
|
||||
// store 4 pixels
|
||||
v_store(dst + x, v_reinterpret_as_u16(v0));
|
||||
v_store_low(dst + x + cWidth * 2, v_reinterpret_as_u16(v2));
|
||||
v_int16 db, dg, dr;
|
||||
db = v_add_wrap(v_pack(v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bl)), m0, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gl)), m1, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rl)), m2, m3)))),
|
||||
v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bh)), m0, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gh)), m1, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rh)), m2, m3))))), delta);
|
||||
dg = v_add_wrap(v_pack(v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bl)), m4, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gl)), m5, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rl)), m6, m7)))),
|
||||
v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bh)), m4, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gh)), m5, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rh)), m6, m7))))), delta);
|
||||
dr = v_add_wrap(v_pack(v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bl)), m8, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gl)), m9, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rl)), m10, m11)))),
|
||||
v_round(v_muladd(v_cvt_f32(v_reinterpret_as_s32(bh)), m8, v_muladd(v_cvt_f32(v_reinterpret_as_s32(gh)), m9, v_muladd(v_cvt_f32(v_reinterpret_as_s32(rh)), m10, m11))))), delta);
|
||||
v_store_interleave(dst + x, v_reinterpret_as_u16(db), v_reinterpret_as_u16(dg), v_reinterpret_as_u16(dr));
|
||||
}
|
||||
|
||||
for( ; x < len * nChannels; x += nChannels )
|
||||
#endif
|
||||
v_float32x4 _m0l(m[0], m[4], m[ 8], 0.f);
|
||||
v_float32x4 _m1l(m[1], m[5], m[ 9], 0.f);
|
||||
v_float32x4 _m2l(m[2], m[6], m[10], 0.f);
|
||||
v_float32x4 _m3l(m[3] - 32768.f, m[7] - 32768.f, m[11] - 32768.f, 0.f);
|
||||
v_float32x4 _m0h = v_rotate_left<1>(_m0l);
|
||||
v_float32x4 _m1h = v_rotate_left<1>(_m1l);
|
||||
v_float32x4 _m2h = v_rotate_left<1>(_m2l);
|
||||
v_float32x4 _m3h = v_rotate_left<1>(_m3l);
|
||||
v_int16x8 _delta(0, -32768, -32768, -32768, -32768, -32768, -32768, 0);
|
||||
for( ; x <= len*3 - v_uint16x8::nlanes; x += 3*v_uint16x8::nlanes/4 )
|
||||
v_store(dst + x, v_rotate_right<1>(v_reinterpret_as_u16(v_add_wrap(v_pack(
|
||||
v_round(v_matmuladd(v_cvt_f32(v_reinterpret_as_s32(v_load_expand(src + x ))), _m0h, _m1h, _m2h, _m3h)),
|
||||
v_round(v_matmuladd(v_cvt_f32(v_reinterpret_as_s32(v_load_expand(src + x + 3))), _m0l, _m1l, _m2l, _m3l))), _delta))));
|
||||
for( ; x < len * 3; x += 3 )
|
||||
{
|
||||
float v0 = src[x], v1 = src[x + 1], v2 = src[x + 2];
|
||||
ushort t0 = saturate_cast<ushort>(m[0] * v0 + m[1] * v1 + m[2] * v2 + m[3]);
|
||||
ushort t1 = saturate_cast<ushort>(m[4] * v0 + m[5] * v1 + m[6] * v2 + m[7]);
|
||||
ushort t0 = saturate_cast<ushort>(m[0] * v0 + m[1] * v1 + m[ 2] * v2 + m[ 3]);
|
||||
ushort t1 = saturate_cast<ushort>(m[4] * v0 + m[5] * v1 + m[ 6] * v2 + m[ 7]);
|
||||
ushort t2 = saturate_cast<ushort>(m[8] * v0 + m[9] * v1 + m[10] * v2 + m[11]);
|
||||
dst[x] = t0; dst[x + 1] = t1; dst[x + 2] = t2;
|
||||
}
|
||||
vx_cleanup();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -1638,52 +1606,68 @@ transform_16u( const ushort* src, ushort* dst, const float* m, int len, int scn,
|
||||
static void
|
||||
transform_32f( const float* src, float* dst, const float* m, int len, int scn, int dcn )
|
||||
{
|
||||
#if CV_SIMD128 && !defined(__aarch64__)
|
||||
if( hasSIMD128() )
|
||||
#if CV_SIMD && !defined(__aarch64__)
|
||||
int x = 0;
|
||||
if( scn == 3 && dcn == 3 )
|
||||
{
|
||||
int x = 0;
|
||||
if( scn == 3 && dcn == 3 )
|
||||
int idx[v_float32::nlanes/2];
|
||||
for( int i = 0; i < v_float32::nlanes/4; i++ )
|
||||
{
|
||||
const int cWidth = 3;
|
||||
v_float32x4 m0, m1, m2, m3;
|
||||
load3x3Matrix(m, m0, m1, m2, m3);
|
||||
|
||||
for( ; x < (len - 1)*cWidth; x += cWidth )
|
||||
{
|
||||
v_float32x4 x0 = v_load(src + x);
|
||||
v_float32x4 y0 = v_matmuladd(x0, m0, m1, m2, m3);
|
||||
v_store_low(dst + x, y0);
|
||||
dst[x + 2] = v_combine_high(y0, y0).get0();
|
||||
}
|
||||
|
||||
for( ; x < len*cWidth; x += cWidth )
|
||||
{
|
||||
float v0 = src[x], v1 = src[x+1], v2 = src[x+2];
|
||||
float t0 = saturate_cast<float>(m[0]*v0 + m[1]*v1 + m[2]*v2 + m[3]);
|
||||
float t1 = saturate_cast<float>(m[4]*v0 + m[5]*v1 + m[6]*v2 + m[7]);
|
||||
float t2 = saturate_cast<float>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
|
||||
dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
|
||||
}
|
||||
return;
|
||||
idx[i] = 3*i;
|
||||
idx[i + v_float32::nlanes/4] = 0;
|
||||
}
|
||||
|
||||
if( scn == 4 && dcn == 4 )
|
||||
float _m[] = { m[0], m[4], m[ 8], 0.f,
|
||||
m[1], m[5], m[ 9], 0.f,
|
||||
m[2], m[6], m[10], 0.f,
|
||||
m[3], m[7], m[11], 0.f };
|
||||
v_float32 m0 = vx_lut_quads(_m , idx + v_float32::nlanes/4);
|
||||
v_float32 m1 = vx_lut_quads(_m + 4, idx + v_float32::nlanes/4);
|
||||
v_float32 m2 = vx_lut_quads(_m + 8, idx + v_float32::nlanes/4);
|
||||
v_float32 m3 = vx_lut_quads(_m + 12, idx + v_float32::nlanes/4);
|
||||
for( ; x <= len*3 - v_float32::nlanes; x += 3*v_float32::nlanes/4 )
|
||||
v_store(dst + x, v_pack_triplets(v_matmuladd(vx_lut_quads(src + x, idx), m0, m1, m2, m3)));
|
||||
for( ; x < len*3; x += 3 )
|
||||
{
|
||||
const int cWidth = 4;
|
||||
v_float32x4 m0 = v_float32x4(m[0], m[5], m[10], m[15]);
|
||||
v_float32x4 m1 = v_float32x4(m[1], m[6], m[11], m[16]);
|
||||
v_float32x4 m2 = v_float32x4(m[2], m[7], m[12], m[17]);
|
||||
v_float32x4 m3 = v_float32x4(m[3], m[8], m[13], m[18]);
|
||||
v_float32x4 m4 = v_float32x4(m[4], m[9], m[14], m[19]);
|
||||
|
||||
for( ; x < len*cWidth; x += cWidth )
|
||||
{
|
||||
v_float32x4 x0 = v_load(src + x);
|
||||
v_float32x4 y0 = v_matmul(x0, m0, m1, m2, m3) + m4;
|
||||
v_store(dst + x, y0);
|
||||
}
|
||||
return;
|
||||
float v0 = src[x], v1 = src[x+1], v2 = src[x+2];
|
||||
float t0 = saturate_cast<float>(m[0]*v0 + m[1]*v1 + m[ 2]*v2 + m[ 3]);
|
||||
float t1 = saturate_cast<float>(m[4]*v0 + m[5]*v1 + m[ 6]*v2 + m[ 7]);
|
||||
float t2 = saturate_cast<float>(m[8]*v0 + m[9]*v1 + m[10]*v2 + m[11]);
|
||||
dst[x] = t0; dst[x+1] = t1; dst[x+2] = t2;
|
||||
}
|
||||
vx_cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
if( scn == 4 && dcn == 4 )
|
||||
{
|
||||
#if CV_SIMD_WIDTH > 16
|
||||
int idx[v_float32::nlanes/4];
|
||||
for( int i = 0; i < v_float32::nlanes/4; i++ )
|
||||
idx[i] = 0;
|
||||
float _m[] = { m[4], m[9], m[14], m[19] };
|
||||
v_float32 m0 = vx_lut_quads(m , idx);
|
||||
v_float32 m1 = vx_lut_quads(m+ 5, idx);
|
||||
v_float32 m2 = vx_lut_quads(m+10, idx);
|
||||
v_float32 m3 = vx_lut_quads(m+15, idx);
|
||||
v_float32 m4 = vx_lut_quads(_m, idx);
|
||||
for( ; x <= len*4 - v_float32::nlanes; x += v_float32::nlanes )
|
||||
{
|
||||
v_float32 v_src = vx_load(src + x);
|
||||
v_store(dst + x, v_reduce_sum4(v_src * m0, v_src * m1, v_src * m2, v_src * m3) + m4);
|
||||
}
|
||||
#endif
|
||||
v_float32x4 _m0 = v_load(m );
|
||||
v_float32x4 _m1 = v_load(m + 5);
|
||||
v_float32x4 _m2 = v_load(m + 10);
|
||||
v_float32x4 _m3 = v_load(m + 15);
|
||||
v_float32x4 _m4(m[4], m[9], m[14], m[19]);
|
||||
for( ; x < len*4; x += v_float32x4::nlanes )
|
||||
{
|
||||
v_float32x4 v_src = v_load(src + x);
|
||||
v_store(dst + x, v_reduce_sum4(v_src * _m0, v_src * _m1, v_src * _m2, v_src * _m3) + _m4);
|
||||
}
|
||||
vx_cleanup();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
@CL_REMAP_ORIGIN@
|
||||
|
||||
#if defined __APPLE__
|
||||
#define CL_SILENCE_DEPRECATION
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
#if defined(HAVE_OPENCL_STATIC)
|
||||
#if defined __APPLE__
|
||||
#define CL_SILENCE_DEPRECATION
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
|
||||
@@ -94,7 +94,7 @@ void* allocSingletonBuffer(size_t size) { return fastMalloc(size); }
|
||||
#include <cstdlib> // std::abort
|
||||
#endif
|
||||
|
||||
#if defined __ANDROID__ || defined __linux__ || defined __FreeBSD__ || defined __HAIKU__ || defined __Fuchsia__
|
||||
#if defined __ANDROID__ || defined __linux__ || defined __FreeBSD__ || defined __OpenBSD__ || defined __HAIKU__ || defined __Fuchsia__
|
||||
# include <unistd.h>
|
||||
# include <fcntl.h>
|
||||
# include <elf.h>
|
||||
|
||||
@@ -495,7 +495,7 @@ cv::String getCacheDirectory(const char* sub_directory_name, const char* configu
|
||||
if (utils::fs::isDirectory(default_cache_path))
|
||||
{
|
||||
cv::String default_cache_path_base = utils::fs::join(default_cache_path, "opencv");
|
||||
default_cache_path = utils::fs::join(default_cache_path_base, "4.0" CV_VERSION_STATUS);
|
||||
default_cache_path = utils::fs::join(default_cache_path_base, CVAUX_STR(CV_VERSION_MAJOR) "." CVAUX_STR(CV_VERSION_MINOR) CV_VERSION_STATUS);
|
||||
if (utils::getConfigurationParameterBool("OPENCV_CACHE_SHOW_CLEANUP_MESSAGE", true)
|
||||
&& !utils::fs::isDirectory(default_cache_path))
|
||||
{
|
||||
|
||||
@@ -519,4 +519,27 @@ TEST_P(Core_EigenZero, double)
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Core_EigenZero, testing::Values(2, 3, 5));
|
||||
|
||||
TEST(Core_EigenNonSymmetric, convergence)
|
||||
{
|
||||
Matx33d m(
|
||||
0, -1, 0,
|
||||
1, 0, 1,
|
||||
0, -1, 0);
|
||||
Mat eigenvalues, eigenvectors;
|
||||
// eigen values are complex, algorithm doesn't converge
|
||||
try
|
||||
{
|
||||
cv::eigenNonSymmetric(m, eigenvalues, eigenvectors);
|
||||
std::cout << Mat(eigenvalues.t()) << std::endl;
|
||||
}
|
||||
catch (const cv::Exception& e)
|
||||
{
|
||||
EXPECT_EQ(Error::StsNoConv, e.code) << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FAIL() << "Unknown exception has been raised";
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -1020,7 +1020,7 @@ static void cvTsPerspectiveTransform( const CvArr* _src, CvArr* _dst, const CvMa
|
||||
int i, j, cols;
|
||||
int cn, depth, mat_depth;
|
||||
CvMat astub, bstub, *a, *b;
|
||||
double mat[16];
|
||||
double mat[16] = {0.0};
|
||||
|
||||
a = cvGetMat( _src, &astub, 0, 0 );
|
||||
b = cvGetMat( _dst, &bstub, 0, 0 );
|
||||
|
||||
@@ -89,7 +89,15 @@ ocv_glob_module_sources(${sources_options} SOURCES ${fw_srcs})
|
||||
ocv_create_module(${libs} ${INF_ENGINE_TARGET})
|
||||
ocv_add_samples()
|
||||
ocv_add_accuracy_tests(${INF_ENGINE_TARGET})
|
||||
ocv_add_perf_tests(${INF_ENGINE_TARGET})
|
||||
|
||||
set(perf_path "${CMAKE_CURRENT_LIST_DIR}/perf")
|
||||
file(GLOB_RECURSE perf_srcs "${perf_path}/*.cpp")
|
||||
file(GLOB_RECURSE perf_hdrs "${perf_path}/*.hpp" "${perf_path}/*.h")
|
||||
ocv_add_perf_tests(${INF_ENGINE_TARGET}
|
||||
FILES test_common "${CMAKE_CURRENT_LIST_DIR}/test/test_common.hpp" "${CMAKE_CURRENT_LIST_DIR}/test/test_common.impl.hpp"
|
||||
FILES Src ${perf_srcs}
|
||||
FILES Include ${perf_hdrs}
|
||||
)
|
||||
|
||||
ocv_option(${the_module}_PERF_CAFFE "Add performance tests of Caffe framework" OFF)
|
||||
ocv_option(${the_module}_PERF_CLCAFFE "Add performance tests of clCaffe framework" OFF)
|
||||
|
||||
@@ -955,13 +955,6 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
CV_OUT std::vector<int>& indices,
|
||||
const float eta = 1.f, const int top_k = 0);
|
||||
|
||||
/** @brief Release a Myriad device is binded by OpenCV.
|
||||
*
|
||||
* Single Myriad device cannot be shared across multiple processes which uses
|
||||
* Inference Engine's Myriad plugin.
|
||||
*/
|
||||
CV_EXPORTS_W void resetMyriadDevice();
|
||||
|
||||
//! @}
|
||||
CV__DNN_INLINE_NS_END
|
||||
}
|
||||
@@ -970,4 +963,7 @@ CV__DNN_INLINE_NS_END
|
||||
#include <opencv2/dnn/layer.hpp>
|
||||
#include <opencv2/dnn/dnn.inl.hpp>
|
||||
|
||||
/// @deprecated Include this header directly from application. Automatic inclusion will be removed
|
||||
#include <opencv2/dnn/utils/inference_engine.hpp>
|
||||
|
||||
#endif /* OPENCV_DNN_DNN_HPP */
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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.
|
||||
//
|
||||
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#ifndef OPENCV_DNN_UTILS_INF_ENGINE_HPP
|
||||
#define OPENCV_DNN_UTILS_INF_ENGINE_HPP
|
||||
|
||||
#include "../dnn.hpp"
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
|
||||
/** @brief Release a Myriad device (binded by OpenCV).
|
||||
*
|
||||
* Single Myriad device cannot be shared across multiple processes which uses
|
||||
* Inference Engine's Myriad plugin.
|
||||
*/
|
||||
CV_EXPORTS_W void resetMyriadDevice();
|
||||
|
||||
|
||||
/* Values for 'OPENCV_DNN_IE_VPU_TYPE' parameter */
|
||||
#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_UNSPECIFIED ""
|
||||
/// Intel(R) Movidius(TM) Neural Compute Stick, NCS (USB 03e7:2150), Myriad2 (https://software.intel.com/en-us/movidius-ncs)
|
||||
#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2 "Myriad2"
|
||||
/// Intel(R) Neural Compute Stick 2, NCS2 (USB 03e7:2485), MyriadX (https://software.intel.com/ru-ru/neural-compute-stick)
|
||||
#define CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X "MyriadX"
|
||||
|
||||
|
||||
/** @brief Returns Inference Engine VPU type.
|
||||
*
|
||||
* See values of `CV_DNN_INFERENCE_ENGINE_VPU_TYPE_*` macros.
|
||||
*/
|
||||
CV_EXPORTS_W cv::String getInferenceEngineVPUType();
|
||||
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace
|
||||
|
||||
#endif // OPENCV_DNN_UTILS_INF_ENGINE_HPP
|
||||
@@ -0,0 +1,6 @@
|
||||
// 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 "perf_precomp.hpp"
|
||||
#include "../test/test_common.impl.hpp" // shared with accuracy tests
|
||||
@@ -185,6 +185,11 @@ PERF_TEST_P_(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#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));
|
||||
}
|
||||
@@ -217,6 +222,10 @@ PERF_TEST_P_(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
|
||||
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 (backend == DNN_BACKEND_HALIDE ||
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
|
||||
+10
-12
@@ -253,7 +253,7 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef
|
||||
std::vector<Mat> images;
|
||||
images_.getMatVector(images);
|
||||
CV_Assert(!images.empty());
|
||||
for (int i = 0; i < images.size(); i++)
|
||||
for (size_t i = 0; i < images.size(); i++)
|
||||
{
|
||||
Size imgSize = images[i].size();
|
||||
if (size == Size())
|
||||
@@ -283,11 +283,10 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef
|
||||
images[i] *= scalefactor;
|
||||
}
|
||||
|
||||
size_t i, nimages = images.size();
|
||||
size_t nimages = images.size();
|
||||
Mat image0 = images[0];
|
||||
int nch = image0.channels();
|
||||
CV_Assert(image0.dims == 2);
|
||||
Mat image;
|
||||
if (nch == 3 || nch == 4)
|
||||
{
|
||||
int sz[] = { (int)nimages, nch, image0.rows, image0.cols };
|
||||
@@ -295,9 +294,9 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef
|
||||
Mat blob = blob_.getMat();
|
||||
Mat ch[4];
|
||||
|
||||
for( i = 0; i < nimages; i++ )
|
||||
for(size_t i = 0; i < nimages; i++ )
|
||||
{
|
||||
image = images[i];
|
||||
const Mat& image = images[i];
|
||||
CV_Assert(image.depth() == blob_.depth());
|
||||
nch = image.channels();
|
||||
CV_Assert(image.dims == 2 && (nch == 3 || nch == 4));
|
||||
@@ -317,9 +316,9 @@ void blobFromImages(InputArrayOfArrays images_, OutputArray blob_, double scalef
|
||||
blob_.create(4, sz, ddepth);
|
||||
Mat blob = blob_.getMat();
|
||||
|
||||
for( i = 0; i < nimages; i++ )
|
||||
for(size_t i = 0; i < nimages; i++ )
|
||||
{
|
||||
Mat image = images[i];
|
||||
const Mat& image = images[i];
|
||||
CV_Assert(image.depth() == blob_.depth());
|
||||
nch = image.channels();
|
||||
CV_Assert(image.dims == 2 && (nch == 1));
|
||||
@@ -1700,7 +1699,7 @@ struct Net::Impl
|
||||
preferableTarget == DNN_TARGET_MYRIAD ||
|
||||
preferableTarget == DNN_TARGET_FPGA) && !fused)
|
||||
{
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
|
||||
for (const std::string& name : {"weights", "biases"})
|
||||
{
|
||||
auto it = ieNode->layer.getParameters().find(name);
|
||||
@@ -2146,10 +2145,6 @@ struct Net::Impl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (preferableBackend != DNN_BACKEND_OPENCV)
|
||||
continue; // Go to the next layer.
|
||||
|
||||
// the optimization #2. if there is no layer that takes max pooling layer's computed
|
||||
// max indices (and only some semantical segmentation networks might need this;
|
||||
// many others only take the maximum values), then we switch the max pooling
|
||||
@@ -2170,6 +2165,9 @@ struct Net::Impl
|
||||
}
|
||||
}
|
||||
|
||||
if (preferableBackend != DNN_BACKEND_OPENCV)
|
||||
continue; // Go to the next layer.
|
||||
|
||||
// the optimization #3. if there is concat layer that concatenates channels
|
||||
// from the inputs together (i.e. axis == 1) then we make the inputs of
|
||||
// the concat layer to write to the concatenation output buffer
|
||||
|
||||
@@ -676,7 +676,7 @@ public:
|
||||
|
||||
int inpCnAll = input.size[1], width = input.size[3], height = input.size[2];
|
||||
int inpCn = inpCnAll / ngroups;
|
||||
p.is1x1_ = kernel == Size(0,0) && pad == Size(0, 0);
|
||||
p.is1x1_ = kernel == Size(1,1) && pad == Size(0, 0);
|
||||
p.useAVX = checkHardwareSupport(CPU_AVX);
|
||||
p.useAVX2 = checkHardwareSupport(CPU_AVX2);
|
||||
p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX;
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
return (bias == 1) && (preferableTarget != DNN_TARGET_MYRIAD || type == SPATIAL_NRM);
|
||||
return bias == 1;
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan() && (size % 2 == 1) && (type == CHANNEL_NRM));
|
||||
|
||||
@@ -290,7 +290,7 @@ public:
|
||||
weights = wrapToInfEngineBlob(blobs[0], {(size_t)numChannels}, InferenceEngine::Layout::C);
|
||||
l.getParameters()["channel_shared"] = blobs[0].total() == 1;
|
||||
}
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
|
||||
l.getParameters()["weights"] = weights;
|
||||
#else
|
||||
l.addConstantData("weights", weights);
|
||||
|
||||
@@ -148,10 +148,18 @@ public:
|
||||
{
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
{
|
||||
if (preferableTarget == DNN_TARGET_MYRIAD)
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (preferableTarget == DNN_TARGET_MYRIAD) {
|
||||
if (type == MAX && (pad_l == 1 && pad_t == 1) && stride == Size(2, 2) ) {
|
||||
return !isMyriadX();
|
||||
}
|
||||
return type == MAX || type == AVE;
|
||||
}
|
||||
else
|
||||
return type != STOCHASTIC;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
|
||||
@@ -591,6 +591,37 @@ void ONNXImporter::populateNet(Net dstNet)
|
||||
}
|
||||
layerParams.set("num_output", layerParams.blobs[0].size[1] * layerParams.get<int>("group", 1));
|
||||
layerParams.set("bias_term", node_proto.input_size() == 3);
|
||||
|
||||
if (layerParams.has("output_shape"))
|
||||
{
|
||||
const DictValue& outShape = layerParams.get("output_shape");
|
||||
|
||||
if (outShape.size() != 4)
|
||||
CV_Error(Error::StsNotImplemented, "Output shape must have 4 elements.");
|
||||
|
||||
const int strideY = layerParams.get<int>("stride_h", 1);
|
||||
const int strideX = layerParams.get<int>("stride_w", 1);
|
||||
const int outH = outShape.getIntValue(2);
|
||||
const int outW = outShape.getIntValue(3);
|
||||
|
||||
if (layerParams.get<String>("pad_mode") == "SAME")
|
||||
{
|
||||
layerParams.set("adj_w", (outW - 1) % strideX);
|
||||
layerParams.set("adj_h", (outH - 1) % strideY);
|
||||
}
|
||||
else if (layerParams.get<String>("pad_mode") == "VALID")
|
||||
{
|
||||
if (!layerParams.has("kernel_h") || !layerParams.has("kernel_w"))
|
||||
CV_Error(Error::StsNotImplemented,
|
||||
"Required attributes 'kernel_h' and 'kernel_w' are not present.");
|
||||
|
||||
int kernelH = layerParams.get<int>("kernel_h");
|
||||
int kernelW = layerParams.get<int>("kernel_w");
|
||||
|
||||
layerParams.set("adj_w", (outW - kernelW) % strideX);
|
||||
layerParams.set("adj_h", (outH - kernelH) % strideY);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (layer_type == "Transpose")
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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.
|
||||
//
|
||||
// Copyright (C) 2018, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "precomp.hpp"
|
||||
@@ -12,8 +12,14 @@
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
#include <ie_extension.h>
|
||||
#include <ie_plugin_dispatcher.hpp>
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R5)
|
||||
#include <vpu/vpu_plugin_config.hpp>
|
||||
#endif
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
@@ -124,7 +130,7 @@ void InfEngineBackendNet::init(int targetId)
|
||||
for (int id : unconnectedLayersIds)
|
||||
{
|
||||
InferenceEngine::Builder::OutputLayer outLayer("myconv1");
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
|
||||
// Inference Engine determines network precision by ports.
|
||||
InferenceEngine::Precision p = (targetId == DNN_TARGET_MYRIAD ||
|
||||
targetId == DNN_TARGET_OPENCL_FP16) ?
|
||||
@@ -182,7 +188,7 @@ void InfEngineBackendNet::init(int targetId)
|
||||
|
||||
void InfEngineBackendNet::addLayer(InferenceEngine::Builder::Layer& layer)
|
||||
{
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
|
||||
// Add weights to network and connect them after input blobs.
|
||||
std::map<std::string, InferenceEngine::Parameter>& params = layer.getParameters();
|
||||
std::vector<int> blobsIds;
|
||||
@@ -223,7 +229,7 @@ void InfEngineBackendNet::addLayer(InferenceEngine::Builder::Layer& layer)
|
||||
CV_Assert(layers.insert({layerName, id}).second);
|
||||
unconnectedLayersIds.insert(id);
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
|
||||
// By default, all the weights are connected to last ports ids.
|
||||
for (int i = 0; i < blobsIds.size(); ++i)
|
||||
{
|
||||
@@ -683,6 +689,64 @@ static std::map<InferenceEngine::TargetDevice, InferenceEngine::InferenceEngineP
|
||||
return sharedPlugins;
|
||||
}
|
||||
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R5) && !defined(OPENCV_DNN_IE_VPU_TYPE_DEFAULT)
|
||||
static bool detectMyriadX_()
|
||||
{
|
||||
InferenceEngine::Builder::Network builder("");
|
||||
InferenceEngine::idx_t inpId = builder.addLayer(
|
||||
InferenceEngine::Builder::InputLayer().setPort(InferenceEngine::Port({1})));
|
||||
|
||||
#if INF_ENGINE_RELEASE <= 2018050000
|
||||
InferenceEngine::idx_t clampId;
|
||||
{
|
||||
InferenceEngine::Builder::Layer l = InferenceEngine::Builder::ClampLayer();
|
||||
auto& blobs = l.getConstantData();
|
||||
auto blob = InferenceEngine::make_shared_blob<int16_t>(
|
||||
InferenceEngine::Precision::FP16,
|
||||
InferenceEngine::Layout::C, {1});
|
||||
blob->allocate();
|
||||
blobs[""] = blob;
|
||||
clampId = builder.addLayer({inpId}, l);
|
||||
}
|
||||
builder.addLayer({InferenceEngine::PortInfo(clampId)}, InferenceEngine::Builder::OutputLayer());
|
||||
#else
|
||||
InferenceEngine::idx_t clampId = builder.addLayer({inpId}, InferenceEngine::Builder::ClampLayer());
|
||||
builder.addLayer({InferenceEngine::PortInfo(clampId)},
|
||||
InferenceEngine::Builder::OutputLayer().setPort(InferenceEngine::Port({},
|
||||
InferenceEngine::Precision::FP16)));
|
||||
#endif
|
||||
|
||||
InferenceEngine::CNNNetwork cnn = InferenceEngine::CNNNetwork(
|
||||
InferenceEngine::Builder::convertToICNNNetwork(builder.build()));
|
||||
|
||||
InferenceEngine::TargetDevice device = InferenceEngine::TargetDevice::eMYRIAD;
|
||||
InferenceEngine::InferenceEnginePluginPtr enginePtr;
|
||||
{
|
||||
AutoLock lock(getInitializationMutex());
|
||||
auto& sharedPlugins = getSharedPlugins();
|
||||
auto pluginIt = sharedPlugins.find(device);
|
||||
if (pluginIt != sharedPlugins.end()) {
|
||||
enginePtr = pluginIt->second;
|
||||
} else {
|
||||
auto dispatcher = InferenceEngine::PluginDispatcher({""});
|
||||
enginePtr = dispatcher.getSuitablePlugin(device);
|
||||
sharedPlugins[device] = enginePtr;
|
||||
}
|
||||
}
|
||||
auto plugin = InferenceEngine::InferencePlugin(enginePtr);
|
||||
try
|
||||
{
|
||||
auto netExec = plugin.LoadNetwork(cnn, {{InferenceEngine::VPUConfigParams::KEY_VPU_PLATFORM,
|
||||
InferenceEngine::VPUConfigParams::VPU_2480}});
|
||||
auto infRequest = netExec.CreateInferRequest();
|
||||
} catch(...) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // >= 2018R5
|
||||
|
||||
void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net)
|
||||
{
|
||||
CV_Assert(!isInitialized());
|
||||
@@ -720,6 +784,8 @@ void InfEngineBackendNet::initPlugin(InferenceEngine::ICNNNetwork& net)
|
||||
continue;
|
||||
#ifdef _WIN32
|
||||
std::string libName = "cpu_extension" + suffixes[i] + ".dll";
|
||||
#elif defined(__APPLE__)
|
||||
std::string libName = "libcpu_extension" + suffixes[i] + ".dylib";
|
||||
#else
|
||||
std::string libName = "libcpu_extension" + suffixes[i] + ".so";
|
||||
#endif // _WIN32
|
||||
@@ -784,7 +850,11 @@ bool InfEngineBackendLayer::getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
std::vector<MatShape> &outputs,
|
||||
std::vector<MatShape> &internals) const
|
||||
{
|
||||
#if INF_ENGINE_VER_MAJOR_EQ(INF_ENGINE_RELEASE_2018R3)
|
||||
InferenceEngine::ICNNNetwork::InputShapes inShapes = const_cast<InferenceEngine::CNNNetwork&>(t_net).getInputShapes();
|
||||
#else
|
||||
InferenceEngine::ICNNNetwork::InputShapes inShapes = t_net.getInputShapes();
|
||||
#endif
|
||||
InferenceEngine::ICNNNetwork::InputShapes::iterator itr;
|
||||
bool equal_flag = true;
|
||||
size_t i = 0;
|
||||
@@ -835,7 +905,7 @@ InferenceEngine::Blob::Ptr convertFp16(const InferenceEngine::Blob::Ptr& blob)
|
||||
void addConstantData(const std::string& name, InferenceEngine::Blob::Ptr data,
|
||||
InferenceEngine::Builder::Layer& l)
|
||||
{
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R5)
|
||||
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2019R1)
|
||||
l.getParameters()[name] = data;
|
||||
#else
|
||||
l.addConstantData(name, data);
|
||||
@@ -875,5 +945,59 @@ void resetMyriadDevice()
|
||||
#endif // HAVE_INF_ENGINE
|
||||
}
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
bool isMyriadX()
|
||||
{
|
||||
static bool myriadX = getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X;
|
||||
return myriadX;
|
||||
}
|
||||
|
||||
static std::string getInferenceEngineVPUType_()
|
||||
{
|
||||
static std::string param_vpu_type = utils::getConfigurationParameterString("OPENCV_DNN_IE_VPU_TYPE", "");
|
||||
if (param_vpu_type == "")
|
||||
{
|
||||
#if defined(OPENCV_DNN_IE_VPU_TYPE_DEFAULT)
|
||||
param_vpu_type = OPENCV_DNN_IE_VPU_TYPE_DEFAULT;
|
||||
#elif INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R5)
|
||||
CV_LOG_INFO(NULL, "OpenCV-DNN: running Inference Engine VPU autodetection: Myriad2/X. In case of other accelerator types specify 'OPENCV_DNN_IE_VPU_TYPE' parameter");
|
||||
try {
|
||||
bool isMyriadX_ = detectMyriadX_();
|
||||
if (isMyriadX_)
|
||||
{
|
||||
param_vpu_type = CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X;
|
||||
}
|
||||
else
|
||||
{
|
||||
param_vpu_type = CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "OpenCV-DNN: Failed Inference Engine VPU autodetection. Specify 'OPENCV_DNN_IE_VPU_TYPE' parameter.");
|
||||
param_vpu_type.clear();
|
||||
}
|
||||
#else
|
||||
CV_LOG_WARNING(NULL, "OpenCV-DNN: VPU auto-detection is not implemented. Consider specifying VPU type via 'OPENCV_DNN_IE_VPU_TYPE' parameter");
|
||||
param_vpu_type = CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2;
|
||||
#endif
|
||||
}
|
||||
CV_LOG_INFO(NULL, "OpenCV-DNN: Inference Engine VPU type='" << param_vpu_type << "'");
|
||||
return param_vpu_type;
|
||||
}
|
||||
|
||||
cv::String getInferenceEngineVPUType()
|
||||
{
|
||||
static cv::String vpu_type = getInferenceEngineVPUType_();
|
||||
return vpu_type;
|
||||
}
|
||||
#else // HAVE_INF_ENGINE
|
||||
cv::String getInferenceEngineVPUType()
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "This OpenCV build doesn't include InferenceEngine support");
|
||||
}
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace dnn, namespace cv
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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.
|
||||
//
|
||||
// Copyright (C) 2018, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#ifndef __OPENCV_DNN_OP_INF_ENGINE_HPP__
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "opencv2/core/cvstd.hpp"
|
||||
#include "opencv2/dnn.hpp"
|
||||
|
||||
#include "opencv2/dnn/utils/inference_engine.hpp"
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
#if defined(__GNUC__) && __GNUC__ >= 5
|
||||
//#pragma GCC diagnostic push
|
||||
@@ -25,10 +27,11 @@
|
||||
#define INF_ENGINE_RELEASE_2018R3 2018030000
|
||||
#define INF_ENGINE_RELEASE_2018R4 2018040000
|
||||
#define INF_ENGINE_RELEASE_2018R5 2018050000
|
||||
#define INF_ENGINE_RELEASE_2019R1 2019010000
|
||||
|
||||
#ifndef INF_ENGINE_RELEASE
|
||||
#warning("IE version have not been provided via command-line. Using 2018R5 by default")
|
||||
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2018R5
|
||||
#warning("IE version have not been provided via command-line. Using 2019R1 by default")
|
||||
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2019R1
|
||||
#endif
|
||||
|
||||
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
|
||||
@@ -114,10 +117,8 @@ public:
|
||||
|
||||
virtual size_t getBatchSize() const CV_NOEXCEPT CV_OVERRIDE;
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R2)
|
||||
virtual InferenceEngine::StatusCode AddExtension(const InferenceEngine::IShapeInferExtensionPtr& extension, InferenceEngine::ResponseDesc* resp) CV_NOEXCEPT;
|
||||
virtual InferenceEngine::StatusCode reshape(const InputShapes& inputShapes, InferenceEngine::ResponseDesc* resp) CV_NOEXCEPT;
|
||||
#endif
|
||||
virtual InferenceEngine::StatusCode AddExtension(const InferenceEngine::IShapeInferExtensionPtr& extension, InferenceEngine::ResponseDesc* resp) CV_NOEXCEPT CV_OVERRIDE;
|
||||
virtual InferenceEngine::StatusCode reshape(const InputShapes& inputShapes, InferenceEngine::ResponseDesc* resp) CV_NOEXCEPT CV_OVERRIDE;
|
||||
|
||||
void init(int targetId);
|
||||
|
||||
@@ -279,6 +280,12 @@ private:
|
||||
InferenceEngine::CNNNetwork t_net;
|
||||
};
|
||||
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
bool isMyriadX();
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
bool haveInfEngine();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#ifdef HAVE_PROTOBUF
|
||||
|
||||
#include "tf_graph_simplifier.hpp"
|
||||
#include <queue>
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
@@ -630,6 +631,21 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class SoftMaxSlimSubgraph : public Subgraph
|
||||
{
|
||||
public:
|
||||
SoftMaxSlimSubgraph()
|
||||
{
|
||||
int input = addNodeToMatch("");
|
||||
int shape = addNodeToMatch("Const");
|
||||
int shapeOp = addNodeToMatch("Shape", input);
|
||||
int reshape = addNodeToMatch("Reshape", input, shape);
|
||||
int softmax = addNodeToMatch("Softmax", reshape);
|
||||
addNodeToMatch("Reshape", softmax, shapeOp);
|
||||
setFusedNode("Softmax", input);
|
||||
}
|
||||
};
|
||||
|
||||
void simplifySubgraphs(tensorflow::GraphDef& net)
|
||||
{
|
||||
std::vector<Ptr<Subgraph> > subgraphs;
|
||||
@@ -646,6 +662,7 @@ void simplifySubgraphs(tensorflow::GraphDef& net)
|
||||
subgraphs.push_back(Ptr<Subgraph>(new ResizeBilinearSubgraph()));
|
||||
subgraphs.push_back(Ptr<Subgraph>(new UpsamplingKerasSubgraph()));
|
||||
subgraphs.push_back(Ptr<Subgraph>(new ReshapeAsShapeSubgraph()));
|
||||
subgraphs.push_back(Ptr<Subgraph>(new SoftMaxSlimSubgraph()));
|
||||
|
||||
int numNodes = net.node_size();
|
||||
std::vector<int> matchedNodesIds;
|
||||
@@ -867,7 +884,6 @@ void sortByExecutionOrder(tensorflow::GraphDef& net)
|
||||
nodesToAdd.pop_back();
|
||||
|
||||
permIds.push_back(nodeToAdd);
|
||||
// std::cout << net.node(nodeToAdd).name() << '\n';
|
||||
|
||||
for (int i = 0; i < edges[nodeToAdd].size(); ++i)
|
||||
{
|
||||
@@ -886,6 +902,85 @@ void sortByExecutionOrder(tensorflow::GraphDef& net)
|
||||
permute(net.mutable_node(), permIds);
|
||||
}
|
||||
|
||||
// Remove training switches (Switch and Merge nodes and corresponding subgraphs).
|
||||
void removePhaseSwitches(tensorflow::GraphDef& net)
|
||||
{
|
||||
std::vector<int> nodesToRemove;
|
||||
std::map<std::string, int> nodesMap;
|
||||
std::map<std::string, int>::iterator nodesMapIt;
|
||||
std::queue<int> mergeOpSubgraphNodes;
|
||||
for (int i = 0; i < net.node_size(); ++i)
|
||||
{
|
||||
const tensorflow::NodeDef& node = net.node(i);
|
||||
nodesMap.insert(std::make_pair(node.name(), i));
|
||||
if (node.op() == "Switch" || node.op() == "Merge")
|
||||
{
|
||||
CV_Assert(node.input_size() > 0);
|
||||
// Replace consumers' inputs.
|
||||
for (int j = 0; j < net.node_size(); ++j)
|
||||
{
|
||||
tensorflow::NodeDef* consumer = net.mutable_node(j);
|
||||
for (int k = 0; k < consumer->input_size(); ++k)
|
||||
{
|
||||
std::string inpName = consumer->input(k);
|
||||
inpName = inpName.substr(0, inpName.rfind(':'));
|
||||
if (inpName == node.name())
|
||||
{
|
||||
consumer->set_input(k, node.input(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
nodesToRemove.push_back(i);
|
||||
if (node.op() == "Merge")
|
||||
mergeOpSubgraphNodes.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> numConsumers(net.node_size(), 0);
|
||||
for (int i = 0; i < net.node_size(); ++i)
|
||||
{
|
||||
const tensorflow::NodeDef& node = net.node(i);
|
||||
for (int j = 0; j < node.input_size(); ++j)
|
||||
{
|
||||
std::string inpName = node.input(j);
|
||||
inpName = inpName.substr(1 + (int)inpName.find('^'), inpName.rfind(':'));
|
||||
nodesMapIt = nodesMap.find(inpName);
|
||||
CV_Assert(nodesMapIt != nodesMap.end());
|
||||
numConsumers[nodesMapIt->second] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove subgraphs of unused nodes which are terminated by Merge nodes.
|
||||
while (!mergeOpSubgraphNodes.empty())
|
||||
{
|
||||
const tensorflow::NodeDef& node = net.node(mergeOpSubgraphNodes.front());
|
||||
mergeOpSubgraphNodes.pop();
|
||||
for (int i = 0; i < node.input_size(); ++i)
|
||||
{
|
||||
std::string inpName = node.input(i);
|
||||
inpName = inpName.substr(1 + (int)inpName.find('^'), inpName.rfind(':'));
|
||||
nodesMapIt = nodesMap.find(inpName);
|
||||
CV_Assert(nodesMapIt != nodesMap.end());
|
||||
|
||||
int inpNodeId = nodesMapIt->second;
|
||||
if (numConsumers[inpNodeId] == 1)
|
||||
{
|
||||
mergeOpSubgraphNodes.push(inpNodeId);
|
||||
nodesToRemove.push_back(inpNodeId);
|
||||
}
|
||||
else if (numConsumers[inpNodeId] > 0)
|
||||
numConsumers[inpNodeId] -= 1;
|
||||
}
|
||||
}
|
||||
std::sort(nodesToRemove.begin(), nodesToRemove.end());
|
||||
for (int i = nodesToRemove.size() - 1; i >= 0; --i)
|
||||
{
|
||||
if (nodesToRemove[i] < net.node_size()) // Ids might be repeated.
|
||||
net.mutable_node()->DeleteSubrange(nodesToRemove[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace dnn, namespace cv
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ void releaseTensor(tensorflow::TensorProto* tensor);
|
||||
|
||||
void sortByExecutionOrder(tensorflow::GraphDef& net);
|
||||
|
||||
void removePhaseSwitches(tensorflow::GraphDef& net);
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace dnn, namespace cv
|
||||
|
||||
|
||||
@@ -657,11 +657,17 @@ static int predictOutputDataLayout(const tensorflow::GraphDef& net,
|
||||
|
||||
void TFImporter::populateNet(Net dstNet)
|
||||
{
|
||||
if (!netTxt.ByteSize())
|
||||
removePhaseSwitches(netBin);
|
||||
|
||||
RemoveIdentityOps(netBin);
|
||||
RemoveIdentityOps(netTxt);
|
||||
|
||||
if (!netTxt.ByteSize())
|
||||
{
|
||||
simplifySubgraphs(netBin);
|
||||
sortByExecutionOrder(netBin);
|
||||
}
|
||||
|
||||
std::set<String> layers_to_ignore;
|
||||
|
||||
@@ -939,7 +945,7 @@ void TFImporter::populateNet(Net dstNet)
|
||||
if (getDataLayout(name, data_layouts) == DATA_LAYOUT_UNKNOWN)
|
||||
data_layouts[name] = DATA_LAYOUT_NHWC;
|
||||
}
|
||||
else if (type == "BiasAdd" || type == "Add" || type == "Sub")
|
||||
else if (type == "BiasAdd" || type == "Add" || type == "Sub" || type=="AddN")
|
||||
{
|
||||
bool haveConst = false;
|
||||
for(int ii = 0; !haveConst && ii < layer.input_size(); ++ii)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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.
|
||||
//
|
||||
// Copyright (C) 2018, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
@@ -157,21 +157,29 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
|
||||
float diffScores = (target == DNN_TARGET_OPENCL_FP16) ? 6e-3 : 0.0;
|
||||
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
|
||||
inp, "detection_out", "", diffScores);
|
||||
float diffScores = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 1.5e-2 : 0.0;
|
||||
float diffSquares = (target == DNN_TARGET_MYRIAD) ? 0.063 : 0.0;
|
||||
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.252 : 0.0;
|
||||
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
|
||||
inp, "detection_out", "", diffScores, diffSquares, detectionConfThresh);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe_Different_Width_Height)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 560), Scalar(127.5, 127.5, 127.5), false);
|
||||
float diffScores = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.029 : 0.0;
|
||||
float diffSquares = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0;
|
||||
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
|
||||
inp, "detection_out", "", diffScores, diffSquares);
|
||||
inp, "detection_out", "", diffScores, diffSquares);
|
||||
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
|
||||
@@ -180,16 +188,22 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.011 : 0.0;
|
||||
float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.06 : 0.0;
|
||||
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.095 : 0.0;
|
||||
float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0;
|
||||
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.216 : 0.2;
|
||||
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt",
|
||||
inp, "detection_out", "", l1, lInf);
|
||||
inp, "detection_out", "", l1, lInf, detectionConfThresh);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
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;
|
||||
@@ -215,32 +229,54 @@ TEST_P(DNNTestNetwork, SSD_VGG16)
|
||||
if (backend == DNN_BACKEND_HALIDE && target == DNN_TARGET_CPU)
|
||||
throw SkipTestException("");
|
||||
double scoreThreshold = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0325 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.032 : 0.0;
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel",
|
||||
"dnn/ssd_vgg16.prototxt", inp, "detection_out", "", scoreThreshold);
|
||||
"dnn/ssd_vgg16.prototxt", inp, "detection_out", "", scoreThreshold, lInf);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_coco)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
|
||||
#endif
|
||||
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0056 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.072 : 0.0;
|
||||
processNet("dnn/openpose_pose_coco.caffemodel", "dnn/openpose_pose_coco.prototxt",
|
||||
Size(46, 46));
|
||||
Size(46, 46), "", "", l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
|
||||
#endif
|
||||
// output range: [-0.001, 0.97]
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.012 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.16 : 0.0;
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt",
|
||||
Size(46, 46));
|
||||
Size(46, 46), "", "", l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
|
||||
#endif
|
||||
// The same .caffemodel but modified .prototxt
|
||||
// See https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/src/openpose/pose/poseParameters.cpp
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi_faster_4_stages.prototxt",
|
||||
@@ -250,17 +286,24 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
TEST_P(DNNTestNetwork, OpenFace)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
#if INF_ENGINE_RELEASE == 2018050000
|
||||
#if INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("");
|
||||
#elif INF_ENGINE_RELEASE < 2018040000
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#elif INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX target");
|
||||
#else
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("Test is enabled starts from OpenVINO 2018R4");
|
||||
throw SkipTestException("Test has been fixed in OpenVINO 2018R4");
|
||||
#endif
|
||||
#endif
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/openface_nn4.small2.v1.t7", "", Size(96, 96), "");
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0024 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.0071 : 0.0;
|
||||
processNet("dnn/openface_nn4.small2.v1.t7", "", Size(96, 96), "", "", l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, opencv_face_detector)
|
||||
@@ -275,6 +318,11 @@ TEST_P(DNNTestNetwork, opencv_face_detector)
|
||||
|
||||
TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
@@ -289,7 +337,7 @@ TEST_P(DNNTestNetwork, DenseNet_121)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
|
||||
// Reference output values are in range [-3.807, 4.605]
|
||||
float l1 = 0.0, lInf = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
@@ -297,7 +345,7 @@ TEST_P(DNNTestNetwork, DenseNet_121)
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 6e-2; lInf = 0.27;
|
||||
l1 = 0.1; lInf = 0.6;
|
||||
}
|
||||
processNet("dnn/DenseNet_121.caffemodel", "dnn/DenseNet_121.prototxt", Size(224, 224), "", "", l1, lInf);
|
||||
}
|
||||
|
||||
@@ -376,6 +376,7 @@ TEST(Reproducibility_GoogLeNet_fp16, Accuracy)
|
||||
TEST_P(Test_Caffe_nets, Colorization)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
Mat inp = blobFromNPY(_tf("colorization_inp.npy"));
|
||||
Mat ref = blobFromNPY(_tf("colorization_out.npy"));
|
||||
Mat kernel = blobFromNPY(_tf("colorization_pts_in_hull.npy"));
|
||||
@@ -393,8 +394,12 @@ TEST_P(Test_Caffe_nets, Colorization)
|
||||
Mat out = net.forward();
|
||||
|
||||
// Reference output values are in range [-29.1, 69.5]
|
||||
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.25 : 4e-4;
|
||||
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 5.3 : 3e-3;
|
||||
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.25 : 4e-4;
|
||||
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 5.3 : 3e-3;
|
||||
if (target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
{
|
||||
l1 = 0.6; lInf = 15;
|
||||
}
|
||||
normAssert(out, ref, "", l1, lInf);
|
||||
}
|
||||
|
||||
@@ -423,7 +428,7 @@ TEST_P(Test_Caffe_nets, DenseNet_121)
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
l1 = 0.097; lInf = 0.52;
|
||||
l1 = 0.11; lInf = 0.5;
|
||||
}
|
||||
normAssert(out, ref, "", l1, lInf);
|
||||
}
|
||||
@@ -515,12 +520,14 @@ INSTANTIATE_TEST_CASE_P(Test_Caffe, opencv_face_detector,
|
||||
|
||||
TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
|
||||
{
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE > 2018030000
|
||||
|| (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("Test is disabled for DLIE OpenCL targets"); // very slow
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#endif
|
||||
)
|
||||
throw SkipTestException("");
|
||||
|
||||
static Mat ref = (Mat_<float>(3, 7) << 0, 2, 0.949398, 99.2454, 210.141, 601.205, 462.849,
|
||||
0, 7, 0.997022, 481.841, 92.3218, 722.685, 175.953,
|
||||
0, 12, 0.993028, 133.221, 189.377, 350.994, 563.166);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// 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 "test_precomp.hpp"
|
||||
#include "test_common.impl.hpp" // shared with perf tests
|
||||
@@ -1,266 +1,77 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's 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.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders 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 Intel Corporation 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.
|
||||
//
|
||||
//M*/
|
||||
// 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_TEST_COMMON_HPP__
|
||||
#define __OPENCV_TEST_COMMON_HPP__
|
||||
|
||||
#include "opencv2/dnn/utils/inference_engine.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
static inline void PrintTo(const cv::dnn::Backend& v, std::ostream* os)
|
||||
{
|
||||
switch (v) {
|
||||
case DNN_BACKEND_DEFAULT: *os << "DEFAULT"; return;
|
||||
case DNN_BACKEND_HALIDE: *os << "HALIDE"; return;
|
||||
case DNN_BACKEND_INFERENCE_ENGINE: *os << "DLIE"; return;
|
||||
case DNN_BACKEND_OPENCV: *os << "OCV"; return;
|
||||
case DNN_BACKEND_VKCOM: *os << "VKCOM"; return;
|
||||
} // don't use "default:" to emit compiler warnings
|
||||
*os << "DNN_BACKEND_UNKNOWN(" << (int)v << ")";
|
||||
}
|
||||
|
||||
static inline void PrintTo(const cv::dnn::Target& v, std::ostream* os)
|
||||
{
|
||||
switch (v) {
|
||||
case DNN_TARGET_CPU: *os << "CPU"; return;
|
||||
case DNN_TARGET_OPENCL: *os << "OCL"; return;
|
||||
case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return;
|
||||
case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return;
|
||||
case DNN_TARGET_VULKAN: *os << "VULKAN"; return;
|
||||
case DNN_TARGET_FPGA: *os << "FPGA"; return;
|
||||
} // don't use "default:" to emit compiler warnings
|
||||
*os << "DNN_TARGET_UNKNOWN(" << (int)v << ")";
|
||||
}
|
||||
|
||||
void PrintTo(const cv::dnn::Backend& v, std::ostream* os);
|
||||
void PrintTo(const cv::dnn::Target& v, std::ostream* os);
|
||||
using opencv_test::tuple;
|
||||
using opencv_test::get;
|
||||
static inline void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os)
|
||||
{
|
||||
PrintTo(get<0>(v), os);
|
||||
*os << "/";
|
||||
PrintTo(get<1>(v), os);
|
||||
}
|
||||
void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os);
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace
|
||||
}} // namespace cv::dnn
|
||||
|
||||
|
||||
|
||||
namespace opencv_test {
|
||||
|
||||
using namespace cv::dnn;
|
||||
|
||||
static inline const std::string &getOpenCVExtraDir()
|
||||
{
|
||||
return cvtest::TS::ptr()->get_data_path();
|
||||
}
|
||||
|
||||
static inline void normAssert(cv::InputArray ref, cv::InputArray test, const char *comment = "",
|
||||
double l1 = 0.00001, double lInf = 0.0001)
|
||||
{
|
||||
double normL1 = cvtest::norm(ref, test, cv::NORM_L1) / ref.getMat().total();
|
||||
EXPECT_LE(normL1, l1) << comment;
|
||||
void normAssert(
|
||||
cv::InputArray ref, cv::InputArray test, const char *comment = "",
|
||||
double l1 = 0.00001, double lInf = 0.0001);
|
||||
|
||||
double normInf = cvtest::norm(ref, test, cv::NORM_INF);
|
||||
EXPECT_LE(normInf, lInf) << comment;
|
||||
}
|
||||
std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m);
|
||||
|
||||
static std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m)
|
||||
{
|
||||
EXPECT_EQ(m.type(), CV_32FC1);
|
||||
EXPECT_EQ(m.dims, 2);
|
||||
EXPECT_EQ(m.cols, 4);
|
||||
|
||||
std::vector<cv::Rect2d> boxes(m.rows);
|
||||
for (int i = 0; i < m.rows; ++i)
|
||||
{
|
||||
CV_Assert(m.row(i).isContinuous());
|
||||
const float* data = m.ptr<float>(i);
|
||||
double l = data[0], t = data[1], r = data[2], b = data[3];
|
||||
boxes[i] = cv::Rect2d(l, t, r - l, b - t);
|
||||
}
|
||||
return boxes;
|
||||
}
|
||||
|
||||
static inline void normAssertDetections(const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refScores,
|
||||
const std::vector<cv::Rect2d>& refBoxes,
|
||||
const std::vector<int>& testClassIds,
|
||||
const std::vector<float>& testScores,
|
||||
const std::vector<cv::Rect2d>& testBoxes,
|
||||
const char *comment = "", double confThreshold = 0.0,
|
||||
double scores_diff = 1e-5, double boxes_iou_diff = 1e-4)
|
||||
{
|
||||
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
|
||||
for (int i = 0; i < testBoxes.size(); ++i)
|
||||
{
|
||||
double testScore = testScores[i];
|
||||
if (testScore < confThreshold)
|
||||
continue;
|
||||
|
||||
int testClassId = testClassIds[i];
|
||||
const cv::Rect2d& testBox = testBoxes[i];
|
||||
bool matched = false;
|
||||
for (int j = 0; j < refBoxes.size() && !matched; ++j)
|
||||
{
|
||||
if (!matchedRefBoxes[j] && testClassId == refClassIds[j] &&
|
||||
std::abs(testScore - refScores[j]) < scores_diff)
|
||||
{
|
||||
double interArea = (testBox & refBoxes[j]).area();
|
||||
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
|
||||
if (std::abs(iou - 1.0) < boxes_iou_diff)
|
||||
{
|
||||
matched = true;
|
||||
matchedRefBoxes[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!matched)
|
||||
std::cout << cv::format("Unmatched prediction: class %d score %f box ",
|
||||
testClassId, testScore) << testBox << std::endl;
|
||||
EXPECT_TRUE(matched) << comment;
|
||||
}
|
||||
|
||||
// Check unmatched reference detections.
|
||||
for (int i = 0; i < refBoxes.size(); ++i)
|
||||
{
|
||||
if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
|
||||
{
|
||||
std::cout << cv::format("Unmatched reference: class %d score %f box ",
|
||||
refClassIds[i], refScores[i]) << refBoxes[i] << std::endl;
|
||||
EXPECT_LE(refScores[i], confThreshold) << comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
void normAssertDetections(
|
||||
const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refScores,
|
||||
const std::vector<cv::Rect2d>& refBoxes,
|
||||
const std::vector<int>& testClassIds,
|
||||
const std::vector<float>& testScores,
|
||||
const std::vector<cv::Rect2d>& testBoxes,
|
||||
const char *comment = "", double confThreshold = 0.0,
|
||||
double scores_diff = 1e-5, double boxes_iou_diff = 1e-4);
|
||||
|
||||
// For SSD-based object detection networks which produce output of shape 1x1xNx7
|
||||
// where N is a number of detections and an every detection is represented by
|
||||
// a vector [batchId, classId, confidence, left, top, right, bottom].
|
||||
static inline void normAssertDetections(cv::Mat ref, cv::Mat out, const char *comment = "",
|
||||
double confThreshold = 0.0, double scores_diff = 1e-5,
|
||||
double boxes_iou_diff = 1e-4)
|
||||
{
|
||||
CV_Assert(ref.total() % 7 == 0);
|
||||
CV_Assert(out.total() % 7 == 0);
|
||||
ref = ref.reshape(1, ref.total() / 7);
|
||||
out = out.reshape(1, out.total() / 7);
|
||||
void normAssertDetections(
|
||||
cv::Mat ref, cv::Mat out, const char *comment = "",
|
||||
double confThreshold = 0.0, double scores_diff = 1e-5,
|
||||
double boxes_iou_diff = 1e-4);
|
||||
|
||||
cv::Mat refClassIds, testClassIds;
|
||||
ref.col(1).convertTo(refClassIds, CV_32SC1);
|
||||
out.col(1).convertTo(testClassIds, CV_32SC1);
|
||||
std::vector<float> refScores(ref.col(2)), testScores(out.col(2));
|
||||
std::vector<cv::Rect2d> refBoxes = matToBoxes(ref.colRange(3, 7));
|
||||
std::vector<cv::Rect2d> testBoxes = matToBoxes(out.colRange(3, 7));
|
||||
normAssertDetections(refClassIds, refScores, refBoxes, testClassIds, testScores,
|
||||
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
|
||||
}
|
||||
bool readFileInMemory(const std::string& filename, std::string& content);
|
||||
|
||||
static inline bool readFileInMemory(const std::string& filename, std::string& content)
|
||||
{
|
||||
std::ios::openmode mode = std::ios::in | std::ios::binary;
|
||||
std::ifstream ifs(filename.c_str(), mode);
|
||||
if (!ifs.is_open())
|
||||
return false;
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
bool validateVPUType();
|
||||
#endif
|
||||
|
||||
content.clear();
|
||||
|
||||
ifs.seekg(0, std::ios::end);
|
||||
content.reserve(ifs.tellg());
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
content.assign((std::istreambuf_iterator<char>(ifs)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace opencv_test {
|
||||
|
||||
using namespace cv::dnn;
|
||||
|
||||
static inline
|
||||
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
|
||||
bool withInferenceEngine = true,
|
||||
bool withHalide = false,
|
||||
bool withCpuOCV = true,
|
||||
bool withVkCom = true
|
||||
)
|
||||
{
|
||||
std::vector< tuple<Backend, Target> > targets;
|
||||
std::vector< Target > available;
|
||||
if (withHalide)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_HALIDE);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, *i));
|
||||
}
|
||||
if (withInferenceEngine)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, *i));
|
||||
}
|
||||
if (withVkCom)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_VKCOM);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
targets.push_back(make_tuple(DNN_BACKEND_VKCOM, *i));
|
||||
}
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_OPENCV);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if (!withCpuOCV && *i == DNN_TARGET_CPU)
|
||||
continue;
|
||||
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, *i));
|
||||
}
|
||||
}
|
||||
if (targets.empty()) // validate at least CPU mode
|
||||
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
|
||||
return testing::ValuesIn(targets);
|
||||
}
|
||||
);
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace opencv_test {
|
||||
using namespace cv::dnn;
|
||||
|
||||
class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
|
||||
{
|
||||
@@ -276,29 +87,29 @@ public:
|
||||
getDefaultThresholds(backend, target, &default_l1, &default_lInf);
|
||||
}
|
||||
|
||||
static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
*l1 = 4e-3;
|
||||
*lInf = 2e-2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*l1 = 1e-5;
|
||||
*lInf = 1e-4;
|
||||
}
|
||||
}
|
||||
static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
*l1 = 4e-3;
|
||||
*lInf = 2e-2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*l1 = 1e-5;
|
||||
*lInf = 1e-4;
|
||||
}
|
||||
}
|
||||
|
||||
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
|
||||
inp->size[0] != 1 && inp->size[0] != ref->size[0])
|
||||
throw SkipTestException("Inconsistent batch size of input and output blobs for Myriad plugin");
|
||||
}
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
|
||||
inp->size[0] != 1 && inp->size[0] != ref->size[0])
|
||||
throw SkipTestException("Inconsistent batch size of input and output blobs for Myriad plugin");
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void checkBackend(Mat* inp = 0, Mat* ref = 0)
|
||||
@@ -309,4 +120,12 @@ protected:
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// src/op_inf_engine.hpp
|
||||
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
|
||||
#define INF_ENGINE_VER_MAJOR_GE(ver) (((INF_ENGINE_RELEASE) / 10000) >= ((ver) / 10000))
|
||||
#define INF_ENGINE_VER_MAJOR_LT(ver) (((INF_ENGINE_RELEASE) / 10000) < ((ver) / 10000))
|
||||
#define INF_ENGINE_VER_MAJOR_LE(ver) (((INF_ENGINE_RELEASE) / 10000) <= ((ver) / 10000))
|
||||
#define INF_ENGINE_VER_MAJOR_EQ(ver) (((INF_ENGINE_RELEASE) / 10000) == ((ver) / 10000))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
// 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.
|
||||
|
||||
// Used in accuracy and perf tests as a content of .cpp file
|
||||
// Note: don't use "precomp.hpp" here
|
||||
#include "opencv2/ts.hpp"
|
||||
#include "opencv2/ts/ts_perf.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
|
||||
#include "opencv2/dnn.hpp"
|
||||
#include "test_common.hpp"
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
namespace cv { namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
void PrintTo(const cv::dnn::Backend& v, std::ostream* os)
|
||||
{
|
||||
switch (v) {
|
||||
case DNN_BACKEND_DEFAULT: *os << "DEFAULT"; return;
|
||||
case DNN_BACKEND_HALIDE: *os << "HALIDE"; return;
|
||||
case DNN_BACKEND_INFERENCE_ENGINE: *os << "DLIE"; return;
|
||||
case DNN_BACKEND_VKCOM: *os << "VKCOM"; return;
|
||||
case DNN_BACKEND_OPENCV: *os << "OCV"; return;
|
||||
} // don't use "default:" to emit compiler warnings
|
||||
*os << "DNN_BACKEND_UNKNOWN(" << (int)v << ")";
|
||||
}
|
||||
|
||||
void PrintTo(const cv::dnn::Target& v, std::ostream* os)
|
||||
{
|
||||
switch (v) {
|
||||
case DNN_TARGET_CPU: *os << "CPU"; return;
|
||||
case DNN_TARGET_OPENCL: *os << "OCL"; return;
|
||||
case DNN_TARGET_OPENCL_FP16: *os << "OCL_FP16"; return;
|
||||
case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return;
|
||||
case DNN_TARGET_VULKAN: *os << "VULKAN"; return;
|
||||
case DNN_TARGET_FPGA: *os << "FPGA"; return;
|
||||
} // don't use "default:" to emit compiler warnings
|
||||
*os << "DNN_TARGET_UNKNOWN(" << (int)v << ")";
|
||||
}
|
||||
|
||||
void PrintTo(const tuple<cv::dnn::Backend, cv::dnn::Target> v, std::ostream* os)
|
||||
{
|
||||
PrintTo(get<0>(v), os);
|
||||
*os << "/";
|
||||
PrintTo(get<1>(v), os);
|
||||
}
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace
|
||||
|
||||
|
||||
|
||||
namespace opencv_test {
|
||||
|
||||
void normAssert(
|
||||
cv::InputArray ref, cv::InputArray test, const char *comment /*= ""*/,
|
||||
double l1 /*= 0.00001*/, double lInf /*= 0.0001*/)
|
||||
{
|
||||
double normL1 = cvtest::norm(ref, test, cv::NORM_L1) / ref.getMat().total();
|
||||
EXPECT_LE(normL1, l1) << comment;
|
||||
|
||||
double normInf = cvtest::norm(ref, test, cv::NORM_INF);
|
||||
EXPECT_LE(normInf, lInf) << comment;
|
||||
}
|
||||
|
||||
std::vector<cv::Rect2d> matToBoxes(const cv::Mat& m)
|
||||
{
|
||||
EXPECT_EQ(m.type(), CV_32FC1);
|
||||
EXPECT_EQ(m.dims, 2);
|
||||
EXPECT_EQ(m.cols, 4);
|
||||
|
||||
std::vector<cv::Rect2d> boxes(m.rows);
|
||||
for (int i = 0; i < m.rows; ++i)
|
||||
{
|
||||
CV_Assert(m.row(i).isContinuous());
|
||||
const float* data = m.ptr<float>(i);
|
||||
double l = data[0], t = data[1], r = data[2], b = data[3];
|
||||
boxes[i] = cv::Rect2d(l, t, r - l, b - t);
|
||||
}
|
||||
return boxes;
|
||||
}
|
||||
|
||||
void normAssertDetections(
|
||||
const std::vector<int>& refClassIds,
|
||||
const std::vector<float>& refScores,
|
||||
const std::vector<cv::Rect2d>& refBoxes,
|
||||
const std::vector<int>& testClassIds,
|
||||
const std::vector<float>& testScores,
|
||||
const std::vector<cv::Rect2d>& testBoxes,
|
||||
const char *comment /*= ""*/, double confThreshold /*= 0.0*/,
|
||||
double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/)
|
||||
{
|
||||
std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
|
||||
for (int i = 0; i < testBoxes.size(); ++i)
|
||||
{
|
||||
double testScore = testScores[i];
|
||||
if (testScore < confThreshold)
|
||||
continue;
|
||||
|
||||
int testClassId = testClassIds[i];
|
||||
const cv::Rect2d& testBox = testBoxes[i];
|
||||
bool matched = false;
|
||||
for (int j = 0; j < refBoxes.size() && !matched; ++j)
|
||||
{
|
||||
if (!matchedRefBoxes[j] && testClassId == refClassIds[j] &&
|
||||
std::abs(testScore - refScores[j]) < scores_diff)
|
||||
{
|
||||
double interArea = (testBox & refBoxes[j]).area();
|
||||
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
|
||||
if (std::abs(iou - 1.0) < boxes_iou_diff)
|
||||
{
|
||||
matched = true;
|
||||
matchedRefBoxes[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!matched)
|
||||
std::cout << cv::format("Unmatched prediction: class %d score %f box ",
|
||||
testClassId, testScore) << testBox << std::endl;
|
||||
EXPECT_TRUE(matched) << comment;
|
||||
}
|
||||
|
||||
// Check unmatched reference detections.
|
||||
for (int i = 0; i < refBoxes.size(); ++i)
|
||||
{
|
||||
if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
|
||||
{
|
||||
std::cout << cv::format("Unmatched reference: class %d score %f box ",
|
||||
refClassIds[i], refScores[i]) << refBoxes[i] << std::endl;
|
||||
EXPECT_LE(refScores[i], confThreshold) << comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For SSD-based object detection networks which produce output of shape 1x1xNx7
|
||||
// where N is a number of detections and an every detection is represented by
|
||||
// a vector [batchId, classId, confidence, left, top, right, bottom].
|
||||
void normAssertDetections(
|
||||
cv::Mat ref, cv::Mat out, const char *comment /*= ""*/,
|
||||
double confThreshold /*= 0.0*/, double scores_diff /*= 1e-5*/,
|
||||
double boxes_iou_diff /*= 1e-4*/)
|
||||
{
|
||||
CV_Assert(ref.total() % 7 == 0);
|
||||
CV_Assert(out.total() % 7 == 0);
|
||||
ref = ref.reshape(1, ref.total() / 7);
|
||||
out = out.reshape(1, out.total() / 7);
|
||||
|
||||
cv::Mat refClassIds, testClassIds;
|
||||
ref.col(1).convertTo(refClassIds, CV_32SC1);
|
||||
out.col(1).convertTo(testClassIds, CV_32SC1);
|
||||
std::vector<float> refScores(ref.col(2)), testScores(out.col(2));
|
||||
std::vector<cv::Rect2d> refBoxes = matToBoxes(ref.colRange(3, 7));
|
||||
std::vector<cv::Rect2d> testBoxes = matToBoxes(out.colRange(3, 7));
|
||||
normAssertDetections(refClassIds, refScores, refBoxes, testClassIds, testScores,
|
||||
testBoxes, comment, confThreshold, scores_diff, boxes_iou_diff);
|
||||
}
|
||||
|
||||
bool readFileInMemory(const std::string& filename, std::string& content)
|
||||
{
|
||||
std::ios::openmode mode = std::ios::in | std::ios::binary;
|
||||
std::ifstream ifs(filename.c_str(), mode);
|
||||
if (!ifs.is_open())
|
||||
return false;
|
||||
|
||||
content.clear();
|
||||
|
||||
ifs.seekg(0, std::ios::end);
|
||||
content.reserve(ifs.tellg());
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
content.assign((std::istreambuf_iterator<char>(ifs)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
|
||||
bool withInferenceEngine /*= true*/,
|
||||
bool withHalide /*= false*/,
|
||||
bool withCpuOCV /*= true*/,
|
||||
bool withVkCom /*= true*/
|
||||
)
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
bool withVPU = validateVPUType();
|
||||
#endif
|
||||
|
||||
std::vector< tuple<Backend, Target> > targets;
|
||||
std::vector< Target > available;
|
||||
if (withHalide)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_HALIDE);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, *i));
|
||||
}
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (withInferenceEngine)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if (*i == DNN_TARGET_MYRIAD && !withVPU)
|
||||
continue;
|
||||
targets.push_back(make_tuple(DNN_BACKEND_INFERENCE_ENGINE, *i));
|
||||
}
|
||||
}
|
||||
#else
|
||||
CV_UNUSED(withInferenceEngine);
|
||||
#endif
|
||||
if (withVkCom)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_VKCOM);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
targets.push_back(make_tuple(DNN_BACKEND_VKCOM, *i));
|
||||
}
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_OPENCV);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if (!withCpuOCV && *i == DNN_TARGET_CPU)
|
||||
continue;
|
||||
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, *i));
|
||||
}
|
||||
}
|
||||
if (targets.empty()) // validate at least CPU mode
|
||||
targets.push_back(make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU));
|
||||
return testing::ValuesIn(targets);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
static std::string getTestInferenceEngineVPUType()
|
||||
{
|
||||
static std::string param_vpu_type = utils::getConfigurationParameterString("OPENCV_TEST_DNN_IE_VPU_TYPE", "");
|
||||
return param_vpu_type;
|
||||
}
|
||||
|
||||
static bool validateVPUType_()
|
||||
{
|
||||
std::string test_vpu_type = getTestInferenceEngineVPUType();
|
||||
if (test_vpu_type == "DISABLED" || test_vpu_type == "disabled")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Target> available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE);
|
||||
bool have_vpu_target = false;
|
||||
for (std::vector<Target>::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
{
|
||||
if (*i == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
have_vpu_target = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (test_vpu_type.empty())
|
||||
{
|
||||
if (have_vpu_target)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "OpenCV-DNN-Test: VPU type for testing is not specified via 'OPENCV_TEST_DNN_IE_VPU_TYPE' parameter.")
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!have_vpu_target)
|
||||
{
|
||||
CV_LOG_FATAL(NULL, "OpenCV-DNN-Test: 'OPENCV_TEST_DNN_IE_VPU_TYPE' parameter requires VPU of type = '" << test_vpu_type << "', but VPU is not detected. STOP.");
|
||||
exit(1);
|
||||
}
|
||||
std::string dnn_vpu_type = getInferenceEngineVPUType();
|
||||
if (dnn_vpu_type != test_vpu_type)
|
||||
{
|
||||
CV_LOG_FATAL(NULL, "OpenCV-DNN-Test: 'testing' and 'detected' VPU types mismatch: '" << test_vpu_type << "' vs '" << dnn_vpu_type << "'. STOP.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateVPUType()
|
||||
{
|
||||
static bool result = validateVPUType_();
|
||||
return result;
|
||||
}
|
||||
#endif // HAVE_INF_ENGINE
|
||||
|
||||
} // namespace
|
||||
@@ -267,6 +267,16 @@ public:
|
||||
|
||||
TEST_P(Test_Darknet_nets, YoloVoc)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("Test is disabled");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for MyriadX (need to update check function)");
|
||||
#endif
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
Mat ref = (Mat_<float>(6, 7) << 0, 6, 0.750469f, 0.577374f, 0.127391f, 0.902949f, 0.300809f, // a car
|
||||
0, 1, 0.780879f, 0.270762f, 0.264102f, 0.732475f, 0.745412f, // a bicycle
|
||||
@@ -282,15 +292,24 @@ TEST_P(Test_Darknet_nets, YoloVoc)
|
||||
std::string config_file = "yolo-voc.cfg";
|
||||
std::string weights_file = "yolo-voc.weights";
|
||||
|
||||
// batch size 1
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
// batch size 2
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, 0.24, nmsThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, TinyYoloVoc)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for MyriadX (need to update check function)");
|
||||
#endif
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
Mat ref = (Mat_<float>(4, 7) << 0, 6, 0.761967f, 0.579042f, 0.159161f, 0.894482f, 0.31994f, // a car
|
||||
0, 11, 0.780595f, 0.129696f, 0.386467f, 0.445275f, 0.920994f, // a dog
|
||||
@@ -303,18 +322,29 @@ TEST_P(Test_Darknet_nets, TinyYoloVoc)
|
||||
std::string config_file = "tiny-yolo-voc.cfg";
|
||||
std::string weights_file = "tiny-yolo-voc.weights";
|
||||
|
||||
// batch size 1
|
||||
{
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 2), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018040000
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_MYRIAD)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018040000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test with 'batch size 2' is disabled for Myriad target (fixed in 2018R5)");
|
||||
#endif
|
||||
// batch size 2
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Test_Darknet_nets, YOLOv3)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
|
||||
// batchId, classId, confidence, left, top, right, bottom
|
||||
Mat ref = (Mat_<float>(9, 7) << 0, 7, 0.952983f, 0.614622f, 0.150257f, 0.901369f, 0.289251f, // a truck
|
||||
0, 1, 0.987908f, 0.150913f, 0.221933f, 0.742255f, 0.74626f, // a bicycle
|
||||
@@ -332,13 +362,18 @@ TEST_P(Test_Darknet_nets, YOLOv3)
|
||||
std::string config_file = "yolov3.cfg";
|
||||
std::string weights_file = "yolov3.weights";
|
||||
|
||||
// batch size 1
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
|
||||
|
||||
if ((backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_MYRIAD) &&
|
||||
(backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_OPENCL))
|
||||
{
|
||||
// batch size 2
|
||||
SCOPED_TRACE("batch size 1");
|
||||
testDarknetModel(config_file, weights_file, ref.rowRange(0, 3), scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL)
|
||||
throw SkipTestException("Test with 'batch size 2' is disabled for DLIE/OpenCL target");
|
||||
#endif
|
||||
|
||||
{
|
||||
SCOPED_TRACE("batch size 2");
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2017-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
// This tests doesn't require any external data. They just compare outputs of
|
||||
@@ -158,15 +158,26 @@ TEST_P(Deconvolution, Accuracy)
|
||||
bool hasBias = get<6>(GetParam());
|
||||
Backend backendId = get<0>(get<7>(GetParam()));
|
||||
Target targetId = get<1>(get<7>(GetParam()));
|
||||
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && (targetId == DNN_TARGET_CPU || targetId == DNN_TARGET_MYRIAD) &&
|
||||
dilation.width == 2 && dilation.height == 2)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018040000
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU &&
|
||||
hasBias && group != 1)
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018040000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU
|
||||
&& hasBias && group != 1)
|
||||
throw SkipTestException("Test is disabled for OpenVINO 2018R4");
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
&& inChannels == 6 && outChannels == 4 && group == 1
|
||||
&& kernel == Size(1, 3) && pad == Size(1, 0)
|
||||
&& stride == Size(1, 1) && dilation == Size(1, 1))
|
||||
throw SkipTestException("Test is disabled");
|
||||
#endif
|
||||
|
||||
int sz[] = {inChannels, outChannels / group, kernel.height, kernel.width};
|
||||
Mat weights(4, &sz[0], CV_32F);
|
||||
randu(weights, -1.0f, 1.0f);
|
||||
@@ -228,6 +239,10 @@ TEST_P(LRN, Accuracy)
|
||||
Backend backendId = get<0>(get<5>(GetParam()));
|
||||
Target targetId = get<1>(get<5>(GetParam()));
|
||||
|
||||
if ((inSize.width == 5 || inSize.height == 5) && targetId == DNN_TARGET_MYRIAD &&
|
||||
nrmType == "ACROSS_CHANNELS")
|
||||
throw SkipTestException("This test case is disabled");
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("norm_region", nrmType);
|
||||
lp.set("local_size", localSize);
|
||||
@@ -266,10 +281,18 @@ TEST_P(AvePooling, Accuracy)
|
||||
Size stride = get<3>(GetParam());
|
||||
Backend backendId = get<0>(get<4>(GetParam()));
|
||||
Target targetId = get<1>(get<4>(GetParam()));
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE < 2018040000
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
&& kernel == Size(1, 1) && (stride == Size(1, 1) || stride == Size(2, 2)))
|
||||
throw SkipTestException("Test is disabled for MyriadX target");
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2018040000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD &&
|
||||
stride == Size(3, 2) && kernel == Size(3, 3) && outSize != Size(1, 1))
|
||||
throw SkipTestException("Test is enabled starts from OpenVINO 2018R4");
|
||||
throw SkipTestException("Test is fixed in OpenVINO 2018R4");
|
||||
#endif
|
||||
|
||||
const int inWidth = (outSize.width - 1) * stride.width + kernel.width;
|
||||
@@ -311,6 +334,32 @@ TEST_P(MaxPooling, Accuracy)
|
||||
Backend backendId = get<0>(get<5>(GetParam()));
|
||||
Target targetId = get<1>(get<5>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
|
||||
&& inSize == Size(7, 6) && kernel == Size(3, 2)
|
||||
&& (stride == Size(1, 1) || stride == Size(2, 2))
|
||||
&& (pad == Size(0, 1) || pad == Size(1, 1))
|
||||
)
|
||||
throw SkipTestException("Test is disabled in OpenVINO <= 2018R5");
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
|
||||
&& (kernel == Size(2, 2) || kernel == Size(3, 2))
|
||||
&& stride == Size(1, 1) && (pad == Size(0, 0) || pad == Size(0, 1))
|
||||
)
|
||||
throw SkipTestException("Problems with output dimension in OpenVINO 2018R5");
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
&& (stride == Size(1, 1) || stride == Size(2, 2))
|
||||
&& (pad == Size(0, 1) || pad == Size(1, 1))
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX target");
|
||||
#endif
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("pool", "max");
|
||||
lp.set("kernel_w", kernel.width);
|
||||
@@ -512,6 +561,12 @@ TEST_P(ReLU, Accuracy)
|
||||
float negativeSlope = get<0>(GetParam());
|
||||
Backend backendId = get<0>(get<1>(GetParam()));
|
||||
Target targetId = get<1>(get<1>(GetParam()));
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE
|
||||
&& negativeSlope < 0
|
||||
)
|
||||
throw SkipTestException("Test is disabled");
|
||||
#endif
|
||||
|
||||
LayerParams lp;
|
||||
lp.set("negative_slope", negativeSlope);
|
||||
@@ -534,6 +589,13 @@ TEST_P(NoParamActivation, Accuracy)
|
||||
LayerParams lp;
|
||||
lp.type = get<0>(GetParam());
|
||||
lp.name = "testLayer";
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE
|
||||
&& lp.type == "AbsVal"
|
||||
)
|
||||
throw SkipTestException("Test is disabled");
|
||||
#endif
|
||||
|
||||
testInPlaceActivation(lp, backendId, targetId);
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(Layer_Test_Halide, NoParamActivation, Combine(
|
||||
@@ -619,6 +681,20 @@ TEST_P(Concat, Accuracy)
|
||||
Backend backendId = get<0>(get<2>(GetParam()));
|
||||
Target targetId = get<1>(get<2>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD
|
||||
&& inSize == Vec3i(1, 4, 5) && numChannels == Vec3i(1, 6, 2)
|
||||
)
|
||||
throw SkipTestException("Test is disabled for Myriad target"); // crash
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU
|
||||
&& inSize == Vec3i(1, 4, 5) && numChannels == Vec3i(1, 6, 2)
|
||||
)
|
||||
throw SkipTestException("Test is disabled for DLIE/CPU target");
|
||||
#endif
|
||||
|
||||
Net net;
|
||||
|
||||
std::vector<int> convLayerIds;
|
||||
@@ -687,10 +763,15 @@ TEST_P(Eltwise, Accuracy)
|
||||
Backend backendId = get<0>(get<4>(GetParam()));
|
||||
Target targetId = get<1>(get<4>(GetParam()));
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE > 2018050000
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE &&
|
||||
(targetId == DNN_TARGET_OPENCL || targetId == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_MYRIAD &&
|
||||
inSize == Vec3i(1, 4, 5))
|
||||
throw SkipTestException("Test is disabled for Myriad target");
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && numConv > 1)
|
||||
throw SkipTestException("Test is disabled for DLIE backend");
|
||||
#endif
|
||||
|
||||
Net net;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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.
|
||||
//
|
||||
// Copyright (C) 2018, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
@@ -21,9 +21,18 @@ static void initDLDTDataPath()
|
||||
static bool initialized = false;
|
||||
if (!initialized)
|
||||
{
|
||||
#if INF_ENGINE_RELEASE <= 2018050000
|
||||
const char* dldtTestDataPath = getenv("INTEL_CVSDK_DIR");
|
||||
if (dldtTestDataPath)
|
||||
cvtest::addDataSearchPath(cv::utils::fs::join(dldtTestDataPath, "deployment_tools"));
|
||||
cvtest::addDataSearchPath(dldtTestDataPath);
|
||||
#else
|
||||
const char* omzDataPath = getenv("OPENCV_OPEN_MODEL_ZOO_DATA_PATH");
|
||||
if (omzDataPath)
|
||||
cvtest::addDataSearchPath(omzDataPath);
|
||||
const char* dnnDataPath = getenv("OPENCV_DNN_TEST_DATA_PATH");
|
||||
if (dnnDataPath)
|
||||
cvtest::addDataSearchPath(std::string(dnnDataPath) + "/omz_intel_models");
|
||||
#endif
|
||||
initialized = true;
|
||||
}
|
||||
#endif
|
||||
@@ -33,6 +42,76 @@ using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
using namespace InferenceEngine;
|
||||
|
||||
struct OpenVINOModelTestCaseInfo
|
||||
{
|
||||
const char* modelPathFP32;
|
||||
const char* modelPathFP16;
|
||||
};
|
||||
|
||||
static const std::map<std::string, OpenVINOModelTestCaseInfo>& getOpenVINOTestModels()
|
||||
{
|
||||
static std::map<std::string, OpenVINOModelTestCaseInfo> g_models {
|
||||
#if INF_ENGINE_RELEASE <= 2018050000
|
||||
{ "age-gender-recognition-retail-0013", {
|
||||
"deployment_tools/intel_models/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013",
|
||||
"deployment_tools/intel_models/age-gender-recognition-retail-0013/FP16/age-gender-recognition-retail-0013"
|
||||
}},
|
||||
{ "face-person-detection-retail-0002", {
|
||||
"deployment_tools/intel_models/face-person-detection-retail-0002/FP32/face-person-detection-retail-0002",
|
||||
"deployment_tools/intel_models/face-person-detection-retail-0002/FP16/face-person-detection-retail-0002"
|
||||
}},
|
||||
{ "head-pose-estimation-adas-0001", {
|
||||
"deployment_tools/intel_models/head-pose-estimation-adas-0001/FP32/head-pose-estimation-adas-0001",
|
||||
"deployment_tools/intel_models/head-pose-estimation-adas-0001/FP16/head-pose-estimation-adas-0001"
|
||||
}},
|
||||
{ "person-detection-retail-0002", {
|
||||
"deployment_tools/intel_models/person-detection-retail-0002/FP32/person-detection-retail-0002",
|
||||
"deployment_tools/intel_models/person-detection-retail-0002/FP16/person-detection-retail-0002"
|
||||
}},
|
||||
{ "vehicle-detection-adas-0002", {
|
||||
"deployment_tools/intel_models/vehicle-detection-adas-0002/FP32/vehicle-detection-adas-0002",
|
||||
"deployment_tools/intel_models/vehicle-detection-adas-0002/FP16/vehicle-detection-adas-0002"
|
||||
}}
|
||||
#else
|
||||
// layout is defined by open_model_zoo/model_downloader
|
||||
// Downloaded using these parameters for Open Model Zoo downloader (2019R1):
|
||||
// ./downloader.py -o ${OPENCV_DNN_TEST_DATA_PATH}/omz_intel_models --cache_dir ${OPENCV_DNN_TEST_DATA_PATH}/.omz_cache/ \
|
||||
// --name face-person-detection-retail-0002,face-person-detection-retail-0002-fp16,age-gender-recognition-retail-0013,age-gender-recognition-retail-0013-fp16,head-pose-estimation-adas-0001,head-pose-estimation-adas-0001-fp16,person-detection-retail-0002,person-detection-retail-0002-fp16,vehicle-detection-adas-0002,vehicle-detection-adas-0002-fp16
|
||||
{ "age-gender-recognition-retail-0013", {
|
||||
"Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013",
|
||||
"Retail/object_attributes/age_gender/dldt/age-gender-recognition-retail-0013-fp16"
|
||||
}},
|
||||
{ "face-person-detection-retail-0002", {
|
||||
"Retail/object_detection/face_pedestrian/rmnet-ssssd-2heads/0002/dldt/face-person-detection-retail-0002",
|
||||
"Retail/object_detection/face_pedestrian/rmnet-ssssd-2heads/0002/dldt/face-person-detection-retail-0002-fp16"
|
||||
}},
|
||||
{ "head-pose-estimation-adas-0001", {
|
||||
"Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001",
|
||||
"Transportation/object_attributes/headpose/vanilla_cnn/dldt/head-pose-estimation-adas-0001-fp16"
|
||||
}},
|
||||
{ "person-detection-retail-0002", {
|
||||
"Retail/object_detection/pedestrian/hypernet-rfcn/0026/dldt/person-detection-retail-0002",
|
||||
"Retail/object_detection/pedestrian/hypernet-rfcn/0026/dldt/person-detection-retail-0002-fp16"
|
||||
}},
|
||||
{ "vehicle-detection-adas-0002", {
|
||||
"Transportation/object_detection/vehicle/mobilenet-reduced-ssd/dldt/vehicle-detection-adas-0002",
|
||||
"Transportation/object_detection/vehicle/mobilenet-reduced-ssd/dldt/vehicle-detection-adas-0002-fp16"
|
||||
}}
|
||||
#endif
|
||||
};
|
||||
|
||||
return g_models;
|
||||
}
|
||||
|
||||
static const std::vector<std::string> getOpenVINOTestModelsList()
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
|
||||
for (const auto& it : models)
|
||||
result.push_back(it.first);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void genData(const std::vector<size_t>& dims, Mat& m, Blob::Ptr& dataPtr)
|
||||
{
|
||||
std::vector<int> reversedDims(dims.begin(), dims.end());
|
||||
@@ -93,6 +172,8 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
|
||||
continue;
|
||||
#ifdef _WIN32
|
||||
std::string libName = "cpu_extension" + suffixes[i] + ".dll";
|
||||
#elif defined(__APPLE__)
|
||||
std::string libName = "libcpu_extension" + suffixes[i] + ".dylib";
|
||||
#else
|
||||
std::string libName = "libcpu_extension" + suffixes[i] + ".so";
|
||||
#endif // _WIN32
|
||||
@@ -172,41 +253,23 @@ void runCV(Target target, const std::string& xmlPath, const std::string& binPath
|
||||
}
|
||||
}
|
||||
|
||||
typedef TestWithParam<tuple<Target, String> > DNNTestOpenVINO;
|
||||
typedef TestWithParam<tuple<Target, std::string> > DNNTestOpenVINO;
|
||||
TEST_P(DNNTestOpenVINO, models)
|
||||
{
|
||||
initDLDTDataPath();
|
||||
|
||||
Target target = (dnn::Target)(int)get<0>(GetParam());
|
||||
std::string modelName = get<1>(GetParam());
|
||||
bool isFP16 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD);
|
||||
|
||||
#ifdef INF_ENGINE_RELEASE
|
||||
#if INF_ENGINE_RELEASE <= 2018030000
|
||||
if (target == DNN_TARGET_MYRIAD && (modelName == "landmarks-regression-retail-0001" ||
|
||||
modelName == "semantic-segmentation-adas-0001" ||
|
||||
modelName == "face-reidentification-retail-0001"))
|
||||
throw SkipTestException("");
|
||||
#elif INF_ENGINE_RELEASE == 2018040000
|
||||
if (modelName == "single-image-super-resolution-0034" ||
|
||||
(target == DNN_TARGET_MYRIAD && (modelName == "license-plate-recognition-barrier-0001" ||
|
||||
modelName == "landmarks-regression-retail-0009" ||
|
||||
modelName == "semantic-segmentation-adas-0001")))
|
||||
throw SkipTestException("");
|
||||
#elif INF_ENGINE_RELEASE == 2018050000
|
||||
if (modelName == "single-image-super-resolution-0063" ||
|
||||
modelName == "single-image-super-resolution-1011" ||
|
||||
modelName == "single-image-super-resolution-1021" ||
|
||||
(target == DNN_TARGET_OPENCL_FP16 && modelName == "face-reidentification-retail-0095") ||
|
||||
(target == DNN_TARGET_MYRIAD && (modelName == "license-plate-recognition-barrier-0001" ||
|
||||
modelName == "semantic-segmentation-adas-0001")))
|
||||
throw SkipTestException("");
|
||||
#endif
|
||||
#endif
|
||||
const std::map<std::string, OpenVINOModelTestCaseInfo>& models = getOpenVINOTestModels();
|
||||
const auto it = models.find(modelName);
|
||||
ASSERT_TRUE(it != models.end()) << modelName;
|
||||
OpenVINOModelTestCaseInfo modelInfo = it->second;
|
||||
std::string modelPath = isFP16 ? modelInfo.modelPathFP16 : modelInfo.modelPathFP32;
|
||||
|
||||
std::string precision = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? "FP16" : "FP32";
|
||||
std::string prefix = utils::fs::join("intel_models",
|
||||
utils::fs::join(modelName,
|
||||
utils::fs::join(precision, modelName)));
|
||||
std::string xmlPath = findDataFile(prefix + ".xml");
|
||||
std::string binPath = findDataFile(prefix + ".bin");
|
||||
std::string xmlPath = findDataFile(modelPath + ".xml");
|
||||
std::string binPath = findDataFile(modelPath + ".bin");
|
||||
|
||||
std::map<std::string, cv::Mat> inputsMap;
|
||||
std::map<std::string, cv::Mat> ieOutputsMap, cvOutputsMap;
|
||||
@@ -226,37 +289,12 @@ TEST_P(DNNTestOpenVINO, models)
|
||||
}
|
||||
}
|
||||
|
||||
static testing::internal::ParamGenerator<String> intelModels()
|
||||
{
|
||||
initDLDTDataPath();
|
||||
std::vector<String> modelsNames;
|
||||
|
||||
std::string path;
|
||||
try
|
||||
{
|
||||
path = findDataDirectory("intel_models", false);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << "ERROR: Can't find OpenVINO models. Check INTEL_CVSDK_DIR environment variable (run setup.sh)" << std::endl;
|
||||
return ValuesIn(modelsNames); // empty list
|
||||
}
|
||||
|
||||
cv::utils::fs::glob_relative(path, "", modelsNames, false, true);
|
||||
|
||||
modelsNames.erase(
|
||||
std::remove_if(modelsNames.begin(), modelsNames.end(),
|
||||
[&](const String& dir){ return !utils::fs::isDirectory(utils::fs::join(path, dir)); }),
|
||||
modelsNames.end()
|
||||
);
|
||||
CV_Assert(!modelsNames.empty());
|
||||
|
||||
return ValuesIn(modelsNames);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/,
|
||||
DNNTestOpenVINO,
|
||||
Combine(testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE)), intelModels())
|
||||
Combine(testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE)),
|
||||
testing::ValuesIn(getOpenVINOTestModelsList())
|
||||
)
|
||||
);
|
||||
|
||||
}}
|
||||
|
||||
@@ -236,9 +236,9 @@ TEST_P(Test_Caffe_layers, Dropout)
|
||||
|
||||
TEST_P(Test_Caffe_layers, Concat)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE > 2018050000
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("");
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#endif
|
||||
testLayerUsingCaffeModels("layer_concat");
|
||||
testLayerUsingCaffeModels("layer_concat_optim", true, false);
|
||||
@@ -247,14 +247,19 @@ TEST_P(Test_Caffe_layers, Concat)
|
||||
|
||||
TEST_P(Test_Caffe_layers, Fused_Concat)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16 ||
|
||||
(INF_ENGINE_RELEASE < 2018040000 && target == DNN_TARGET_CPU))
|
||||
throw SkipTestException("");
|
||||
}
|
||||
throw SkipTestException("Test is disabled for DLIE due negative_slope parameter");
|
||||
#endif
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE
|
||||
&& (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16
|
||||
|| (INF_ENGINE_RELEASE < 2018040000 && target == DNN_TARGET_CPU))
|
||||
)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
|
||||
checkBackend();
|
||||
|
||||
// Test case
|
||||
@@ -312,7 +317,10 @@ TEST_P(Test_Caffe_layers, layer_prelu_fc)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("");
|
||||
testLayerUsingCaffeModels("layer_prelu_fc", true, false);
|
||||
// Reference output values are in range [-0.0001, 10.3906]
|
||||
double l1 = (target == DNN_TARGET_MYRIAD) ? 0.005 : 0.0;
|
||||
double lInf = (target == DNN_TARGET_MYRIAD) ? 0.021 : 0.0;
|
||||
testLayerUsingCaffeModels("layer_prelu_fc", true, false, l1, lInf);
|
||||
}
|
||||
|
||||
//template<typename XMat>
|
||||
@@ -358,6 +366,11 @@ TEST_P(Test_Caffe_layers, Reshape_Split_Slice)
|
||||
|
||||
TEST_P(Test_Caffe_layers, Conv_Elu)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE <= 2018050000
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("");
|
||||
#endif
|
||||
|
||||
Net net = readNetFromTensorflow(_tf("layer_elu_model.pb"));
|
||||
ASSERT_FALSE(net.empty());
|
||||
|
||||
@@ -938,7 +951,7 @@ TEST_P(Layer_Test_Convolution_DLDT, Accuracy)
|
||||
|
||||
Mat out = net.forward();
|
||||
|
||||
double l1 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 1.4e-3 : 1e-5;
|
||||
double l1 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 1.5e-3 : 1e-5;
|
||||
double lInf = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 1.8e-2 : 1e-4;
|
||||
normAssert(outDefault, out, "", l1, lInf);
|
||||
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
// 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.
|
||||
|
||||
// Copyright (C) 2018, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2018-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "npy_blob.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
template<typename TString>
|
||||
@@ -28,7 +27,8 @@ public:
|
||||
pb
|
||||
};
|
||||
|
||||
void testONNXModels(const String& basename, const Extension ext = npy, const double l1 = 0, const float lInf = 0)
|
||||
void testONNXModels(const String& basename, const Extension ext = npy,
|
||||
const double l1 = 0, const float lInf = 0, const bool useSoftmax = false)
|
||||
{
|
||||
String onnxmodel = _tf("models/" + basename + ".onnx");
|
||||
Mat inp, ref;
|
||||
@@ -51,7 +51,21 @@ public:
|
||||
net.setPreferableTarget(target);
|
||||
|
||||
net.setInput(inp);
|
||||
Mat out = net.forward();
|
||||
Mat out = net.forward("");
|
||||
|
||||
if (useSoftmax)
|
||||
{
|
||||
LayerParams lp;
|
||||
Net netSoftmax;
|
||||
netSoftmax.addLayerToPrev("softmaxLayer", "SoftMax", lp);
|
||||
netSoftmax.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
|
||||
netSoftmax.setInput(out);
|
||||
out = netSoftmax.forward();
|
||||
|
||||
netSoftmax.setInput(ref);
|
||||
ref = netSoftmax.forward();
|
||||
}
|
||||
normAssert(ref, out, "", l1 ? l1 : default_l1, lInf ? lInf : default_lInf);
|
||||
}
|
||||
};
|
||||
@@ -65,6 +79,18 @@ TEST_P(Test_ONNX_layers, MaxPooling)
|
||||
TEST_P(Test_ONNX_layers, Convolution)
|
||||
{
|
||||
testONNXModels("convolution");
|
||||
}
|
||||
|
||||
|
||||
TEST_P(Test_ONNX_layers, Two_convolution)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX"); // 2018R5+ is failed
|
||||
#endif
|
||||
// Reference output values are in range [-0.855, 0.611]
|
||||
testONNXModels("two_convolution");
|
||||
}
|
||||
|
||||
@@ -73,6 +99,7 @@ TEST_P(Test_ONNX_layers, Deconvolution)
|
||||
testONNXModels("deconvolution");
|
||||
testONNXModels("two_deconvolution");
|
||||
testONNXModels("deconvolution_group");
|
||||
testONNXModels("deconvolution_output_shape");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, Dropout)
|
||||
@@ -133,6 +160,11 @@ TEST_P(Test_ONNX_layers, Multiplication)
|
||||
|
||||
TEST_P(Test_ONNX_layers, Constant)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
|
||||
#endif
|
||||
testONNXModels("constant");
|
||||
}
|
||||
|
||||
@@ -243,7 +275,8 @@ TEST_P(Test_ONNX_nets, CaffeNet)
|
||||
|
||||
TEST_P(Test_ONNX_nets, RCNN_ILSVRC13)
|
||||
{
|
||||
testONNXModels("rcnn_ilsvrc13", pb);
|
||||
// Reference output values are in range [-4.992, -1.161]
|
||||
testONNXModels("rcnn_ilsvrc13", pb, 0.0045);
|
||||
}
|
||||
|
||||
#ifdef OPENCV_32BIT_CONFIGURATION
|
||||
@@ -252,21 +285,8 @@ TEST_P(Test_ONNX_nets, DISABLED_VGG16) // memory usage >2Gb
|
||||
TEST_P(Test_ONNX_nets, VGG16)
|
||||
#endif
|
||||
{
|
||||
double l1 = default_l1;
|
||||
double lInf = default_lInf;
|
||||
// output range: [-69; 72]
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) {
|
||||
l1 = 0.087;
|
||||
lInf = 0.585;
|
||||
}
|
||||
else if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL) {
|
||||
lInf = 1.2e-4;
|
||||
}
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
l1 = 0.131;
|
||||
#endif
|
||||
testONNXModels("vgg16", pb, l1, lInf);
|
||||
// output range: [-69; 72], after Softmax [0; 0.96]
|
||||
testONNXModels("vgg16", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
#ifdef OPENCV_32BIT_CONFIGURATION
|
||||
@@ -275,19 +295,9 @@ TEST_P(Test_ONNX_nets, DISABLED_VGG16_bn) // memory usage >2Gb
|
||||
TEST_P(Test_ONNX_nets, VGG16_bn)
|
||||
#endif
|
||||
{
|
||||
double l1 = default_l1;
|
||||
double lInf = default_lInf;
|
||||
// output range: [-16; 27]
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) {
|
||||
l1 = 0.0086;
|
||||
lInf = 0.037;
|
||||
}
|
||||
else if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
|
||||
(target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)) {
|
||||
l1 = 0.031;
|
||||
lInf = 0.2;
|
||||
}
|
||||
testONNXModels("vgg16-bn", pb, l1, lInf);
|
||||
// output range: [-16; 27], after Softmax [0; 0.67]
|
||||
const double lInf = (target == DNN_TARGET_MYRIAD) ? 0.038 : default_lInf;
|
||||
testONNXModels("vgg16-bn", pb, default_l1, lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, ZFNet)
|
||||
@@ -297,56 +307,62 @@ TEST_P(Test_ONNX_nets, ZFNet)
|
||||
|
||||
TEST_P(Test_ONNX_nets, ResNet18v1)
|
||||
{
|
||||
// output range: [-16; 22]
|
||||
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.022 : default_l1;
|
||||
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.12 : default_lInf;
|
||||
testONNXModels("resnet18v1", pb, l1, lInf);
|
||||
// output range: [-16; 22], after Softmax [0, 0.51]
|
||||
testONNXModels("resnet18v1", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, ResNet50v1)
|
||||
{
|
||||
// output range: [-67; 75]
|
||||
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.6 : 1.25e-5;
|
||||
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.51 : 1.2e-4;
|
||||
testONNXModels("resnet50v1", pb, l1, lInf);
|
||||
// output range: [-67; 75], after Softmax [0, 0.98]
|
||||
testONNXModels("resnet50v1", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, ResNet101_DUC_HDC)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_OPENCL
|
||||
|| target == DNN_TARGET_MYRIAD) {
|
||||
throw SkipTestException("");
|
||||
}
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE targets");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#endif
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_OPENCL)
|
||||
throw SkipTestException("Test is disabled for OpenCL targets");
|
||||
testONNXModels("resnet101_duc_hdc", pb);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, TinyYolov2)
|
||||
{
|
||||
if (cvtest::skipUnstableTests ||
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))) {
|
||||
throw SkipTestException("");
|
||||
}
|
||||
if (cvtest::skipUnstableTests)
|
||||
throw SkipTestException("Skip unstable test");
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE
|
||||
&& (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)
|
||||
)
|
||||
throw SkipTestException("Test is disabled for DLIE OpenCL targets");
|
||||
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
// output range: [-11; 8]
|
||||
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.017 : default_l1;
|
||||
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.14 : default_lInf;
|
||||
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.017 : default_l1;
|
||||
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.14 : default_lInf;
|
||||
testONNXModels("tiny_yolo2", pb, l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, CNN_MNIST)
|
||||
{
|
||||
// output range: [-1952; 6574]
|
||||
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 3.82 : 4.4e-4;
|
||||
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 13.5 : 2e-3;
|
||||
|
||||
testONNXModels("cnn_mnist", pb, l1, lInf);
|
||||
// output range: [-1952; 6574], after Softmax [0; 1]
|
||||
testONNXModels("cnn_mnist", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, MobileNet_v2)
|
||||
{
|
||||
// output range: [-166; 317]
|
||||
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.4 : 7e-5;
|
||||
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 2.87 : 5e-4;
|
||||
testONNXModels("mobilenetv2", pb, l1, lInf);
|
||||
// output range: [-166; 317], after Softmax [0; 1]
|
||||
testONNXModels("mobilenetv2", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, LResNet100E_IR)
|
||||
@@ -371,9 +387,17 @@ TEST_P(Test_ONNX_nets, LResNet100E_IR)
|
||||
|
||||
TEST_P(Test_ONNX_nets, Emotion_ferplus)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
|
||||
double l1 = default_l1;
|
||||
double lInf = default_lInf;
|
||||
// Output values are in range [-2.01109, 2.11111]
|
||||
|
||||
// Output values are in range [-2.011, 2.111]
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
l1 = 0.007;
|
||||
else if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
@@ -390,25 +414,20 @@ TEST_P(Test_ONNX_nets, Emotion_ferplus)
|
||||
|
||||
TEST_P(Test_ONNX_nets, Inception_v2)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("");
|
||||
|
||||
testONNXModels("inception_v2", pb);
|
||||
testONNXModels("inception_v2", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, DenseNet121)
|
||||
{
|
||||
// output range: [-87; 138]
|
||||
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.12 : 2.2e-5;
|
||||
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.74 : 1.23e-4;
|
||||
testONNXModels("densenet121", pb, l1, lInf);
|
||||
// output range: [-87; 138], after Softmax [0; 1]
|
||||
testONNXModels("densenet121", pb, default_l1, default_lInf, true);
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_nets, Inception_v1)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled for OpenVINO 2018R5");
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#endif
|
||||
testONNXModels("inception_v1", pb);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// 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.
|
||||
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2017-2019, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
/*
|
||||
@@ -133,12 +133,27 @@ TEST_P(Test_TensorFlow_layers, conv)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, padding)
|
||||
{
|
||||
runTensorFlowNet("padding_same");
|
||||
runTensorFlowNet("padding_valid");
|
||||
runTensorFlowNet("spatial_padding");
|
||||
runTensorFlowNet("keras_pad_concat");
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, padding_same)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
// Reference output values are in range [0.0006, 2.798]
|
||||
runTensorFlowNet("padding_same");
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, eltwise)
|
||||
{
|
||||
runTensorFlowNet("eltwise_add_mul");
|
||||
@@ -170,6 +185,16 @@ TEST_P(Test_TensorFlow_layers, batch_norm)
|
||||
runTensorFlowNet("mvn_batch_norm_1x1");
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, slim_batch_norm)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
// Output values range: [-40.0597, 207.827]
|
||||
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.041 : default_l1;
|
||||
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.33 : default_lInf;
|
||||
runTensorFlowNet("slim_batch_norm", false, l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, pooling)
|
||||
{
|
||||
runTensorFlowNet("max_pool_even");
|
||||
@@ -181,6 +206,13 @@ TEST_P(Test_TensorFlow_layers, pooling)
|
||||
// TODO: fix tests and replace to pooling
|
||||
TEST_P(Test_TensorFlow_layers, ave_pool_same)
|
||||
{
|
||||
// Reference output values are in range [-0.519531, 0.112976]
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
runTensorFlowNet("ave_pool_same");
|
||||
}
|
||||
|
||||
@@ -200,8 +232,11 @@ TEST_P(Test_TensorFlow_layers, matmul)
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||
throw SkipTestException("");
|
||||
runTensorFlowNet("matmul");
|
||||
runTensorFlowNet("nhwc_reshape_matmul");
|
||||
runTensorFlowNet("nhwc_transpose_reshape_matmul");
|
||||
// Reference output values are in range [-5.688, 4.484]
|
||||
double l1 = target == DNN_TARGET_MYRIAD ? 6.1e-3 : default_l1;
|
||||
runTensorFlowNet("nhwc_reshape_matmul", false, l1);
|
||||
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, reshape)
|
||||
@@ -216,26 +251,36 @@ TEST_P(Test_TensorFlow_layers, reshape)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, flatten)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
|
||||
(target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_2
|
||||
)
|
||||
throw SkipTestException("Test is disabled for Myriad2");
|
||||
#endif
|
||||
|
||||
runTensorFlowNet("flatten", true);
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, unfused_flatten)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
|
||||
(target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
|
||||
runTensorFlowNet("unfused_flatten");
|
||||
runTensorFlowNet("unfused_flatten_unknown_batch");
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, leaky_relu)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL)
|
||||
throw SkipTestException("");
|
||||
throw SkipTestException("Test is disabled for DLIE/OCL target (OpenVINO 2018R5)");
|
||||
#endif
|
||||
runTensorFlowNet("leaky_relu_order1");
|
||||
runTensorFlowNet("leaky_relu_order2");
|
||||
@@ -244,14 +289,30 @@ TEST_P(Test_TensorFlow_layers, leaky_relu)
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, l2_normalize)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
|
||||
runTensorFlowNet("l2_normalize");
|
||||
}
|
||||
|
||||
// TODO: fix it and add to l2_normalize
|
||||
TEST_P(Test_TensorFlow_layers, l2_normalize_3d)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE
|
||||
&& (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)
|
||||
)
|
||||
throw SkipTestException("Test is disabled for DLIE for OpenCL targets");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#endif
|
||||
|
||||
runTensorFlowNet("l2_normalize_3d");
|
||||
}
|
||||
|
||||
@@ -300,6 +361,13 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
|
||||
checkBackend();
|
||||
std::string proto = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pbtxt", false);
|
||||
std::string model = findDataFile("dnn/ssd_inception_v2_coco_2017_11_17.pb", false);
|
||||
@@ -320,6 +388,7 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
|
||||
0, 3, 0.75838411, 0.44668293, 0.45907149, 0.49459291, 0.52197015,
|
||||
0, 10, 0.95932811, 0.38349164, 0.32528657, 0.40387636, 0.39165527,
|
||||
0, 10, 0.93973452, 0.66561931, 0.37841269, 0.68074018, 0.42907384);
|
||||
|
||||
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0097 : default_l1;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.09 : default_lInf;
|
||||
normAssertDetections(ref, out, "", 0.5, scoreDiff, iouDiff);
|
||||
@@ -329,6 +398,13 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD)
|
||||
{
|
||||
checkBackend();
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
|
||||
std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false);
|
||||
std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt", false);
|
||||
|
||||
@@ -354,7 +430,7 @@ TEST_P(Test_TensorFlow_nets, Faster_RCNN)
|
||||
"faster_rcnn_resnet50_coco_2018_01_28"};
|
||||
|
||||
checkBackend();
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE) ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
|
||||
@@ -380,10 +456,11 @@ TEST_P(Test_TensorFlow_nets, Faster_RCNN)
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("Unstable test case");
|
||||
throw SkipTestException("Test is disabled for DLIE OpenCL targets in OpenVINO 2018R5");
|
||||
#endif
|
||||
|
||||
checkBackend();
|
||||
std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt", false);
|
||||
std::string model = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pb", false);
|
||||
@@ -399,9 +476,9 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
|
||||
net.setInput(blob);
|
||||
Mat out = net.forward();
|
||||
|
||||
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.011 : 1.1e-5;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.021 : default_lInf;
|
||||
normAssertDetections(ref, out, "", 0.4, scoreDiff, iouDiff);
|
||||
double scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.048 : 1.1e-5;
|
||||
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.058 : default_lInf;
|
||||
normAssertDetections(ref, out, "", 0.45, scoreDiff, iouDiff);
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
|
||||
@@ -444,7 +521,13 @@ TEST_P(Test_TensorFlow_nets, opencv_face_detector_uint8)
|
||||
// np.save('east_text_detection.geometry.npy', geometry)
|
||||
TEST_P(Test_TensorFlow_nets, EAST_text_detection)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#endif
|
||||
|
||||
checkBackend();
|
||||
|
||||
std::string netPath = findDataFile("dnn/frozen_east_text_detection.pb", false);
|
||||
std::string imgPath = findDataFile("cv/ximgproc/sources/08.png", false);
|
||||
std::string refScoresPath = findDataFile("dnn/east_text_detection.scores.npy", false);
|
||||
@@ -478,8 +561,8 @@ TEST_P(Test_TensorFlow_nets, EAST_text_detection)
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
lInf_scores = 0.214;
|
||||
l1_geometry = 0.47; lInf_geometry = 15.34;
|
||||
lInf_scores = 0.41;
|
||||
l1_geometry = 0.28; lInf_geometry = 5.94;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -493,17 +576,40 @@ INSTANTIATE_TEST_CASE_P(/**/, Test_TensorFlow_nets, dnnBackendsAndTargets());
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, fp16_weights)
|
||||
{
|
||||
const float l1 = 0.00071;
|
||||
const float lInf = 0.012;
|
||||
float l1 = 0.00078;
|
||||
float lInf = 0.012;
|
||||
runTensorFlowNet("fp16_single_conv", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_max_pool_odd_same", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_eltwise_add_mul", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_max_pool_even", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_padding_same", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_pad_and_concat", false, l1, lInf);
|
||||
runTensorFlowNet("fp16_padding_valid", false, l1, lInf);
|
||||
// Reference output values are in range [0.0889, 1.651]
|
||||
runTensorFlowNet("fp16_max_pool_even", false, (target == DNN_TARGET_MYRIAD) ? 0.003 : l1, lInf);
|
||||
if (target == DNN_TARGET_MYRIAD) {
|
||||
l1 = 0.0041;
|
||||
lInf = 0.024;
|
||||
}
|
||||
// Reference output values are in range [0, 10.75]
|
||||
runTensorFlowNet("fp16_deconvolution", false, l1, lInf);
|
||||
// Reference output values are in range [0.418, 2.297]
|
||||
runTensorFlowNet("fp16_max_pool_odd_valid", false, l1, lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, fp16_padding_same)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
throw SkipTestException("Test is disabled for DLIE");
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
|
||||
)
|
||||
throw SkipTestException("Test is disabled for MyriadX");
|
||||
#endif
|
||||
|
||||
// Reference output values are in range [-3.504, -0.002]
|
||||
runTensorFlowNet("fp16_padding_same", false, 6e-4, 4e-3);
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, defun)
|
||||
@@ -549,6 +655,7 @@ TEST_P(Test_TensorFlow_layers, slice)
|
||||
TEST_P(Test_TensorFlow_layers, softmax)
|
||||
{
|
||||
runTensorFlowNet("keras_softmax");
|
||||
runTensorFlowNet("slim_softmax");
|
||||
}
|
||||
|
||||
TEST_P(Test_TensorFlow_layers, relu6)
|
||||
|
||||
@@ -148,8 +148,8 @@ TEST_P(Test_Torch_layers, run_reshape_single_sample)
|
||||
{
|
||||
// Reference output values in range [14.4586, 18.4492].
|
||||
runTorchNet("net_reshape_single_sample", "", false, false, true,
|
||||
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.0073 : default_l1,
|
||||
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.025 : default_lInf);
|
||||
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.033 : default_l1,
|
||||
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.05 : default_lInf);
|
||||
}
|
||||
|
||||
TEST_P(Test_Torch_layers, run_linear)
|
||||
@@ -272,9 +272,9 @@ class Test_Torch_nets : public DNNTestLayer {};
|
||||
|
||||
TEST_P(Test_Torch_nets, OpenFace_accuracy)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("");
|
||||
throw SkipTestException("Test is disabled for Myriad targets");
|
||||
#endif
|
||||
checkBackend();
|
||||
|
||||
@@ -295,8 +295,12 @@ TEST_P(Test_Torch_nets, OpenFace_accuracy)
|
||||
net.setInput(inputBlob);
|
||||
Mat out = net.forward();
|
||||
|
||||
// Reference output values are in range [-0.17212, 0.263492]
|
||||
// on Myriad problem layer: l4_Pooling - does not use pads_begin
|
||||
float l1 = (target == DNN_TARGET_OPENCL_FP16) ? 4e-4 : 1e-5;
|
||||
float lInf = (target == DNN_TARGET_OPENCL_FP16) ? 1.5e-3 : 1e-3;
|
||||
Mat outRef = readTorchBlob(_tf("net_openface_output.dat"), true);
|
||||
normAssert(out, outRef, "", default_l1, default_lInf);
|
||||
normAssert(out, outRef, "", l1, lInf);
|
||||
}
|
||||
|
||||
static Mat getSegmMask(const Mat& scores)
|
||||
@@ -393,6 +397,12 @@ TEST_P(Test_Torch_nets, ENet_accuracy)
|
||||
// -model models/instance_norm/feathers.t7
|
||||
TEST_P(Test_Torch_nets, FastNeuralStyle_accuracy)
|
||||
{
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
throw SkipTestException("Test is disabled for OpenVINO <= 2018R5 + MyriadX target");
|
||||
#endif
|
||||
|
||||
checkBackend();
|
||||
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
|
||||
@@ -276,17 +276,15 @@ public:
|
||||
public:
|
||||
KMeansDistanceComputer(Distance _distance, const Matrix<ElementType>& _dataset,
|
||||
const int _branching, const int* _indices, const Matrix<double>& _dcenters, const size_t _veclen,
|
||||
int* _count, int* _belongs_to, std::vector<DistanceType>& _radiuses, bool& _converged)
|
||||
std::vector<int> &_new_centroids, std::vector<DistanceType> &_sq_dists)
|
||||
: distance(_distance)
|
||||
, dataset(_dataset)
|
||||
, branching(_branching)
|
||||
, indices(_indices)
|
||||
, dcenters(_dcenters)
|
||||
, veclen(_veclen)
|
||||
, count(_count)
|
||||
, belongs_to(_belongs_to)
|
||||
, radiuses(_radiuses)
|
||||
, converged(_converged)
|
||||
, new_centroids(_new_centroids)
|
||||
, sq_dists(_sq_dists)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -297,8 +295,8 @@ public:
|
||||
|
||||
for( int i = begin; i<end; ++i)
|
||||
{
|
||||
DistanceType sq_dist = distance(dataset[indices[i]], dcenters[0], veclen);
|
||||
int new_centroid = 0;
|
||||
DistanceType sq_dist(distance(dataset[indices[i]], dcenters[0], veclen));
|
||||
int new_centroid(0);
|
||||
for (int j=1; j<branching; ++j) {
|
||||
DistanceType new_sq_dist = distance(dataset[indices[i]], dcenters[j], veclen);
|
||||
if (sq_dist>new_sq_dist) {
|
||||
@@ -306,15 +304,8 @@ public:
|
||||
sq_dist = new_sq_dist;
|
||||
}
|
||||
}
|
||||
if (sq_dist > radiuses[new_centroid]) {
|
||||
radiuses[new_centroid] = sq_dist;
|
||||
}
|
||||
if (new_centroid != belongs_to[i]) {
|
||||
CV_XADD(&count[belongs_to[i]], -1);
|
||||
CV_XADD(&count[new_centroid], 1);
|
||||
belongs_to[i] = new_centroid;
|
||||
converged = false;
|
||||
}
|
||||
sq_dists[i] = sq_dist;
|
||||
new_centroids[i] = new_centroid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,10 +316,8 @@ public:
|
||||
const int* indices;
|
||||
const Matrix<double>& dcenters;
|
||||
const size_t veclen;
|
||||
int* count;
|
||||
int* belongs_to;
|
||||
std::vector<DistanceType>& radiuses;
|
||||
bool& converged;
|
||||
std::vector<int> &new_centroids;
|
||||
std::vector<DistanceType> &sq_dists;
|
||||
KMeansDistanceComputer& operator=( const KMeansDistanceComputer & ) { return *this; }
|
||||
};
|
||||
|
||||
@@ -796,10 +785,27 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> new_centroids(indices_length);
|
||||
std::vector<DistanceType> sq_dists(indices_length);
|
||||
|
||||
// reassign points to clusters
|
||||
KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, count, belongs_to, radiuses, converged);
|
||||
KMeansDistanceComputer invoker(distance_, dataset_, branching, indices, dcenters, veclen_, new_centroids, sq_dists);
|
||||
parallel_for_(cv::Range(0, (int)indices_length), invoker);
|
||||
|
||||
for (int i=0; i < (int)indices_length; ++i) {
|
||||
DistanceType sq_dist(sq_dists[i]);
|
||||
int new_centroid(new_centroids[i]);
|
||||
if (sq_dist > radiuses[new_centroid]) {
|
||||
radiuses[new_centroid] = sq_dist;
|
||||
}
|
||||
if (new_centroid != belongs_to[i]) {
|
||||
count[belongs_to[i]]--;
|
||||
count[new_centroid]++;
|
||||
belongs_to[i] = new_centroid;
|
||||
converged = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<branching; ++i) {
|
||||
// if one cluster converges to an empty cluster,
|
||||
// move an element into that cluster
|
||||
|
||||
@@ -328,7 +328,8 @@ namespace util
|
||||
util::type_list_index<T, Types...>::value;
|
||||
|
||||
if (v.index() == t_index)
|
||||
return reinterpret_cast<T&>(v.memory);
|
||||
return *(T*)(&v.memory); // workaround for ICC 2019
|
||||
// original code: return reinterpret_cast<T&>(v.memory);
|
||||
else
|
||||
throw_error(bad_variant_access());
|
||||
}
|
||||
@@ -340,7 +341,8 @@ namespace util
|
||||
util::type_list_index<T, Types...>::value;
|
||||
|
||||
if (v.index() == t_index)
|
||||
return reinterpret_cast<const T&>(v.memory);
|
||||
return *(const T*)(&v.memory); // workaround for ICC 2019
|
||||
// original code: return reinterpret_cast<const T&>(v.memory);
|
||||
else
|
||||
throw_error(bad_variant_access());
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "perf_precomp.hpp"
|
||||
#include "../perf_precomp.hpp"
|
||||
#include "gapi_core_perf_tests_inl.hpp"
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "perf_precomp.hpp"
|
||||
#include "../perf_precomp.hpp"
|
||||
#include "gapi_imgproc_perf_tests_inl.hpp"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "perf_precomp.hpp"
|
||||
#include "../perf_precomp.hpp"
|
||||
#include "../../test/common/gapi_tests_common.hpp"
|
||||
|
||||
namespace opencv_test
|
||||
|
||||
@@ -1399,6 +1399,20 @@ void GFluidBackendImpl::addBackendPasses(ade::ExecutionEngineSetupContext &ectx)
|
||||
// will be copied by views on each iteration and base our choice
|
||||
// on this criteria)
|
||||
auto readers = node->outNodes();
|
||||
|
||||
// There can be a situation when __internal__ nodes produced as part of some
|
||||
// operation are unused later in the graph:
|
||||
//
|
||||
// in -> OP1
|
||||
// |------> internal_1 // unused node
|
||||
// |------> internal_2 -> OP2
|
||||
// |------> out
|
||||
//
|
||||
// To allow graphs like the one above, skip nodes with empty outNodes()
|
||||
if (readers.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto &candidate = ade::util::find_if(readers, [&](ade::NodeHandle nh) {
|
||||
return fg.metadata(nh).contains<FluidUnit>() &&
|
||||
fg.metadata(nh).get<FluidUnit>().border_size == fd.border_size;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
// FIXME: move out from Common
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "../test_precomp.hpp"
|
||||
#include "opencv2/gapi/cpu/core.hpp"
|
||||
|
||||
#include <ade/util/algorithm.hpp>
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "../test_precomp.hpp"
|
||||
#include "gapi_core_tests_inl.hpp"
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "../test_precomp.hpp"
|
||||
#include "gapi_imgproc_tests_inl.hpp"
|
||||
|
||||
@@ -564,6 +564,7 @@ TEST_P(NV12toRGBTest, AccuracyTest)
|
||||
|
||||
// Additional mat for uv
|
||||
cv::Mat in_mat_uv(cv::Size(sz.width / 2, sz.height / 2), CV_8UC2);
|
||||
cv::randn(in_mat_uv, cv::Scalar::all(127), cv::Scalar::all(40.f));
|
||||
|
||||
cv::GComputation c(cv::GIn(in_y, in_uv), cv::GOut(out));
|
||||
c.apply(cv::gin(in_mat1, in_mat_uv), cv::gout(out_mat_gapi), std::move(compile_args));
|
||||
@@ -594,6 +595,7 @@ TEST_P(NV12toBGRTest, AccuracyTest)
|
||||
|
||||
// Additional mat for uv
|
||||
cv::Mat in_mat_uv(cv::Size(sz.width / 2, sz.height / 2), CV_8UC2);
|
||||
cv::randn(in_mat_uv, cv::Scalar::all(127), cv::Scalar::all(40.f));
|
||||
|
||||
cv::GComputation c(cv::GIn(in_y, in_uv), cv::GOut(out));
|
||||
c.apply(cv::gin(in_mat1, in_mat_uv), cv::gout(out_mat_gapi), std::move(compile_args));
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "../test_precomp.hpp"
|
||||
#include "gapi_operators_tests_inl.hpp"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "../test_precomp.hpp"
|
||||
#include "../common/gapi_operators_tests.hpp"
|
||||
|
||||
#define CORE_FLUID cv::gapi::core::fluid::kernels()
|
||||
|
||||
@@ -752,4 +752,19 @@ INSTANTIATE_TEST_CASE_P(Fluid, NV12RoiTest,
|
||||
,std::make_pair(cv::Size{1920, 1080}, cv::Rect{0, 710, 1920, 270})
|
||||
));
|
||||
|
||||
TEST(Fluid, UnusedNodeTest) {
|
||||
cv::GMat in;
|
||||
cv::GMat a, b, c, d;
|
||||
std::tie(a, b, c, d) = cv::gapi::split4(in);
|
||||
cv::GMat out = cv::gapi::merge3(a, b, c);
|
||||
|
||||
cv::Mat in_mat(cv::Size(8, 8), CV_8UC4);
|
||||
cv::Mat out_mat(cv::Size(8, 8), CV_8UC3);
|
||||
|
||||
cv::GComputation comp(cv::GIn(in), cv::GOut(out));
|
||||
|
||||
ASSERT_NO_THROW(comp.apply(cv::gin(in_mat), cv::gout(out_mat),
|
||||
cv::compile_args(cv::gapi::core::fluid::kernels())));
|
||||
}
|
||||
|
||||
} // namespace opencv_test
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "gapi_mock_kernels.hpp"
|
||||
#include "../test_precomp.hpp"
|
||||
#include "../gapi_mock_kernels.hpp"
|
||||
|
||||
#include "compiler/gmodel.hpp"
|
||||
#include "compiler/gcompiler.hpp"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "../test_precomp.hpp"
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "../test_precomp.hpp"
|
||||
|
||||
namespace opencv_test {
|
||||
// Tests on T/Kind matching ////////////////////////////////////////////////////
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user