1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-22 03:43:03 +04:00

Compare commits

...

50 Commits

Author SHA1 Message Date
Alexander Alekhin 4a7ca5a291 OpenCV version++ (3.4.7)
OpenCV 3.4.7
2019-07-25 19:01:19 +00:00
Alexander Alekhin 7295983964 Merge pull request #15139 from alalek:openvino_2019R2 2019-07-25 18:59:56 +00:00
Alexander Alekhin 39a6889767 Merge pull request #15118 from dkurt:fix_15106 2019-07-25 18:56:32 +00:00
Chip Kerchner 0db4fb1835 Merge pull request #15136 from ChipKerchner:dotProd_unroll
* Unroll multiply and add instructions in dotProd_32f - 35% faster.

* Eliminate unnecessary v_reduce_sum instructions.
2019-07-25 21:21:32 +03:00
Alexander Alekhin ac425f67e4 Merge pull request #15150 from alalek:fix_15124_15125 2019-07-25 18:19:04 +00:00
Dmitry Kurtaev a2125594ea Fix false positives of face detection network for large faces 2019-07-25 20:09:59 +03:00
Alexander Alekhin 416c693b3f dnn(test): OpenVINO 2019R2 2019-07-25 19:01:16 +03:00
Alexander Alekhin 321c74ccd6 objdetect: validate feature rectangle on reading 2019-07-25 18:58:53 +03:00
Alexander Alekhin 6158bd2afa Merge pull request #15103 from alalek:simd_intrinsics_in_user_code 2019-07-25 11:36:36 +00:00
Alexander Alekhin d2911a8d41 dnn: use OpenVINO 2019R2 defines 2019-07-24 21:37:03 +00:00
Hugo Lindström 2ee00e7f7d Merge pull request #15059 from hugolm84:improved-support-for-wince
* Improve support for Windows Embedded Compact

* Remove redundant set(WINCE true) and format CMake
2019-07-24 23:12:09 +03:00
Alexander Alekhin ad092bf1ce Merge pull request #15107 from dkurt:js_features2d_drawings 2019-07-21 17:57:19 +00:00
Alexander Alekhin 557990fdcf Merge pull request #15104 from alalek:videoio_fix_debug_message 2019-07-21 17:56:41 +00:00
Dmitry Kurtaev a66a1a24d7 Fix drawKeypoints and drawMatches for JS 2019-07-20 23:47:26 +03:00
Alexander Alekhin 099f4f9e7c Merge pull request #15093 from tomoaki0705:fixCudaLegacyRansac 2019-07-20 08:07:14 +00:00
Alexander Alekhin 8bac8b513c core: support SIMD intrinsics in user code 2019-07-19 20:33:32 +00:00
Lubov Batanina 781f4d439e Merge pull request #15032 from l-bat:reduce_mean
* Added support for the ONNX "ReduceMean" Layer. (as this is the same as the GlobalAveragePool)

* Add ReduceMean test

* Fix ONNX importer

* Fix ReduceMean

* Add assert

* Split test

* Fix split test
2019-07-19 19:18:34 +03:00
Alexander Alekhin a8a71eb200 Merge pull request #15092 from alalek:videoio_gstreamer_more_get_checks 2019-07-19 15:50:54 +00:00
Alexander Alekhin 61f589ddd0 videoio(gstreamer): more .get() checks 2019-07-19 13:16:58 +03:00
Tomoaki Teshima c6de84d868 cudalegacy: fix test failure of SolvePnPRansac
* use SOLVE_EPNP for the initial guess
2019-07-19 17:50:00 +09:00
Alexander Alekhin 228af2d617 videoio: fix debug message 2019-07-18 21:45:07 +00:00
Alexander Alekhin 002904e445 Merge pull request #15050 from alalek:core_fix_base64_packed_struct 2019-07-18 19:07:06 +00:00
Vitaly Tuzov e0f8bb83a6 Merge pull request #14994 from terfendail:wintr_undistort
WUI based implementation to initUndistortRectifyMap (#14994)

* Add initUndistortRectifyMap performance test

* Move cv namespace boundaries

* Add wide universal intrinsics based implementation to initUndistortRectifyMap

* Dispatch undistort
2019-07-18 19:32:51 +03:00
Lubov Batanina 12fdaf895e Merge pull request #15057 from l-bat:fix_vizualizer
* Fix dumpToFile

* Add test

* Fix test
2019-07-18 18:41:08 +03:00
Alexander Alekhin c12e26ff28 Merge pull request #15071 from l-bat:tf_split 2019-07-18 08:12:42 +00:00
Liubov Batanina 0d2bc7b5fd Fix TF Split layer 2019-07-17 15:50:50 +03:00
Alexander Alekhin e4e0bb533d Merge pull request #15052 from alalek:dnn_fix_required_data 2019-07-16 16:00:33 +00:00
Alexander Alekhin f5e01f7b49 Merge pull request #15037 from hugolm84:noop-noexcept-for-vs13 2019-07-16 13:28:15 +00:00
Chip Kerchner c9fcc12e3b Merge pull request #15048 from ChipKerchner:reduceStoreGatheringThreshold
* Reduce store gathering pressures - speeds thresholds by up to 20%

* Rename temporary histogram array and initialize so that MACOSX builder is happy
2019-07-16 16:10:49 +03:00
Alexander Alekhin 4ea8526e9f core(persistence): fix writeRaw() / readRaw() struct support
- writeRaw(): support structs
- readRaw(): 'len' is buffer limit in bytes (documentation is fixed)
2019-07-16 14:03:39 +03:00
Alexander Alekhin 5ccb2a4cbd dnn(test): fix required data 2019-07-16 07:53:50 +00:00
Alexander Alekhin c3b838b738 core(persistence): struct storage layout without alignment gaps 2019-07-15 21:37:20 +00:00
Alexander Alekhin 054c796213 Merge pull request #15026 from terfendail:gaussian_fix 2019-07-12 18:31:09 +00:00
Hugo Lindström 245c256b1c Support compiliation for <=VS13 2019-07-12 19:02:36 +02:00
Alexander Alekhin 6aa07cdc7e Merge pull request #15025 from alalek:issue_14281 2019-07-12 15:28:44 +00:00
Vitaly Tuzov 894ad33bf4 Fix pixel value evaluation overflow in bit-exact GaussianBlur implementation 2019-07-12 18:11:51 +03:00
Lubov Batanina 34f6b05467 Merge pull request #14996 from l-bat:ocv_deconv3d
* Support Deconvolution3D on IE backend

* Add test tag

* Fix tests
2019-07-12 15:51:44 +03:00
Alexander Alekhin 32c6e58bdb imgproc: fix unaligned memory access
may cause crashes on ARM platform
2019-07-11 20:49:47 +00:00
Lubov Batanina 8bcd7e122a Merge pull request #14842 from l-bat:ocv_conv3d
* Support Conv3D on OCV backend

* Add header

* Add perf tests

* Support pool3d

* Enable Resnet34_kinetics on OCV backend

* Add test

* Fix conv

* Optimize Conv2D
2019-07-11 20:13:52 +03:00
Alexander Alekhin 3c086fb2fe Merge pull request #15001 from antmicro:v4l2-y10-support 2019-07-09 14:34:11 +00:00
Alexander Alekhin 32b6ebb670 Merge pull request #14989 from alalek:issue_14978 2019-07-09 14:14:06 +00:00
Tomasz Gorochowik 4997a6bf06 V4L2: Add V4L2_PIX_FMT_Y10 (10 bit grey) support 2019-07-09 14:36:00 +02:00
Alexander Alekhin 1e9e2aa95c Merge pull request #14811 from jxu:ubuntu-doc-fix 2019-07-08 16:47:19 +00:00
jxu b9399a5df8 Fix python setup in ubuntu dependencies 2019-07-07 15:15:31 -04:00
Alexander Alekhin eedbd1ad59 imgcodecs: force reshaping of imdecode() input into a single row
OpenCV upstream stuff may reinterpret vector as column.
2019-07-06 10:11:29 +00:00
Alexander Alekhin 7589225fc0 Merge pull request #14981 from alalek:android_camera_use_calc_frame_size_method 2019-07-06 08:20:20 +00:00
Alexander Alekhin 39a975cb29 Merge pull request #14983 from tomoaki0705:fixOclCvtColorMRGBA 2019-07-05 09:31:08 +00:00
Tomoaki Teshima 594a95839c fix test failure of OCL_ImgProc/CvtColor8u.mRGBA2RGBA 2019-07-05 11:22:22 +09:00
Alexander Alekhin 3998b41d68 android: JavaCamera2View use calculateCameraFrameSize() method
from CameraBridgeViewBase (common base with JavaCameraView)
2019-07-04 21:43:09 +00:00
Diego 57fae4a6a1 Merge pull request #14858 from dvd42:instancenorm_onnx
Instancenorm onnx (#14858)

* Onnx unsupported operation handling

* instance norm implementation

* Revert "Onnx unsupported operation handling"

* instance norm layer test

* onnx instancenorm layer
2019-07-04 21:15:04 +03:00
74 changed files with 3790 additions and 869 deletions
+1 -1
View File
@@ -136,7 +136,7 @@ const char * ZEXPORT zError(err)
return ERR_MSG(err);
}
#if defined(_WIN32_WCE)
#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
/* The Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used.
+7 -5
View File
@@ -169,11 +169,13 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
# if defined(_WIN32_WCE)
# define fdopen(fd,mode) NULL /* No fdopen() */
# ifndef _PTRDIFF_T_DEFINED
typedef int ptrdiff_t;
# define _PTRDIFF_T_DEFINED
# endif
# if _WIN32_WCE < 0x800
# define fdopen(fd,mode) NULL /* No fdopen() */
# ifndef _PTRDIFF_T_DEFINED
typedef int ptrdiff_t;
# define _PTRDIFF_T_DEFINED
# endif
# endif
# else
# define fdopen(fd,type) _fdopen(fd,type)
# endif
+33 -29
View File
@@ -53,35 +53,6 @@ if(NOT DEFINED CMAKE_INSTALL_PREFIX)
endif()
endif()
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
set(WINRT TRUE)
endif()
if(WINRT)
add_definitions(-DWINRT -DNO_GETENV)
# Making definitions available to other configurations and
# to filter dependency restrictions at compile time.
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone)
set(WINRT_PHONE TRUE)
add_definitions(-DWINRT_PHONE)
elseif(CMAKE_SYSTEM_NAME MATCHES WindowsStore)
set(WINRT_STORE TRUE)
add_definitions(-DWINRT_STORE)
endif()
if(CMAKE_SYSTEM_VERSION MATCHES 10)
set(WINRT_10 TRUE)
add_definitions(-DWINRT_10)
elseif(CMAKE_SYSTEM_VERSION MATCHES 8.1)
set(WINRT_8_1 TRUE)
add_definitions(-DWINRT_8_1)
elseif(CMAKE_SYSTEM_VERSION MATCHES 8.0)
set(WINRT_8_0 TRUE)
add_definitions(-DWINRT_8_0)
endif()
endif()
if(POLICY CMP0026)
cmake_policy(SET CMP0026 NEW)
endif()
@@ -136,6 +107,39 @@ enable_testing()
project(OpenCV CXX C)
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
set(WINRT TRUE)
endif()
if(WINRT OR WINCE)
add_definitions(-DNO_GETENV)
endif()
if(WINRT)
add_definitions(-DWINRT)
# Making definitions available to other configurations and
# to filter dependency restrictions at compile time.
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone)
set(WINRT_PHONE TRUE)
add_definitions(-DWINRT_PHONE)
elseif(CMAKE_SYSTEM_NAME MATCHES WindowsStore)
set(WINRT_STORE TRUE)
add_definitions(-DWINRT_STORE)
endif()
if(CMAKE_SYSTEM_VERSION MATCHES 10)
set(WINRT_10 TRUE)
add_definitions(-DWINRT_10)
elseif(CMAKE_SYSTEM_VERSION MATCHES 8.1)
set(WINRT_8_1 TRUE)
add_definitions(-DWINRT_8_1)
elseif(CMAKE_SYSTEM_VERSION MATCHES 8.0)
set(WINRT_8_0 TRUE)
add_definitions(-DWINRT_8_0)
endif()
endif()
if(MSVC)
set(CMAKE_USE_RELATIVE_PATHS ON CACHE INTERNAL "" FORCE)
endif()
+2 -2
View File
@@ -87,9 +87,9 @@ endif()
if(INF_ENGINE_TARGET)
if(NOT INF_ENGINE_RELEASE)
message(WARNING "InferenceEngine version have not been set, 2019R1 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
message(WARNING "InferenceEngine version have not been set, 2019R2 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
endif()
set(INF_ENGINE_RELEASE "2019010000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
set(INF_ENGINE_RELEASE "2019020000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
)
@@ -62,8 +62,8 @@ We need **CMake** to configure the installation, **GCC** for compilation, **Pyth
```
sudo apt-get install cmake
sudo apt-get install python-devel numpy
sudo apt-get install gcc gcc-c++
sudo apt-get install python-dev python-numpy
sudo apt-get install gcc g++
```
Next we need **GTK** support for GUI features, Camera support (libv4l), Media Support
+1 -1
View File
@@ -627,7 +627,7 @@ Cv64suf;
\****************************************************************************************/
#ifndef CV_NOEXCEPT
# ifdef CV_CXX11
# if defined(CV_CXX11) && (!defined(_MSC_VER) || _MSC_VER > 1800) /* MSVC 2015 and above */
# define CV_NOEXCEPT noexcept
# endif
#endif
@@ -597,8 +597,8 @@ public:
Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array.
@param len Number of elements to read. If it is greater than number of remaining elements then all
of them will be read.
@param len Number of bytes to read (buffer size limit). If it is greater than number of
remaining elements then all of them will be read.
*/
void readRaw( const String& fmt, uchar* vec, size_t len ) const;
@@ -668,11 +668,12 @@ public:
Usually it is more convenient to use operator `>>` instead of this method.
@param fmt Specification of each array element. See @ref format_spec "format specification"
@param vec Pointer to the destination array.
@param maxCount Number of elements to read. If it is greater than number of remaining elements then
all of them will be read.
@param len Number of bytes to read (buffer size limit). If it is greater than number of
remaining elements then all of them will be read.
*/
FileNodeIterator& readRaw( const String& fmt, uchar* vec,
size_t maxCount=(size_t)INT_MAX );
size_t len=(size_t)INT_MAX );
struct SeqReader
{
@@ -0,0 +1,88 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_CORE_SIMD_INTRINSICS_HPP
#define OPENCV_CORE_SIMD_INTRINSICS_HPP
/**
Helper header to support SIMD intrinsics (universal intrinsics) in user code.
Intrinsics documentation: https://docs.opencv.org/3.4/df/d91/group__core__hal__intrin.html
Checks of target CPU instruction set based on compiler definitions don't work well enough.
More reliable solutions require utilization of configuration systems (like CMake).
So, probably you need to specify your own configuration.
You can do that via CMake in this way:
add_definitions(/DOPENCV_SIMD_CONFIG_HEADER=opencv_simd_config_custom.hpp)
or
add_definitions(/DOPENCV_SIMD_CONFIG_INCLUDE_DIR=1)
Additionally you may need to add include directory to your files:
include_directories("${CMAKE_CURRENT_LIST_DIR}/opencv_config_${MYTARGET}")
These files can be pre-generated for target configurations of your application
or generated by CMake on the fly (use CMAKE_BINARY_DIR for that).
Notes:
- H/W capability checks are still responsibility of your applcation
- runtime dispatching is not covered by this helper header
*/
#ifdef __OPENCV_BUILD
#error "Use core/hal/intrin.hpp during OpenCV build"
#endif
#ifdef OPENCV_HAL_INTRIN_HPP
#error "core/simd_intrinsics.hpp must be included before core/hal/intrin.hpp"
#endif
#include "opencv2/core/cvdef.h"
#include "opencv2/core/version.hpp"
#ifdef OPENCV_SIMD_CONFIG_HEADER
#include CVAUX_STR(OPENCV_SIMD_CONFIG_HEADER)
#elif defined(OPENCV_SIMD_CONFIG_INCLUDE_DIR)
#include "opencv_simd_config.hpp" // corresponding directory should be added via -I compiler parameter
#else // custom config headers
#if (!defined(CV_AVX_512F) || !CV_AVX_512F) && (defined(__AVX512__) || defined(__AVX512F__))
# include <immintrin.h>
# undef CV_AVX_512F
# define CV_AVX_512F 1
# ifndef OPENCV_SIMD_DONT_ASSUME_SKX // Skylake-X with AVX-512F/CD/BW/DQ/VL
# undef CV_AVX512_SKX
# define CV_AVX512_SKX 1
# undef CV_AVX_512CD
# define CV_AVX_512CD 1
# undef CV_AVX_512BW
# define CV_AVX_512BW 1
# undef CV_AVX_512DQ
# define CV_AVX_512DQ 1
# undef CV_AVX_512VL
# define CV_AVX_512VL 1
# endif
#endif // AVX512
// GCC/Clang: -mavx2
// MSVC: /arch:AVX2
#if defined __AVX2__
# include <immintrin.h>
# undef CV_AVX2
# define CV_AVX2 1
# if defined __F16C__
# undef CV_FP16
# define CV_FP16 1
# endif
#endif
#endif
// SSE / NEON / VSX is handled by cv_cpu_dispatch.h compatibility block
#include "cv_cpu_dispatch.h"
#include "hal/intrin.hpp"
#endif // OPENCV_CORE_SIMD_INTRINSICS_HPP
@@ -9,7 +9,7 @@
#ifndef OPENCV_HAVE_FILESYSTEM_SUPPORT
# if defined(__EMSCRIPTEN__) || defined(__native_client__)
/* no support */
# elif defined WINRT
# elif defined WINRT || defined _WIN32_WCE
/* not supported */
# elif defined __ANDROID__ || defined __linux__ || defined _WIN32 || \
defined __FreeBSD__ || defined __bsdi__ || defined __HAIKU__
@@ -8,7 +8,7 @@
#define CV_VERSION_MAJOR 3
#define CV_VERSION_MINOR 4
#define CV_VERSION_REVISION 7
#define CV_VERSION_STATUS "-pre"
#define CV_VERSION_STATUS ""
#define CVAUX_STR_EXP(__A) #__A
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
+3 -3
View File
@@ -57,7 +57,7 @@ namespace
struct DIR
{
#ifdef WINRT
#if defined(WINRT) || defined(_WIN32_WCE)
WIN32_FIND_DATAW data;
#else
WIN32_FIND_DATAA data;
@@ -78,7 +78,7 @@ namespace
{
DIR* dir = new DIR;
dir->ent.d_name = 0;
#ifdef WINRT
#if defined(WINRT) || defined(_WIN32_WCE)
cv::String full_path = cv::String(path) + "\\*";
wchar_t wfull_path[MAX_PATH];
size_t copied = mbstowcs(wfull_path, full_path.c_str(), MAX_PATH);
@@ -100,7 +100,7 @@ namespace
dirent* readdir(DIR* dir)
{
#ifdef WINRT
#if defined(WINRT) || defined(_WIN32_WCE)
if (dir->ent.d_name != 0)
{
if (::FindNextFileW(dir->handle, &dir->data) != TRUE)
+22 -1
View File
@@ -2511,6 +2511,27 @@ double dotProd_32f(const float* src1, const float* src2, int len)
int j = 0;
int cWidth = v_float32::nlanes;
#if CV_ENABLE_UNROLLED
v_float32 v_sum1 = vx_setzero_f32();
v_float32 v_sum2 = vx_setzero_f32();
v_float32 v_sum3 = vx_setzero_f32();
for (; j <= blockSize - (cWidth * 4); j += (cWidth * 4))
{
v_sum = v_muladd(vx_load(src1 + j),
vx_load(src2 + j), v_sum);
v_sum1 = v_muladd(vx_load(src1 + j + cWidth),
vx_load(src2 + j + cWidth), v_sum1);
v_sum2 = v_muladd(vx_load(src1 + j + (cWidth * 2)),
vx_load(src2 + j + (cWidth * 2)), v_sum2);
v_sum3 = v_muladd(vx_load(src1 + j + (cWidth * 3)),
vx_load(src2 + j + (cWidth * 3)), v_sum3);
}
v_sum += v_sum1 + v_sum2 + v_sum3;
#endif
for (; j <= blockSize - cWidth; j += cWidth)
v_sum = v_muladd(vx_load(src1 + j), vx_load(src2 + j), v_sum);
@@ -2532,4 +2553,4 @@ double dotProd_64f(const double* src1, const double* src2, int len)
#endif
CV_CPU_OPTIMIZATION_NAMESPACE_END
} // namespace
} // namespace
+1 -1
View File
@@ -1722,7 +1722,7 @@ static bool parseOpenCLDeviceConfiguration(const std::string& configurationStr,
return true;
}
#ifdef WINRT
#if defined WINRT || defined _WIN32_WCE
static cl_device_id selectOpenCLDevice()
{
return NULL;
+1 -1
View File
@@ -145,7 +145,7 @@ CvGenericHash* cvCreateMap( int flags, int header_size, int elem_size, CvMemStor
return map;
}
void icvParseError( CvFileStorage* fs, const char* func_name,
void icvParseError(const CvFileStorage* fs, const char* func_name,
const char* err_msg, const char* source_file, int source_line )
{
cv::String msg = cv::format("%s(%d): %s", fs->filename, fs->lineno, err_msg);
+2 -2
View File
@@ -55,7 +55,7 @@ size_t base64_decode_buffer_size(size_t cnt, char const * src, bool is_end_with
size_t base64_decode_buffer_size(size_t cnt, uchar const * src, bool is_end_with_zero = true);
std::string make_base64_header(const char * dt);
bool read_base64_header(std::vector<char> const & header, std::string & dt);
void make_seq(void * binary_data, int elem_cnt, const char * dt, CvSeq & seq);
void make_seq(::CvFileStorage* fs, const uchar* binary_data, size_t elem_cnt, const char * dt, CvSeq & seq);
void cvWriteRawDataBase64(::CvFileStorage* fs, const void* _data, int len, const char* dt);
class Base64ContextEmitter;
@@ -262,7 +262,7 @@ void icvFSCreateCollection( CvFileStorage* fs, int tag, CvFileNode* collection )
char* icvFSResizeWriteBuffer( CvFileStorage* fs, char* ptr, int len );
int icvCalcStructSize( const char* dt, int initial_size );
int icvCalcElemSize( const char* dt, int initial_size );
void CV_NORETURN icvParseError( CvFileStorage* fs, const char* func_name, const char* err_msg, const char* source_file, int source_line );
void CV_NORETURN icvParseError(const CvFileStorage* fs, const char* func_name, const char* err_msg, const char* source_file, int source_line);
char* icvEncodeFormat( int elem_type, char* dt );
int icvDecodeFormat( const char* dt, int* fmt_pairs, int max_len );
int icvDecodeSimpleFormat( const char* dt );
+50 -20
View File
@@ -5,6 +5,8 @@
#include "precomp.hpp"
#include "persistence.hpp"
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/core/utils/configuration.private.hpp>
namespace base64 {
@@ -555,7 +557,7 @@ public:
CV_Assert(len > 0);
/* calc step and to_binary_funcs */
make_to_binary_funcs(dt);
step_packed = make_to_binary_funcs(dt);
end = beg;
cur = beg;
@@ -570,10 +572,10 @@ public:
for (size_t i = 0U, n = to_binary_funcs.size(); i < n; i++) {
elem_to_binary_t & pack = to_binary_funcs[i];
pack.func(cur + pack.offset, dst + pack.offset);
pack.func(cur + pack.offset, dst + pack.offset_packed);
}
cur += step;
dst += step;
dst += step_packed;
return *this;
}
@@ -588,14 +590,16 @@ private:
struct elem_to_binary_t
{
size_t offset;
size_t offset_packed;
to_binary_t func;
};
private:
void make_to_binary_funcs(const std::string &dt)
size_t make_to_binary_funcs(const std::string &dt)
{
size_t cnt = 0;
size_t offset = 0;
size_t offset_packed = 0;
char type = '\0';
std::istringstream iss(dt);
@@ -646,11 +650,15 @@ private:
pack.offset = offset;
offset += size;
pack.offset_packed = offset_packed;
offset_packed += size;
to_binary_funcs.push_back(pack);
}
}
CV_Assert(iss.eof());
return offset_packed;
}
private:
@@ -659,27 +667,26 @@ private:
const uchar * end;
size_t step;
size_t step_packed;
std::vector<elem_to_binary_t> to_binary_funcs;
};
class BinaryToCvSeqConvertor
{
public:
BinaryToCvSeqConvertor(const void* src, int len, const char* dt)
: cur(reinterpret_cast<const uchar *>(src))
, beg(reinterpret_cast<const uchar *>(src))
, end(reinterpret_cast<const uchar *>(src))
BinaryToCvSeqConvertor(CvFileStorage* fs, const uchar* src, size_t total_byte_size, const char* dt)
: cur(src)
, end(src + total_byte_size)
{
CV_Assert(src);
CV_Assert(dt);
CV_Assert(len >= 0);
CV_Assert(total_byte_size > 0);
/* calc binary_to_funcs */
make_funcs(dt);
step = make_funcs(dt); // calc binary_to_funcs
functor_iter = binary_to_funcs.begin();
step = ::icvCalcStructSize(dt, 0);
end = beg + step * static_cast<size_t>(len);
if (total_byte_size % step != 0)
CV_PARSE_ERROR("Total byte size not match elememt size");
}
inline BinaryToCvSeqConvertor & operator >> (CvFileNode & dst)
@@ -699,7 +706,7 @@ public:
double d;
} buffer; /* for GCC -Wstrict-aliasing */
std::memset(buffer.mem, 0, sizeof(buffer));
functor_iter->func(cur + functor_iter->offset, buffer.mem);
functor_iter->func(cur + functor_iter->offset_packed, buffer.mem);
/* set node::data */
switch (functor_iter->cv_type)
@@ -746,16 +753,17 @@ private:
struct binary_to_filenode_t
{
size_t cv_type;
size_t offset;
size_t offset_packed;
binary_to_t func;
};
private:
void make_funcs(const char* dt)
size_t make_funcs(const char* dt)
{
size_t cnt = 0;
char type = '\0';
size_t offset = 0;
size_t offset_packed = 0;
std::istringstream iss(dt);
while (!iss.eof()) {
@@ -803,9 +811,28 @@ private:
}; // need a better way for outputting error.
offset = static_cast<size_t>(cvAlign(static_cast<int>(offset), static_cast<int>(size)));
pack.offset = offset;
if (offset != offset_packed)
{
static bool skip_message = cv::utils::getConfigurationParameterBool("OPENCV_PERSISTENCE_SKIP_PACKED_STRUCT_WARNING",
#ifdef _DEBUG
false
#else
true
#endif
);
if (!skip_message)
{
CV_LOG_WARNING(NULL, "Binary converter: struct storage layout has been changed in OpenCV 3.4.7. Alignment gaps has been removed from the storage containers. "
"Details: https://github.com/opencv/opencv/pull/15050"
);
skip_message = true;
}
}
offset += size;
pack.offset_packed = offset_packed;
offset_packed += size;
/* set type */
switch (type)
{
@@ -827,12 +854,13 @@ private:
CV_Assert(iss.eof());
CV_Assert(binary_to_funcs.size());
return offset_packed;
}
private:
const uchar * cur;
const uchar * beg;
const uchar * end;
size_t step;
@@ -889,11 +917,13 @@ void Base64Writer::check_dt(const char* dt)
}
void make_seq(void * binary, int elem_cnt, const char * dt, ::CvSeq & seq)
void make_seq(CvFileStorage* fs, const uchar* binary, size_t total_byte_size, const char * dt, ::CvSeq & seq)
{
if (total_byte_size == 0)
return;
::CvFileNode node;
node.info = 0;
BinaryToCvSeqConvertor convertor(binary, elem_cnt, dt);
BinaryToCvSeqConvertor convertor(fs, binary, total_byte_size, dt);
while (convertor) {
convertor >> node;
cvSeqPush(&seq, &node);
+23 -27
View File
@@ -11,21 +11,6 @@
namespace cv
{
static void getElemSize( const String& fmt, size_t& elemSize, size_t& cn )
{
const char* dt = fmt.c_str();
cn = 1;
if( cv_isdigit(dt[0]) )
{
cn = dt[0] - '0';
dt++;
}
char c = dt[0];
elemSize = cn*(c == 'u' || c == 'c' ? sizeof(uchar) : c == 'w' || c == 's' ? sizeof(ushort) :
c == 'i' ? sizeof(int) : c == 'f' ? sizeof(float) : c == 'd' ? sizeof(double) :
c == 'r' ? sizeof(void*) : (size_t)0);
}
FileStorage::FileStorage()
{
state = UNDEFINED;
@@ -164,8 +149,8 @@ void FileStorage::writeRaw( const String& fmt, const uchar* vec, size_t len )
{
if( !isOpened() )
return;
size_t elemSize, cn;
getElemSize( fmt, elemSize, cn );
CV_Assert(!fmt.empty());
size_t elemSize = ::icvCalcStructSize(fmt.c_str(), 0);
CV_Assert( len % elemSize == 0 );
cvWriteRawData( fs, vec, (int)(len/elemSize), fmt.c_str());
}
@@ -412,19 +397,30 @@ FileNodeIterator& FileNodeIterator::operator -= (int ofs)
}
FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, uchar* vec, size_t maxCount )
FileNodeIterator& FileNodeIterator::readRaw(const String& fmt, uchar* vec, size_t len)
{
if( fs && container && remaining > 0 )
CV_Assert(!fmt.empty());
if( fs && container && remaining > 0 && len > 0)
{
size_t elem_size, cn;
getElemSize( fmt, elem_size, cn );
CV_Assert( elem_size > 0 );
size_t count = std::min(remaining, maxCount);
if( reader.seq )
if (reader.seq)
{
cvReadRawDataSlice( fs, (CvSeqReader*)&reader, (int)count, vec, fmt.c_str() );
remaining -= count*cn;
size_t step = ::icvCalcStructSize(fmt.c_str(), 0);
if (len % step && len != (size_t)INT_MAX) // TODO remove compatibility hack
{
CV_PARSE_ERROR("readRaw: total byte size not match elememt size");
}
size_t maxCount = len / step;
int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2] = {};
int fmt_pair_count = icvDecodeFormat(fmt.c_str(), fmt_pairs, CV_FS_MAX_FMT_PAIRS);
int vecElems = 0;
for (int k = 0; k < fmt_pair_count; k++)
{
vecElems += fmt_pairs[k*2];
}
CV_Assert(vecElems > 0);
size_t count = std::min((size_t)remaining, (size_t)maxCount * vecElems);
cvReadRawDataSlice(fs, (CvSeqReader*)&reader, (int)count, vec, fmt.c_str());
remaining -= count;
}
else
{
+1 -7
View File
@@ -259,15 +259,9 @@ static char* icvJSONParseValue( CvFileStorage* fs, char* ptr, CvFileNode* node )
parser.flush();
}
/* save as CvSeq */
int elem_size = ::icvCalcStructSize(dt.c_str(), 0);
if (total_byte_size % elem_size != 0)
CV_PARSE_ERROR("Byte size not match elememt size");
int elem_cnt = total_byte_size / elem_size;
/* after icvFSCreateCollection, node->tag == struct_flags */
icvFSCreateCollection(fs, CV_NODE_FLOW | CV_NODE_SEQ, node);
base64::make_seq(binary_buffer.data(), elem_cnt, dt.c_str(), *node->data.seq);
base64::make_seq(fs, binary_buffer.data(), total_byte_size, dt.c_str(), *node->data.seq);
}
else
{
+1 -7
View File
@@ -167,17 +167,11 @@ static char* icvXMLParseBase64(CvFileStorage* fs, char* ptr, CvFileNode * node)
parser.flush();
}
/* save as CvSeq */
int elem_size = ::icvCalcStructSize(dt.c_str(), 0);
if (total_byte_size % elem_size != 0)
CV_PARSE_ERROR("data size not matches elememt size");
int elem_cnt = total_byte_size / elem_size;
node->tag = CV_NODE_NONE;
int struct_flags = CV_NODE_SEQ;
/* after icvFSCreateCollection, node->tag == struct_flags */
icvFSCreateCollection(fs, struct_flags, node);
base64::make_seq(binary_buffer.data(), elem_cnt, dt.c_str(), *node->data.seq);
base64::make_seq(fs, binary_buffer.data(), total_byte_size, dt.c_str(), *node->data.seq);
if (fs->dummy_eof) {
/* end of file */
+1 -7
View File
@@ -130,17 +130,11 @@ static char* icvYMLParseBase64(CvFileStorage* fs, char* ptr, int indent, CvFileN
parser.flush();
}
/* save as CvSeq */
int elem_size = ::icvCalcStructSize(dt.c_str(), 0);
if (total_byte_size % elem_size != 0)
CV_PARSE_ERROR("Byte size not match elememt size");
int elem_cnt = total_byte_size / elem_size;
node->tag = CV_NODE_NONE;
int struct_flags = CV_NODE_FLOW | CV_NODE_SEQ;
/* after icvFSCreateCollection, node->tag == struct_flags */
icvFSCreateCollection(fs, struct_flags, node);
base64::make_seq(binary_buffer.data(), elem_cnt, dt.c_str(), *node->data.seq);
base64::make_seq(fs, binary_buffer.data(), total_byte_size, dt.c_str(), *node->data.seq);
if (fs->dummy_eof) {
/* end of file */
+19 -5
View File
@@ -378,7 +378,7 @@ struct HWFeatures
void initialize(void)
{
#ifndef WINRT
#ifndef NO_GETENV
if (getenv("OPENCV_DUMP_CONFIG"))
{
fprintf(stderr, "\nOpenCV build configuration is:\n%s\n",
@@ -614,10 +614,10 @@ struct HWFeatures
{
bool dump = true;
const char* disabled_features =
#ifndef WINRT
getenv("OPENCV_CPU_DISABLE");
#else
#ifdef NO_GETENV
NULL;
#else
getenv("OPENCV_CPU_DISABLE");
#endif
if (disabled_features && disabled_features[0] != 0)
{
@@ -892,7 +892,7 @@ String format( const char* fmt, ... )
String tempfile( const char* suffix )
{
String fname;
#ifndef WINRT
#ifndef NO_GETENV
const char *temp_dir = getenv("OPENCV_TEMP_PATH");
#endif
@@ -913,6 +913,20 @@ String tempfile( const char* suffix )
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
fname = String(aname);
RoUninitialize();
#elif defined(_WIN32_WCE)
const auto kMaxPathSize = MAX_PATH+1;
wchar_t temp_dir[kMaxPathSize] = {0};
wchar_t temp_file[kMaxPathSize] = {0};
::GetTempPathW(kMaxPathSize, temp_dir);
if(0 != ::GetTempFileNameW(temp_dir, L"ocv", 0, temp_file)) {
DeleteFileW(temp_file);
char aname[MAX_PATH];
size_t copied = wcstombs(aname, temp_file, MAX_PATH);
CV_Assert((copied != MAX_PATH) && (copied != (size_t)-1));
fname = String(aname);
}
#else
char temp_dir2[MAX_PATH] = { 0 };
char temp_file[MAX_PATH] = { 0 };
+88 -42
View File
@@ -659,38 +659,29 @@ struct data_t
}
};
TEST(Core_InputOutput, filestorage_base64_basic)
static void test_filestorage_basic(int write_flags, const char* suffix_name, bool testReadWrite, bool useMemory = false)
{
const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
std::string basename = (test_info == 0)
? "filestorage_base64_valid_call"
: (std::string(test_info->test_case_name()) + "--" + test_info->name());
CV_Assert(test_info);
std::string name = (std::string(test_info->test_case_name()) + "--" + test_info->name() + suffix_name);
if (!testReadWrite)
name = string(cvtest::TS::ptr()->get_data_path()) + "io/" + name;
char const * filenames[] = {
"core_io_base64_basic_test.yml",
"core_io_base64_basic_test.xml",
"core_io_base64_basic_test.json",
0
};
for (char const ** ptr = filenames; *ptr; ptr++)
{
char const * suffix_name = *ptr;
std::string name = basename + '_' + suffix_name;
const size_t rawdata_N = 40;
std::vector<data_t> rawdata;
cv::Mat _em_out, _em_in;
cv::Mat _2d_out, _2d_in;
cv::Mat _nd_out, _nd_in;
cv::Mat _rd_out(64, 64, CV_64FC1), _rd_in;
cv::Mat _rd_out(8, 16, CV_64FC1), _rd_in;
bool no_type_id = true;
{ /* init */
/* a normal mat */
_2d_out = cv::Mat(100, 100, CV_8UC3, cvScalar(1U, 2U, 127U));
_2d_out = cv::Mat(10, 20, CV_8UC3, cvScalar(1U, 2U, 127U));
for (int i = 0; i < _2d_out.rows; ++i)
for (int j = 0; j < _2d_out.cols; ++j)
_2d_out.at<cv::Vec3b>(i, j)[1] = (i + j) % 256;
@@ -709,7 +700,7 @@ TEST(Core_InputOutput, filestorage_base64_basic)
cv::randu(_rd_out, cv::Scalar(0.0), cv::Scalar(1.0));
/* raw data */
for (int i = 0; i < 1000; i++) {
for (int i = 0; i < (int)rawdata_N; i++) {
data_t tmp;
tmp.u1 = 1;
tmp.u2 = 2;
@@ -722,24 +713,41 @@ TEST(Core_InputOutput, filestorage_base64_basic)
rawdata.push_back(tmp);
}
}
{ /* write */
cv::FileStorage fs(name, cv::FileStorage::WRITE_BASE64);
#ifdef GENERATE_TEST_DATA
#else
if (testReadWrite || useMemory)
#endif
{
cv::FileStorage fs(name, write_flags + (useMemory ? cv::FileStorage::MEMORY : 0));
fs << "normal_2d_mat" << _2d_out;
fs << "normal_nd_mat" << _nd_out;
fs << "empty_2d_mat" << _em_out;
fs << "random_mat" << _rd_out;
cvStartWriteStruct( *fs, "rawdata", CV_NODE_SEQ | CV_NODE_FLOW, "binary" );
for (int i = 0; i < 10; i++)
cvWriteRawDataBase64(*fs, rawdata.data() + i * 100, 100, data_t::signature());
cvEndWriteStruct( *fs );
fs << "rawdata" << "[:";
for (int i = 0; i < (int)rawdata_N/10; i++)
fs.writeRaw(data_t::signature(), (const uchar*)&rawdata[i * 10], sizeof(data_t) * 10);
fs << "]";
fs.release();
size_t sz = 0;
if (useMemory)
{
name = fs.releaseAndGetString();
sz = name.size();
}
else
{
fs.release();
std::ifstream f(name.c_str(), std::ios::in|std::ios::binary);
f.seekg(0, std::fstream::end);
sz = (size_t)f.tellg();
f.close();
}
std::cout << "Storage size: " << sz << std::endl;
EXPECT_LE(sz, (size_t)6000);
}
{ /* read */
cv::FileStorage fs(name, cv::FileStorage::READ);
cv::FileStorage fs(name, cv::FileStorage::READ + (useMemory ? cv::FileStorage::MEMORY : 0));
/* mat */
fs["empty_2d_mat"] >> _em_in;
@@ -754,14 +762,14 @@ TEST(Core_InputOutput, filestorage_base64_basic)
no_type_id = false;
/* raw data */
std::vector<data_t>(1000).swap(rawdata);
cvReadRawData(*fs, fs["rawdata"].node, rawdata.data(), data_t::signature());
std::vector<data_t>(rawdata_N).swap(rawdata);
fs["rawdata"].readRaw(data_t::signature(), (uchar*)&rawdata[0], rawdata.size() * sizeof(data_t));
fs.release();
}
int errors = 0;
for (int i = 0; i < 1000; i++)
for (int i = 0; i < (int)rawdata_N; i++)
{
EXPECT_EQ((int)rawdata[i].u1, 1);
EXPECT_EQ((int)rawdata[i].u2, 2);
@@ -815,18 +823,54 @@ TEST(Core_InputOutput, filestorage_base64_basic)
EXPECT_EQ(_nd_in.cols , _nd_out.cols);
EXPECT_EQ(_nd_in.dims , _nd_out.dims);
EXPECT_EQ(_nd_in.depth(), _nd_out.depth());
EXPECT_EQ(cv::countNonZero(cv::mean(_nd_in != _nd_out)), 0);
EXPECT_EQ(0, cv::norm(_nd_in, _nd_out, NORM_INF));
EXPECT_EQ(_rd_in.rows , _rd_out.rows);
EXPECT_EQ(_rd_in.cols , _rd_out.cols);
EXPECT_EQ(_rd_in.dims , _rd_out.dims);
EXPECT_EQ(_rd_in.depth(), _rd_out.depth());
EXPECT_EQ(cv::countNonZero(cv::mean(_rd_in != _rd_out)), 0);
remove(name.c_str());
EXPECT_EQ(0, cv::norm(_rd_in, _rd_out, NORM_INF));
}
}
TEST(Core_InputOutput, filestorage_base64_basic_read_XML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", false);
}
TEST(Core_InputOutput, filestorage_base64_basic_read_YAML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", false);
}
TEST(Core_InputOutput, filestorage_base64_basic_read_JSON)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", false);
}
TEST(Core_InputOutput, filestorage_base64_basic_rw_XML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", true);
}
TEST(Core_InputOutput, filestorage_base64_basic_rw_YAML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", true);
}
TEST(Core_InputOutput, filestorage_base64_basic_rw_JSON)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", true);
}
TEST(Core_InputOutput, filestorage_base64_basic_memory_XML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".xml", true, true);
}
TEST(Core_InputOutput, filestorage_base64_basic_memory_YAML)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".yml", true, true);
}
TEST(Core_InputOutput, filestorage_base64_basic_memory_JSON)
{
test_filestorage_basic(cv::FileStorage::WRITE_BASE64, ".json", true, true);
}
TEST(Core_InputOutput, filestorage_base64_valid_call)
{
const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();
@@ -856,10 +900,12 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
std::vector<int> rawdata(10, static_cast<int>(0x00010203));
cv::String str_out = "test_string";
for (char const ** ptr = filenames; *ptr; ptr++)
for (int n = 0; n < 6; n++)
{
char const * suffix_name = *ptr;
char const* suffix_name = filenames[n];
SCOPED_TRACE(suffix_name);
std::string name = basename + '_' + suffix_name;
std::string file_name = basename + '_' + real_name[n];
EXPECT_NO_THROW(
{
@@ -877,9 +923,9 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
});
{
cv::FileStorage fs(name, cv::FileStorage::READ);
cv::FileStorage fs(file_name, cv::FileStorage::READ);
std::vector<int> data_in(rawdata.size());
fs["manydata"][0].readRaw("i", (uchar *)data_in.data(), data_in.size());
fs["manydata"][0].readRaw("i", (uchar *)data_in.data(), data_in.size() * sizeof(data_in[0]));
EXPECT_TRUE(fs["manydata"][0].isSeq());
EXPECT_TRUE(std::equal(rawdata.begin(), rawdata.end(), data_in.begin()));
cv::String str_in;
@@ -905,19 +951,19 @@ TEST(Core_InputOutput, filestorage_base64_valid_call)
});
{
cv::FileStorage fs(name, cv::FileStorage::READ);
cv::FileStorage fs(file_name, cv::FileStorage::READ);
cv::String str_in;
fs["manydata"][0] >> str_in;
EXPECT_TRUE(fs["manydata"][0].isString());
EXPECT_EQ(str_in, str_out);
std::vector<int> data_in(rawdata.size());
fs["manydata"][1].readRaw("i", (uchar *)data_in.data(), data_in.size());
fs["manydata"][1].readRaw("i", (uchar *)data_in.data(), data_in.size() * sizeof(data_in[0]));
EXPECT_TRUE(fs["manydata"][1].isSeq());
EXPECT_TRUE(std::equal(rawdata.begin(), rawdata.end(), data_in.begin()));
fs.release();
}
remove((basename + '_' + real_name[ptr - filenames]).c_str());
EXPECT_EQ(0, remove(file_name.c_str()));
}
}
+1 -1
View File
@@ -181,7 +181,7 @@ namespace
image_subset(0, i) = image->at<Point2f>(subset_indices[i]);
}
solvePnP(object_subset, image_subset, *camera_mat, *dist_coef, rot_vec, transl_vec);
solvePnP(object_subset, image_subset, *camera_mat, *dist_coef, rot_vec, transl_vec, false, SOLVEPNP_EPNP);
// Remember translation vector
Mat transl_vec_ = transl_vectors.colRange(iter * 3, (iter + 1) * 3);
@@ -366,6 +366,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
*/
std::vector<std::vector<Range> > sliceRanges;
int axis;
int num_split;
static Ptr<SliceLayer> create(const LayerParams &params);
};
+1 -1
View File
@@ -387,7 +387,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN
/** @brief Dump net to String
* @returns String with structure, hyperparameters, backend, target and fusion
* To see correct backend, target and fusion run after forward().
* Call method after setInput(). To see correct backend, target and fusion run after forward().
*/
CV_WRAP String dump();
/** @brief Dump net structure, hyperparameters, backend, target and fusion to dot file
+182
View File
@@ -0,0 +1,182 @@
// 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 <opencv2/dnn/shape_utils.hpp>
namespace opencv_test {
struct Conv3DParam_t {
int kernel[3];
struct BlobShape { int dims[5]; } shapeIn;
int outCN;
int groups;
int stride[3];
int dilation[3];
int pad[6];
const char* padMode;
bool hasBias;
double declared_flops;
};
// Details: #12142
static const Conv3DParam_t testConvolution3DConfigs[] = {
{{3, 3, 3}, {{1, 6, 10, 38, 50}}, 6, 1, {1, 1, 1}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "VALID", true, 26956800.},
{{3, 3, 3}, {{1, 2, 19, 19, 19}}, 2, 2, {2, 2, 2}, {1, 1, 1}, {1, 1, 1, 1, 1, 1}, "", true, 218000.},
{{3, 3, 3}, {{1, 2, 25, 19, 19}}, 2, 2, {1, 2, 2}, {1, 1, 1}, {2, 2, 2, 2, 2, 2}, "SAME", false, 545000.},
{{3, 3, 3}, {{1, 11, 9, 150, 200}}, 11, 1, {1, 1, 1}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "VALID", true, 1342562760.},
{{3, 3, 3}, {{1, 10, 98, 10, 10}}, 10, 1, {1, 1, 1}, {1, 1, 1}, {1, 0, 1, 1, 0,1}, "SAME", false, 53018000.},
{{5, 5, 5}, {{1, 6, 19, 19, 19}}, 6, 2, {1, 1, 1}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "", false, 30395250.},
{{5, 5, 5}, {{1, 4, 50, 19, 19}}, 4, 1, {2, 2, 2}, {1, 1, 1}, {1, 1, 1, 1, 1, 1}, "VALID", false, 5893888.},
{{5, 5, 5}, {{1, 3, 75, 75, 100}}, 3, 1, {1, 1, 1}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "SAME", true, 1267312500.},
{{5, 5, 5}, {{1, 2, 21, 75, 100}}, 2, 1, {1, 1, 1}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "", true, 116103744.},
{{5, 5, 5}, {{1, 4, 40, 75, 75}}, 4, 1, {2, 2, 2}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "", false, 93405312.},
{{7, 7, 7}, {{1, 6, 15, 19, 19}}, 6, 1, {2, 1, 1}, {1, 1, 1}, {3, 3, 3, 3, 3, 3}, "SAME", true, 71339376.},
{{7, 7, 7}, {{1, 2, 38, 38, 38}}, 2, 1, {1, 2, 1}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "", false, 44990464.},
{{1, 1, 1}, {{1, 4, 9, 10, 10}}, 4, 1, {1, 1, 2}, {1, 1, 1}, {1, 1, 1, 1, 1, 1}, "VALID", false, 16200.},
{{3, 1, 4}, {{1, 14, 5, 10, 10}}, 14, 1, {1, 1, 1}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "SAME", false, 2359000.},
{{1, 1, 1}, {{1, 8, 1, 10, 10}}, 8, 8, {1, 1, 1}, {1, 1, 1}, {1, 1, 1, 1, 1, 1}, "", true, 58752.},
{{3, 4, 2}, {{1, 4, 8, 10, 10}}, 4, 4, {1, 2, 1}, {1, 1, 1}, {0, 0, 0, 0, 0, 0}, "", true, 166752.}
};
struct Conv3DParamID
{
enum {
CONV_0 = 0,
CONV_100 = 16,
CONV_LAST = sizeof(testConvolution3DConfigs) / sizeof(testConvolution3DConfigs[0])
};
int val_; \
Conv3DParamID(int val = 0) : val_(val) {}
operator int() const { return val_; }
static ::testing::internal::ParamGenerator<Conv3DParamID> all()
{
#if 0
enum { NUM = (int)CONV_LAST };
#else
enum { NUM = (int)CONV_100 };
#endif
Conv3DParamID v_[NUM]; for (int i = 0; i < NUM; ++i) { v_[i] = Conv3DParamID(i); } // reduce generated code size
return ::testing::ValuesIn(v_, v_ + NUM);
}
}; \
static inline void PrintTo(const Conv3DParamID& v, std::ostream* os)
{
CV_Assert((int)v >= 0); CV_Assert((int)v < Conv3DParamID::CONV_LAST);
const Conv3DParam_t& p = testConvolution3DConfigs[(int)v];
*os << "GFLOPS=" << cv::format("%.3f", p.declared_flops * 1e-9)
<< ", K=[" << p.kernel[0] << " x " << p.kernel[1] << " x " << p.kernel[2] << "]"
<< ", IN={" << p.shapeIn.dims[0] << ", " << p.shapeIn.dims[1] << ", " << p.shapeIn.dims[2] << ", " << p.shapeIn.dims[3] << ", " << p.shapeIn.dims[4] << "}"
<< ", OCN=" << p.outCN;
if (p.groups > 1)
*os << ", G=" << p.groups;
if (p.stride[0] * p.stride[1] * p.stride[2] != 1)
*os << ", S=[" << p.stride[0] << " x " << p.stride[1] << " x " << p.stride[2] << "]";
if (p.dilation[0] * p.dilation[1] * p.dilation[2] != 1)
*os << ", D=[" << p.dilation[0] << " x " << p.dilation[1] << " x " << p.dilation[2] << "]";
if (p.pad[0] != 0 && p.pad[1] != 0 && p.pad[2] != 0 &&
p.pad[3] != 0 && p.pad[4] != 0 && p.pad[5] != 0)
*os << ", P=(" << p.pad[0] << ", " << p.pad[3] << ") x ("
<< p.pad[1] << ", " << p.pad[4] << ") x ("
<< p.pad[2] << ", " << p.pad[5] << ")";
if (!((std::string)p.padMode).empty())
*os << ", PM=" << ((std::string)p.padMode);
if (p.hasBias)
*os << ", BIAS";
}
typedef tuple<Conv3DParamID, tuple<Backend, Target> > Conv3DTestParam_t;
typedef TestBaseWithParam<Conv3DTestParam_t> Conv3D;
PERF_TEST_P_(Conv3D, conv3d)
{
int test_id = (int)get<0>(GetParam());
ASSERT_GE(test_id, 0); ASSERT_LT(test_id, Conv3DParamID::CONV_LAST);
const Conv3DParam_t& params = testConvolution3DConfigs[test_id];
double declared_flops = params.declared_flops;
DictValue kernel = DictValue::arrayInt(&params.kernel[0], 3);
DictValue stride = DictValue::arrayInt(&params.stride[0], 3);
DictValue pad = DictValue::arrayInt(&params.pad[0], 6);
DictValue dilation = DictValue::arrayInt(&params.dilation[0], 3);
MatShape inputShape = MatShape(params.shapeIn.dims, params.shapeIn.dims + 5);
int outChannels = params.outCN;
int groups = params.groups;
std::string padMode(params.padMode);
bool hasBias = params.hasBias;
Backend backendId = get<0>(get<1>(GetParam()));
Target targetId = get<1>(get<1>(GetParam()));
if (targetId != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
int inChannels = inputShape[1];
int sz[] = {outChannels, inChannels / groups, params.kernel[0], params.kernel[1], params.kernel[2]};
Mat weights(5, &sz[0], CV_32F);
randu(weights, -1.0f, 1.0f);
LayerParams lp;
lp.set("kernel_size", kernel);
lp.set("pad", pad);
if (!padMode.empty())
lp.set("pad_mode", padMode);
lp.set("stride", stride);
lp.set("dilation", dilation);
lp.set("num_output", outChannels);
lp.set("group", groups);
lp.set("bias_term", hasBias);
lp.type = "Convolution";
lp.name = "testLayer";
lp.blobs.push_back(weights);
if (hasBias)
{
Mat bias(1, outChannels, CV_32F);
randu(bias, -1.0f, 1.0f);
lp.blobs.push_back(bias);
}
int inpSz[] = {1, inChannels, inputShape[2], inputShape[3], inputShape[4]};
Mat input(5, &inpSz[0], CV_32F);
randu(input, -1.0f, 1.0f);
Net net;
net.addLayerToPrev(lp.name, lp.type, lp);
net.setInput(input);
net.setPreferableBackend(backendId);
net.setPreferableTarget(targetId);
Mat output = net.forward();
MatShape netInputShape = shape(input);
size_t weightsMemory = 0, blobsMemory = 0;
net.getMemoryConsumption(netInputShape, weightsMemory, blobsMemory);
int64 flops = net.getFLOPS(netInputShape);
CV_Assert(flops > 0);
std::cout
<< "IN=" << divUp(input.total() * input.elemSize(), 1u<<10) << " Kb " << netInputShape
<< " OUT=" << divUp(output.total() * output.elemSize(), 1u<<10) << " Kb " << shape(output)
<< " Weights(parameters): " << divUp(weightsMemory, 1u<<10) << " Kb"
<< " MFLOPS=" << flops * 1e-6 << std::endl;
TEST_CYCLE()
{
Mat res = net.forward();
}
EXPECT_NEAR(flops, declared_flops, declared_flops * 1e-6);
SANITY_CHECK_NOTHING();
}
INSTANTIATE_TEST_CASE_P(/**/, Conv3D, Combine(
Conv3DParamID::all(),
dnnBackendsAndTargets(false, false) // defined in ../test/test_common.hpp
));
} // namespace
+13
View File
@@ -142,6 +142,8 @@ PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "ssd_mobilenet_v1_coco_2017_11_17.pbtxt", "",
Mat(cv::Size(300, 300), CV_32FC3));
}
@@ -150,6 +152,8 @@ PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
processNet("dnn/ssd_mobilenet_v2_coco_2018_03_29.pb", "ssd_mobilenet_v2_coco_2018_03_29.pbtxt", "",
Mat(cv::Size(300, 300), CV_32FC3));
}
@@ -190,6 +194,11 @@ PERF_TEST_P_(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
throw SkipTestException("Test is disabled for MyriadX");
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is disabled for Myriad in OpenVINO 2019R2");
#endif
processNet("dnn/ssd_inception_v2_coco_2017_11_17.pb", "ssd_inception_v2_coco_2017_11_17.pbtxt", "",
Mat(cv::Size(300, 300), CV_32FC3));
}
@@ -223,6 +232,10 @@ PERF_TEST_P_(DNNTestNetwork, Inception_v2_Faster_RCNN)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019010000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled in OpenVINO 2019R1");
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
throw SkipTestException("Test is disabled in OpenVINO 2019R2");
#endif
if (backend == DNN_BACKEND_HALIDE ||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU) ||
+11 -1
View File
@@ -2170,7 +2170,10 @@ struct Net::Impl
if (isAsync)
CV_Error(Error::StsNotImplemented, "Default implementation fallbacks in asynchronous mode");
CV_Assert(layer->supportBackend(DNN_BACKEND_OPENCV));
if (!layer->supportBackend(DNN_BACKEND_OPENCV))
CV_Error(Error::StsNotImplemented, format("Layer \"%s\" of type \"%s\" unsupported on OpenCV backend",
ld.name.c_str(), ld.type.c_str()));
if (preferableBackend == DNN_BACKEND_OPENCV && IS_DNN_OPENCL_TARGET(preferableTarget))
{
std::vector<UMat> umat_inputBlobs = OpenCLBackendWrapper::getUMatVector(ld.inputBlobsWrappers);
@@ -2903,6 +2906,13 @@ String parseLayerParams(const String& name, const LayerParams& lp) {
String Net::dump()
{
CV_Assert(!empty());
if (impl->netInputLayer->inputsData.empty())
CV_Error(Error::StsError, "Requested set input");
if (!impl->netWasAllocated)
impl->setUpNet();
std::ostringstream out;
std::map<int, LayerData>& map = impl->layers;
int prefBackend = impl->preferableBackend;
+234 -102
View File
@@ -47,6 +47,7 @@
#include "opencv2/core/hal/hal.hpp"
#include "opencv2/core/hal/intrin.hpp"
#include <iostream>
#include <numeric>
#ifdef HAVE_OPENCL
#include "opencl_kernels_dnn.hpp"
@@ -66,7 +67,7 @@ public:
BaseConvolutionLayerImpl(const LayerParams &params)
{
setParamsFrom(params);
getConvolutionKernelParams(params, kernel_size, pads_begin, pads_end, strides, dilations, padMode);
getConvolutionKernelParams(params, kernel_size, pads_begin, pads_end, strides, dilations, padMode, adjust_pads);
numOutput = params.get<int>("num_output");
int ngroups = params.get<int>("group", 1);
@@ -82,14 +83,14 @@ public:
pad = Size(pads_begin[1], pads_begin[0]);
dilation = Size(dilations[1], dilations[0]);
adjust_pads.push_back(params.get<int>("adj_h", 0));
adjust_pads.push_back(params.get<int>("adj_w", 0));
adjustPad.height = adjust_pads[0];
adjustPad.width = adjust_pads[1];
CV_Assert(adjustPad.width < stride.width &&
adjustPad.height < stride.height);
}
for (int i = 0; i < adjust_pads.size(); i++) {
CV_Assert(adjust_pads[i] < strides[i]);
}
fusedWeights = false;
fusedBias = false;
}
@@ -256,7 +257,8 @@ public:
}
else
#endif
return (kernel_size.size() == 2) && (backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE);
return (kernel_size.size() == 3 && preferableTarget == DNN_TARGET_CPU && backendId == DNN_BACKEND_OPENCV) ||
(kernel_size.size() == 2 && (backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE));
}
bool getMemoryShapes(const std::vector<MatShape> &inputs,
@@ -530,8 +532,8 @@ public:
const Mat* input_;
const Mat* weights_;
Mat* output_;
int outShape[4];
Size kernel_, pad_, stride_, dilation_;
int outShape[4]; // used only for conv2d
std::vector<size_t> kernel_size, pads_begin, pads_end, strides, dilations;
int ngroups_, nstripes_;
std::vector<int> ofstab_;
const std::vector<float>* biasvec_;
@@ -550,14 +552,18 @@ public:
static void run( const Mat& input, Mat& output, const Mat& weights,
const std::vector<float>& biasvec,
const std::vector<float>& reluslope,
Size kernel, Size pad, Size stride, Size dilation,
const std::vector<size_t>& kernel_size, const std::vector<size_t>& strides,
const std::vector<size_t>& pads_begin, const std::vector<size_t>& pads_end,
const std::vector<size_t>& dilations,
const ActivationLayer* activ, int ngroups, int nstripes )
{
size_t karea = std::accumulate(kernel_size.begin(), kernel_size.end(),
1, std::multiplies<size_t>());
CV_Assert_N(
input.dims == 4 && output.dims == 4,
(input.dims == 4 || input.dims == 5) && (input.dims == output.dims),
input.size[0] == output.size[0],
weights.rows == output.size[1],
weights.cols == (input.size[1]/ngroups)*kernel.width*kernel.height,
weights.cols == (input.size[1]/ngroups)*karea,
input.type() == output.type(),
input.type() == weights.type(),
input.type() == CV_32FC1,
@@ -571,26 +577,58 @@ public:
p.output_ = &output;
for( int i = 0; i < 4; i++ ) p.outShape[i] = output.size[i];
p.outShape[1] /= ngroups;
p.kernel_ = kernel; p.pad_ = pad; p.stride_ = stride; p.dilation_ = dilation;
p.kernel_size = kernel_size; p.strides = strides; p.dilations = dilations;
p.pads_begin = pads_begin; p.pads_end = pads_end;
p.ngroups_ = ngroups;
p.nstripes_ = nstripes;
int inpCnAll = input.size[1], width = input.size[3], height = input.size[2];
int inpCnAll = input.size[1];
int depth = (input.dims == 5) ? input.size[2] : 1;
int width = input.size[input.dims - 1];
int height = input.size[input.dims - 2];
int inpCn = inpCnAll / ngroups;
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;
bool isConv2D = kernel_size.size() == 2;
p.is1x1_ = isConv2D && kernel_size[0] == 1 && kernel_size[1] == 1 &&
pads_begin[0] == 0 && pads_begin[1] == 0;
p.useAVX = checkHardwareSupport(CPU_AVX) && isConv2D;
p.useAVX2 = checkHardwareSupport(CPU_AVX2) && isConv2D;
p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX && isConv2D;
int ncn = std::min(inpCn, (int)BLK_SIZE_CN);
p.ofstab_.resize(kernel.width*kernel.height*ncn);
int kernel_d = !isConv2D? kernel_size[0] : 1;
int kernel_h = kernel_size[kernel_size.size() - 2];
int kernel_w = kernel_size.back();
int dil_d = !isConv2D? dilations[0] : 1;
int dil_h = dilations[dilations.size() - 2];
int dil_w = dilations.back();
p.ofstab_.resize(karea * ncn);
int* ofstab = &p.ofstab_[0];
for( int k = 0; k < ncn; k++ )
for( int k_r = 0; k_r < kernel.height; k_r++ )
for( int k_c = 0; k_c < kernel.width; k_c++ )
ofstab[(k*kernel.height + k_r)*kernel.width + k_c] =
(k*height + k_r*dilation.height)*width + k_c*dilation.width;
if (isConv2D)
{
for( int k = 0; k < ncn; k++ )
for( int k_r = 0; k_r < kernel_h; k_r++ )
for( int k_c = 0; k_c < kernel_w; k_c++ )
ofstab[(k*kernel_h + k_r)*kernel_w + k_c] =
(k*height + k_r*dil_h)*width + k_c*dil_w;
}
else
{
for( int k = 0; k < ncn; k++ )
for (int k_d = 0; k_d < kernel_d; k_d++)
for( int k_r = 0; k_r < kernel_h; k_r++ )
for( int k_c = 0; k_c < kernel_w; k_c++ )
ofstab[(k*kernel_d*kernel_h + k_d*kernel_h + k_r)*kernel_w + k_c] =
(k*depth*height + k_d*dil_d*height + k_r*dil_h)*width + k_c*dil_w;
}
p.biasvec_ = &biasvec;
p.reluslope_ = &reluslope;
@@ -603,17 +641,39 @@ public:
{
const int valign = ConvolutionLayerImpl::VEC_ALIGN;
int ngroups = ngroups_, batchSize = input_->size[0]*ngroups;
int outW = output_->size[3], outH = output_->size[2], outCn = output_->size[1]/ngroups;
int width = input_->size[3], height = input_->size[2], inpCn = input_->size[1]/ngroups;
bool isConv2D = input_->dims == 4;
int outW = output_->size[output_->dims - 1];
int outH = output_->size[output_->dims - 2];
int outCn = output_->size[1]/ngroups;
int depth = !isConv2D? input_->size[2] : 1;
int height = input_->size[input_->dims - 2];
int width = input_->size[input_->dims - 1];
int inpCn = input_->size[1]/ngroups;
const int nstripes = nstripes_;
int kernel_w = kernel_.width, kernel_h = kernel_.height;
int pad_w = pad_.width, pad_h = pad_.height;
int stride_w = stride_.width, stride_h = stride_.height;
int dilation_w = dilation_.width, dilation_h = dilation_.height;
int karea = kernel_w*kernel_h;
int i, j, k;
size_t inpPlaneSize = width*height;
size_t outPlaneSize = outW*outH;
int kernel_d = !isConv2D? kernel_size[0] : 1;
int kernel_h = kernel_size[kernel_size.size() - 2];
int kernel_w = kernel_size.back();
int karea = kernel_w*kernel_h*kernel_d;
int pad_d = !isConv2D? pads_begin[0] : 0;
int pad_t = pads_begin[pads_begin.size() - 2];
int pad_l = pads_begin.back();
int stride_d = !isConv2D? strides[0] : 0;
int stride_h = strides[strides.size() - 2];
int stride_w = strides.back();
int dilation_d = !isConv2D? dilations[0] : 1;
int dilation_h = dilations[dilations.size() - 2];
int dilation_w = dilations.back();
int i, j, k, d;
size_t inpPlaneSize = input_->total(2);
size_t outPlaneSize = output_->total(2);
bool is1x1 = is1x1_;
int stripesPerSample;
@@ -682,72 +742,125 @@ public:
for( int ofs0 = stripeStart; ofs0 < stripeEnd; ofs0 += BLK_SIZE )
{
int ofs, ofs1 = std::min(ofs0 + BLK_SIZE, stripeEnd);
int out_i = ofs0 / outW;
int out_j = ofs0 - out_i * outW;
int out_d = ofs0 / (outH * outW);
int out_i = (ofs0 - out_d * outH * outW) / outW;
int out_j = ofs0 % outW;
// do im2row for a part of input tensor
float* rowbuf = rowbuf0;
for( ofs = ofs0; ofs < ofs1; out_j = 0, ++out_i )
{
int delta = std::min(ofs1 - ofs, outW - out_j);
int out_j1 = out_j + delta;
int in_i = out_i * stride_h - pad_h;
int in_j = out_j * stride_w - pad_w;
const float* imgptr = data_inp0 + (cn0*height + in_i)*width + in_j;
ofs += delta;
// do im2row for a part of input tensor
if( is1x1 )
if (isConv2D)
{
for( ofs = ofs0; ofs < ofs1; out_j = 0, ++out_i )
{
for( ; out_j < out_j1; out_j++, rowbuf += vsz_a, imgptr += stride_w )
int delta = std::min(ofs1 - ofs, outW - out_j);
int out_j1 = out_j + delta;
int in_i = out_i * stride_h - pad_t;
int in_j = out_j * stride_w - pad_l;
const float* imgptr = data_inp0 + (cn0*height + in_i)*width + in_j;
ofs += delta;
// do im2row for a part of input tensor
if( is1x1 )
{
for( k = 0; k < vsz; k++ )
rowbuf[k] = imgptr[k*inpPlaneSize];
for( ; out_j < out_j1; out_j++, rowbuf += vsz_a, imgptr += stride_w )
{
for( k = 0; k < vsz; k++ )
rowbuf[k] = imgptr[k*inpPlaneSize];
}
}
else
{
bool ok_i = 0 <= in_i && in_i < height - (kernel_h-1)*dilation_h;
int i0 = std::max(0, (-in_i + dilation_h-1)/dilation_h);
int i1 = std::min(kernel_h, (height - in_i + dilation_h-1)/dilation_h);
for( ; out_j < out_j1; out_j++, rowbuf += vsz_a, imgptr += stride_w, in_j += stride_w )
{
// this condition should be true for most of the tensor elements, i.e.
// most of the time the kernel aperture is inside the tensor X-Y plane.
if( ok_i && out_j + 2 <= out_j1 && 0 <= in_j && in_j + stride_w*2 <= width - (kernel_w-1)*dilation_w )
{
for( k = 0; k < vsz; k++ )
{
int k1 = ofstab[k];
float v0 = imgptr[k1];
float v1 = imgptr[k1 + stride_w];
rowbuf[k] = v0;
rowbuf[k+vsz_a] = v1;
}
out_j++;
rowbuf += vsz_a;
imgptr += stride_w;
in_j += stride_w;
}
else
{
int j0 = std::max(0, (-in_j + dilation_w-1)/dilation_w);
int j1 = std::min(kernel_w, (width - in_j + dilation_w-1)/dilation_w);
// here some non-continuous sub-row of the row will not be
// filled from the tensor; we need to make sure that the uncovered
// elements are explicitly set to 0's. the easiest way is to
// set all the elements to 0's before the loop.
memset(rowbuf, 0, vsz*sizeof(rowbuf[0]));
for( k = 0; k < ncn; k++ )
{
for( i = i0; i < i1; i++ )
{
for( j = j0; j < j1; j++ )
{
int imgofs = k*(width*height) + i*(dilation_h*width) + j*dilation_w;
rowbuf[(k*kernel_h + i)*kernel_w + j] = imgptr[imgofs];
}
}
}
}
}
}
}
else
}
else
{
for( ofs = ofs0; ofs < ofs1; out_d += (out_i + 1) / outH, out_i = (out_i + 1) % outH, out_j = 0 )
{
bool ok_i = 0 <= in_i && in_i < height - (kernel_h-1)*dilation_h;
int delta = std::min(ofs1 - ofs, outW - out_j);
int out_j1 = out_j + delta;
int in_d = out_d * stride_d - pad_d;
int in_i = out_i * stride_h - pad_t;
int in_j = out_j * stride_w - pad_l;
const float* imgptr = data_inp0 + (cn0*depth*height + in_d*height + in_i)*width + in_j;
ofs += delta;
int d0 = std::max(0, (-in_d + dilation_d - 1) / dilation_d);
int d1 = std::min(kernel_d, (depth - in_d + dilation_d - 1) / dilation_d);
int i0 = std::max(0, (-in_i + dilation_h-1)/dilation_h);
int i1 = std::min(kernel_h, (height - in_i + dilation_h-1)/dilation_h);
for( ; out_j < out_j1; out_j++, rowbuf += vsz_a, imgptr += stride_w, in_j += stride_w )
{
// this condition should be true for most of the tensor elements, i.e.
// most of the time the kernel aperture is inside the tensor X-Y plane.
if( ok_i && out_j + 2 <= out_j1 && 0 <= in_j && in_j + stride_w*2 <= width - (kernel_w-1)*dilation_w )
{
for( k = 0; k < vsz; k++ )
{
int k1 = ofstab[k];
float v0 = imgptr[k1];
float v1 = imgptr[k1 + stride_w];
rowbuf[k] = v0;
rowbuf[k+vsz_a] = v1;
}
out_j++;
rowbuf += vsz_a;
imgptr += stride_w;
in_j += stride_w;
}
else
{
int j0 = std::max(0, (-in_j + dilation_w-1)/dilation_w);
int j1 = std::min(kernel_w, (width - in_j + dilation_w-1)/dilation_w);
int j0 = std::max(0, (-in_j + dilation_w-1)/dilation_w);
int j1 = std::min(kernel_w, (width - in_j + dilation_w-1)/dilation_w);
// here some non-continuous sub-row of the row will not be
// filled from the tensor; we need to make sure that the uncovered
// elements are explicitly set to 0's. the easiest way is to
// set all the elements to 0's before the loop.
memset(rowbuf, 0, vsz*sizeof(rowbuf[0]));
for( k = 0; k < ncn; k++ )
// here some non-continuous sub-row of the row will not be
// filled from the tensor; we need to make sure that the uncovered
// elements are explicitly set to 0's. the easiest way is to
// set all the elements to 0's before the loop.
memset(rowbuf, 0, vsz*sizeof(rowbuf[0]));
for( k = 0; k < ncn; k++ )
{
for ( d = d0; d < d1; d++)
{
for( i = i0; i < i1; i++ )
{
for( j = j0; j < j1; j++ )
{
int imgofs = k*(width*height) + i*(dilation_h*width) + j*dilation_w;
rowbuf[(k*kernel_h + i)*kernel_w + j] = imgptr[imgofs];
int imgofs = k*(depth*width*height) + d*dilation_d*width*height + i*(dilation_h*width) + j*dilation_w;
rowbuf[(k*kernel_d*kernel_h + d*kernel_h + i)*kernel_w + j] = imgptr[imgofs];
}
}
}
@@ -1057,10 +1170,6 @@ public:
CV_Assert_N(inputs.size() == (size_t)1, inputs[0].size[1] % blobs[0].size[1] == 0,
outputs.size() == 1, inputs[0].data != outputs[0].data);
if (inputs[0].dims == 5) {
CV_Error(Error::StsNotImplemented, "Convolution3D layer is not supported on OCV backend");
}
int ngroups = inputs[0].size[1]/blobs[0].size[1];
CV_Assert(outputs[0].size[1] % ngroups == 0);
int outCn = blobs[0].size[0];
@@ -1089,7 +1198,7 @@ public:
int nstripes = std::max(getNumThreads(), 1);
ParallelConv::run(inputs[0], outputs[0], weightsMat, biasvec, reluslope,
kernel, pad, stride, dilation, activ.get(), ngroups, nstripes);
kernel_size, strides, pads_begin, pads_end, dilations, activ.get(), ngroups, nstripes);
}
virtual int64 getFLOPS(const std::vector<MatShape> &inputs,
@@ -1098,9 +1207,10 @@ public:
CV_Assert(inputs.size() == outputs.size());
int64 flops = 0;
int karea = std::accumulate(kernel_size.begin(), kernel_size.end(), 1, std::multiplies<size_t>());
for (int i = 0; i < inputs.size(); i++)
{
flops += total(outputs[i])*(CV_BIG_INT(2)*kernel.area()*inputs[i][1] + 1);
flops += total(outputs[i])*(CV_BIG_INT(2)*karea*inputs[i][1] + 1);
}
return flops;
@@ -1131,29 +1241,39 @@ public:
virtual bool supportBackend(int backendId) CV_OVERRIDE
{
#ifdef HAVE_INF_ENGINE
const int outGroupCn = blobs[0].size[1]; // Weights are in IOHW layout
const int outGroupCn = blobs[0].size[1]; // Weights are in IOHW or IODHW layout
const int group = numOutput / outGroupCn;
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
{
if (kernel_size.size() == 3)
CV_Error(Error::StsNotImplemented, "Unsupported deconvolution3D layer");
if (kernel_size.size() == 3 && preferableTarget != DNN_TARGET_CPU) {
return false;
}
if (adjustPad.height || adjustPad.width)
if (std::accumulate(adjust_pads.begin(), adjust_pads.end(), 0, std::plus<size_t>()) > 0)
{
if (padMode.empty())
{
if (preferableTarget != DNN_TARGET_CPU && group != 1)
{
if ((adjustPad.height && pad.height) || (adjustPad.width && pad.width))
for (int i = 0; i < adjust_pads.size(); i++) {
if (adjust_pads[i] && pads_begin[i])
return false;
}
}
for (int i = 0; i < adjust_pads.size(); i++) {
if (pads_end[i] < adjust_pads[i])
return false;
}
return pad.width >= adjustPad.width && pad.height >= adjustPad.height;
return true;
}
else if (padMode == "SAME")
{
return kernel.width >= pad.width + 1 + adjustPad.width &&
kernel.height >= pad.height + 1 + adjustPad.height;
for (int i = 0; i < adjust_pads.size(); i++) {
if (kernel_size[i] < pads_begin[i] + 1 + adjust_pads[i])
return false;
}
return true;
}
else if (padMode == "VALID")
return false;
@@ -1164,7 +1284,7 @@ public:
return preferableTarget == DNN_TARGET_CPU;
}
if (preferableTarget == DNN_TARGET_OPENCL || preferableTarget == DNN_TARGET_OPENCL_FP16)
return dilation.width == 1 && dilation.height == 1;
return std::accumulate(dilations.begin(), dilations.end(), 1, std::multiplies<size_t>()) == 1;
return true;
}
else
@@ -1751,11 +1871,14 @@ public:
#ifdef HAVE_INF_ENGINE
virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> > &) CV_OVERRIDE
{
auto ieWeights = wrapToInfEngineBlob(blobs[0], InferenceEngine::Layout::OIHW);
InferenceEngine::Layout layout = blobs[0].dims == 5? InferenceEngine::Layout::NCDHW :
InferenceEngine::Layout::OIHW;
auto ieWeights = wrapToInfEngineBlob(blobs[0], layout);
if (fusedWeights)
{
ieWeights = InferenceEngine::make_shared_blob<float>(
InferenceEngine::Precision::FP32, InferenceEngine::Layout::OIHW,
InferenceEngine::Precision::FP32, layout,
ieWeights->dims());
ieWeights->allocate();
@@ -1764,7 +1887,7 @@ public:
transpose(weightsMat, newWeights);
}
const int outGroupCn = blobs[0].size[1]; // Weights are in IOHW layout
const int outGroupCn = blobs[0].size[1]; // Weights are in IOHW or OIDHW layout
const int group = numOutput / outGroupCn;
InferenceEngine::Builder::DeconvolutionLayer ieLayer(name);
@@ -1776,12 +1899,19 @@ public:
if (padMode.empty())
{
ieLayer.setPaddingsEnd({pads_end[0] - adjust_pads[0], pads_end[1] - adjust_pads[1]});
std::vector<size_t> paddings_end;
for (int i = 0; i < pads_end.size(); i++) {
paddings_end.push_back(pads_end[i] - adjust_pads[i]);
}
ieLayer.setPaddingsEnd(paddings_end);
}
else if (padMode == "SAME")
{
ieLayer.setPaddingsEnd({kernel_size[0] - pads_begin[0] - 1 - adjust_pads[0],
kernel_size[1] - pads_begin[1] - 1 - adjust_pads[1]});
std::vector<size_t> paddings_end;
for (int i = 0; i < pads_begin.size(); i++) {
paddings_end.push_back(kernel_size[i] - pads_begin[i] - 1 - adjust_pads[i]);
}
ieLayer.setPaddingsEnd(paddings_end);
}
ieLayer.setGroup((size_t)group);
ieLayer.setOutDepth((size_t)numOutput);
@@ -1801,10 +1931,12 @@ public:
float flops = 0;
int outChannels = blobs[0].size[0];
size_t karea = std::accumulate(kernel_size.begin(), kernel_size.end(),
1, std::multiplies<size_t>());
for (int i = 0; i < inputs.size(); i++)
{
flops += CV_BIG_INT(2)*outChannels*kernel.area()*total(inputs[i]);
flops += CV_BIG_INT(2)*outChannels*karea*total(inputs[i]);
}
return flops;
+5 -3
View File
@@ -148,13 +148,12 @@ void getPoolingKernelParams(const LayerParams &params, std::vector<size_t>& kern
std::vector<size_t>& pads_begin, std::vector<size_t>& pads_end,
std::vector<size_t>& strides, cv::String &padMode)
{
util::getStrideAndPadding(params, pads_begin, pads_end, strides, padMode);
globalPooling = params.has("global_pooling") &&
params.get<bool>("global_pooling");
if (globalPooling)
{
util::getStrideAndPadding(params, pads_begin, pads_end, strides, padMode);
if(params.has("kernel_h") || params.has("kernel_w") || params.has("kernel_size"))
{
CV_Error(cv::Error::StsBadArg, "In global_pooling mode, kernel_size (or kernel_h and kernel_w) cannot be specified");
@@ -171,15 +170,18 @@ void getPoolingKernelParams(const LayerParams &params, std::vector<size_t>& kern
else
{
util::getKernelSize(params, kernel);
util::getStrideAndPadding(params, pads_begin, pads_end, strides, padMode, kernel.size());
}
}
void getConvolutionKernelParams(const LayerParams &params, std::vector<size_t>& kernel, std::vector<size_t>& pads_begin,
std::vector<size_t>& pads_end, std::vector<size_t>& strides, std::vector<size_t>& dilations, cv::String &padMode)
std::vector<size_t>& pads_end, std::vector<size_t>& strides,
std::vector<size_t>& dilations, cv::String &padMode, std::vector<size_t>& adjust_pads)
{
util::getKernelSize(params, kernel);
util::getStrideAndPadding(params, pads_begin, pads_end, strides, padMode, kernel.size());
util::getParameter(params, "dilation", "dilation", dilations, true, std::vector<size_t>(kernel.size(), 1));
util::getParameter(params, "adj", "adj", adjust_pads, true, std::vector<size_t>(kernel.size(), 0));
for (int i = 0; i < dilations.size(); i++)
CV_Assert(dilations[i] > 0);
+2 -1
View File
@@ -60,7 +60,8 @@ namespace cv
namespace dnn
{
void getConvolutionKernelParams(const LayerParams &params, std::vector<size_t>& kernel, std::vector<size_t>& pads_begin,
std::vector<size_t>& pads_end, std::vector<size_t>& strides, std::vector<size_t>& dilations, cv::String &padMode);
std::vector<size_t>& pads_end, std::vector<size_t>& strides, std::vector<size_t>& dilations,
cv::String &padMode, std::vector<size_t>& adjust_pads);
void getPoolingKernelParams(const LayerParams &params, std::vector<size_t>& kernel, bool &globalPooling,
std::vector<size_t>& pads_begin, std::vector<size_t>& pads_end, std::vector<size_t>& strides, cv::String &padMode);
+118 -56
View File
@@ -47,6 +47,7 @@
#include "../op_inf_engine.hpp"
#include <float.h>
#include <algorithm>
#include <numeric>
using std::max;
using std::min;
@@ -177,9 +178,10 @@ public:
#endif
}
else
return (kernel_size.empty() || kernel_size.size() == 2) && (backendId == DNN_BACKEND_OPENCV ||
return (kernel_size.size() == 3 && backendId == DNN_BACKEND_OPENCV && preferableTarget == DNN_TARGET_CPU) ||
((kernel_size.empty() || kernel_size.size() == 2) && (backendId == DNN_BACKEND_OPENCV ||
(backendId == DNN_BACKEND_HALIDE && haveHalide() &&
(type == MAX || (type == AVE && !pad_t && !pad_l && !pad_b && !pad_r))));
(type == MAX || (type == AVE && !pad_t && !pad_l && !pad_b && !pad_r)))));
}
#ifdef HAVE_OPENCL
@@ -341,18 +343,25 @@ public:
int poolingType;
float spatialScale;
std::vector<size_t> pads_begin, pads_end;
std::vector<size_t> kernel_size;
std::vector<size_t> strides;
PoolingInvoker() : src(0), rois(0), dst(0), mask(0), avePoolPaddedArea(false), nstripes(0),
computeMaxIdx(0), poolingType(MAX), spatialScale(0) {}
static void run(const Mat& src, const Mat& rois, Mat& dst, Mat& mask, Size kernel,
Size stride, int pad_l, int pad_t, int pad_r, int pad_b, bool avePoolPaddedArea, int poolingType, float spatialScale,
static void run(const Mat& src, const Mat& rois, Mat& dst, Mat& mask,
std::vector<size_t> kernel_size, std::vector<size_t> strides,
std::vector<size_t> pads_begin, std::vector<size_t> pads_end,
bool avePoolPaddedArea, int poolingType, float spatialScale,
bool computeMaxIdx, int nstripes)
{
CV_Assert_N(
src.isContinuous(), dst.isContinuous(),
src.type() == CV_32F, src.type() == dst.type(),
src.dims == 4, dst.dims == 4,
(((poolingType == ROI || poolingType == PSROI) && dst.size[0] == rois.size[0]) || src.size[0] == dst.size[0]),
src.dims == 4 || src.dims == 5, dst.dims == 4 || dst.dims == 5,
(((poolingType == ROI || poolingType == PSROI) &&
dst.size[0] == rois.size[0]) || src.size[0] == dst.size[0]),
poolingType == PSROI || src.size[1] == dst.size[1],
(mask.empty() || (mask.type() == src.type() && mask.size == dst.size)));
@@ -361,13 +370,20 @@ public:
p.src = &src;
p.rois = &rois;
p.dst = &dst;
p.kernel_size = kernel_size;
p.strides = strides;
p.pads_begin = pads_begin;
p.pads_end = pads_end;
p.mask = &mask;
p.kernel = kernel;
p.stride = stride;
p.pad_l = pad_l;
p.pad_t = pad_t;
p.pad_r = pad_r;
p.pad_b = pad_b;
p.kernel = Size(kernel_size[1], kernel_size[0]);
p.stride = Size(strides[1], strides[0]);
p.pad_l = pads_begin.back();
p.pad_t = pads_begin[pads_begin.size() - 2];
p.pad_r = pads_end.back();
p.pad_b = pads_end[pads_end.size() - 2];
p.avePoolPaddedArea = avePoolPaddedArea;
p.nstripes = nstripes;
p.computeMaxIdx = computeMaxIdx;
@@ -376,10 +392,21 @@ public:
if( !computeMaxIdx )
{
p.ofsbuf.resize(kernel.width*kernel.height);
for( int i = 0; i < kernel.height; i++ )
for( int j = 0; j < kernel.width; j++ )
p.ofsbuf[i*kernel.width + j] = src.size[3]*i + j;
int height = src.size[src.dims - 2];
int width = src.size[src.dims - 1];
int kernel_d = (kernel_size.size() == 3) ? kernel_size[0] : 1;
int kernel_h = kernel_size[kernel_size.size() - 2];
int kernel_w = kernel_size.back();
p.ofsbuf.resize(kernel_d * kernel_h * kernel_w);
for (int i = 0; i < kernel_d; ++i) {
for (int j = 0; j < kernel_h; ++j) {
for (int k = 0; k < kernel_w; ++k) {
p.ofsbuf[i * kernel_h * kernel_w + j * kernel_w + k] = width * height * i + width * j + k;
}
}
}
}
parallel_for_(Range(0, nstripes), p, nstripes);
@@ -387,14 +414,29 @@ public:
void operator()(const Range& r) const CV_OVERRIDE
{
int channels = dst->size[1], width = dst->size[3], height = dst->size[2];
int inp_width = src->size[3], inp_height = src->size[2];
int channels = dst->size[1];
bool isPool2D = src->dims == 4;
int depth = !isPool2D? dst->size[2] : 1;
int height = dst->size[dst->dims - 2];
int width = dst->size[dst->dims - 1];
int inp_depth = !isPool2D? src->size[2] : 1;
int inp_height = src->size[src->dims - 2];
int inp_width = src->size[src->dims - 1];
size_t total = dst->total();
size_t stripeSize = (total + nstripes - 1)/nstripes;
size_t stripeStart = r.start*stripeSize;
size_t stripeEnd = std::min(r.end*stripeSize, total);
int kernel_w = kernel.width, kernel_h = kernel.height;
int stride_w = stride.width, stride_h = stride.height;
int kernel_d = !isPool2D? kernel_size[0] : 1;
int kernel_h = kernel_size[kernel_size.size() - 2];
int kernel_w = kernel_size.back();
int stride_d = !isPool2D? strides[0] : 0;
int stride_h = strides[strides.size() - 2];
int stride_w = strides.back();
bool compMaxIdx = computeMaxIdx;
#if CV_SIMD128
@@ -413,9 +455,14 @@ public:
ofs /= width;
int y0 = (int)(ofs % height);
ofs /= height;
int d0 = (int)(ofs % depth);
ofs /= depth;
int c = (int)(ofs % channels);
int n = (int)(ofs / channels);
int ystart, yend;
int dstart = 0, dend = 1;
const float *srcData = 0;
if (poolingType == ROI)
@@ -445,15 +492,22 @@ public:
}
else
{
int pad_d_begin = (pads_begin.size() == 3) ? pads_begin[0] : 0;
dstart = d0 * stride_d - pad_d_begin;
dend = min(dstart + kernel_d, (int)(inp_depth + pads_end[0]));
ystart = y0 * stride_h - pad_t;
yend = min(ystart + kernel_h, inp_height + pad_b);
srcData = src->ptr<float>(n, c);
}
int ddelta = dend - dstart;
dstart = max(dstart, 0);
dend = min(dend, inp_depth);
int ydelta = yend - ystart;
ystart = max(ystart, 0);
yend = min(yend, inp_height);
float *dstData = dst->ptr<float>(n, c, y0);
float *dstMaskData = mask->data ? mask->ptr<float>(n, c, y0) : 0;
float *dstData = &dst->ptr<float>(n, c, d0)[y0 * width];
float *dstMaskData = mask->data ? &mask->ptr<float>(n, c, d0)[y0 * width] : 0;
int delta = std::min((int)(stripeEnd - ofs0), width - x0);
ofs0 += delta;
@@ -473,7 +527,7 @@ public:
continue;
}
#if CV_SIMD128
if( xstart > 0 && x0 + 7 < x1 && (x0 + 7) * stride_w - pad_l + kernel_w < inp_width )
if( isPool2D && xstart > 0 && x0 + 7 < x1 && (x0 + 7) * stride_w - pad_l + kernel_w < inp_width )
{
if( compMaxIdx )
{
@@ -578,49 +632,51 @@ public:
if( compMaxIdx )
{
int max_index = -1;
for (int y = ystart; y < yend; ++y)
for (int x = xstart; x < xend; ++x)
{
const int index = y * inp_width + x;
float val = srcData[index];
if (val > max_val)
for (int d = dstart; d < dend; ++d)
for (int y = ystart; y < yend; ++y)
for (int x = xstart; x < xend; ++x)
{
max_val = val;
max_index = index;
const int index = d * inp_width * inp_height + y * inp_width + x;
float val = srcData[index];
if (val > max_val)
{
max_val = val;
max_index = index;
}
}
}
dstData[x0] = max_val;
if (dstMaskData)
dstMaskData[x0] = max_index;
}
else
{
for (int y = ystart; y < yend; ++y)
for (int x = xstart; x < xend; ++x)
{
const int index = y * inp_width + x;
float val = srcData[index];
max_val = std::max(max_val, val);
for (int d = dstart; d < dend; ++d) {
for (int y = ystart; y < yend; ++y) {
for (int x = xstart; x < xend; ++x) {
const int index = d * inp_width * inp_height + y * inp_width + x;
float val = srcData[index];
max_val = std::max(max_val, val);
}
}
}
dstData[x0] = max_val;
}
}
}
else if (poolingType == AVE)
{
for( ; x0 < x1; x0++ )
for( ; x0 < x1; ++x0)
{
int xstart = x0 * stride_w - pad_l;
int xend = min(xstart + kernel_w, inp_width + pad_r);
int xdelta = xend - xstart;
xstart = max(xstart, 0);
xend = min(xend, inp_width);
float inv_kernel_area = avePoolPaddedArea ? xdelta * ydelta : ((yend - ystart) * (xend - xstart));
float inv_kernel_area = avePoolPaddedArea ? xdelta * ydelta * ddelta :
((dend - dstart) * (yend - ystart) * (xend - xstart));
inv_kernel_area = 1.0 / inv_kernel_area;
#if CV_SIMD128
if( xstart > 0 && x0 + 7 < x1 && (x0 + 7) * stride_w - pad_l + kernel_w < inp_width )
if( isPool2D && xstart > 0 && x0 + 7 < x1 && (x0 + 7) * stride_w - pad_l + kernel_w < inp_width )
{
v_float32x4 sum_val0 = v_setzero_f32(), sum_val1 = v_setzero_f32();
v_float32x4 ikarea = v_setall_f32(inv_kernel_area);
@@ -646,14 +702,15 @@ public:
#endif
{
float sum_val = 0.f;
for (int y = ystart; y < yend; ++y)
for (int x = xstart; x < xend; ++x)
{
const int index = y * inp_width + x;
float val = srcData[index];
sum_val += val;
for (int d = dstart; d < dend; ++d) {
for (int y = ystart; y < yend; ++y) {
for (int x = xstart; x < xend; ++x) {
const int index = d * inp_width * inp_height + y * inp_width + x;
float val = srcData[index];
sum_val += val;
}
}
}
dstData[x0] = sum_val*inv_kernel_area;
}
}
@@ -729,21 +786,25 @@ public:
{
const int nstripes = getNumThreads();
Mat rois;
PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad_l, pad_t, pad_r, pad_b, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
PoolingInvoker::run(src, rois, dst, mask, kernel_size, strides, pads_begin, pads_end, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
}
void avePooling(Mat &src, Mat &dst)
{
const int nstripes = getNumThreads();
Mat rois, mask;
PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad_l, pad_t, pad_r, pad_b, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
PoolingInvoker::run(src, rois, dst, mask, kernel_size, strides, pads_begin, pads_end, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
}
void roiPooling(const Mat &src, const Mat &rois, Mat &dst)
{
const int nstripes = getNumThreads();
Mat mask;
PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad_l, pad_t, pad_r, pad_b, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
kernel_size.resize(2);
strides.resize(2);
pads_begin.resize(2);
pads_end.resize(2);
PoolingInvoker::run(src, rois, dst, mask, kernel_size, strides, pads_begin, pads_end, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
}
virtual Ptr<BackendNode> initMaxPoolingHalide(const std::vector<Ptr<BackendWrapper> > &inputs)
@@ -931,17 +992,18 @@ public:
{
CV_UNUSED(inputs); // suppress unused variable warning
long flops = 0;
size_t karea = std::accumulate(kernel_size.begin(), kernel_size.end(),
1, std::multiplies<size_t>());
for(int i = 0; i < outputs.size(); i++)
{
if (type == MAX)
{
if (i%2 == 0)
flops += total(outputs[i])*kernel.area();
flops += total(outputs[i])*karea;
}
else
{
flops += total(outputs[i])*(kernel.area() + 1);
flops += total(outputs[i])*(karea + 1);
}
}
return flops;
+5 -3
View File
@@ -61,6 +61,7 @@ public:
{
setParamsFrom(params);
axis = params.get<int>("axis", 1);
num_split = params.get<int>("num_split", 0);
if (params.has("slice_point"))
{
CV_Assert(!params.has("begin") && !params.has("size") && !params.has("end"));
@@ -141,9 +142,10 @@ public:
else // Divide input blob on equal parts by axis.
{
CV_Assert(0 <= axis && axis < inpShape.size());
CV_Assert(requiredOutputs > 0 && inpShape[axis] % requiredOutputs == 0);
inpShape[axis] /= requiredOutputs;
outputs.resize(requiredOutputs, inpShape);
int splits = num_split ? num_split : requiredOutputs;
CV_Assert(splits > 0 && inpShape[axis] % splits == 0);
inpShape[axis] /= splits;
outputs.resize(splits, inpShape);
}
return false;
}
+89 -33
View File
@@ -397,11 +397,33 @@ void ONNXImporter::populateNet(Net dstNet)
layerParams.set("ceil_mode", layerParams.has("pad_mode"));
layerParams.set("ave_pool_padded_area", framework_name == "pytorch");
}
else if (layer_type == "GlobalAveragePool" || layer_type == "GlobalMaxPool")
else if (layer_type == "GlobalAveragePool" || layer_type == "GlobalMaxPool" || layer_type == "ReduceMean")
{
CV_Assert(node_proto.input_size() == 1);
layerParams.type = "Pooling";
layerParams.set("pool", layer_type == "GlobalAveragePool" ? "AVE" : "MAX");
layerParams.set("global_pooling", true);
layerParams.set("pool", layer_type == "GlobalMaxPool"? "MAX" : "AVE");
layerParams.set("global_pooling", layer_type == "GlobalAveragePool" || layer_type == "GlobalMaxPool");
if (layer_type == "ReduceMean")
{
if (layerParams.get<int>("keepdims") == 0 || !layerParams.has("axes"))
CV_Error(Error::StsNotImplemented, "Unsupported mode of ReduceMean operation.");
MatShape inpShape = outShapes[node_proto.input(0)];
if (inpShape.size() != 4 && inpShape.size() != 5)
CV_Error(Error::StsNotImplemented, "Unsupported input shape of reduce_mean operation.");
DictValue axes = layerParams.get("axes");
CV_Assert(axes.size() <= inpShape.size() - 2);
std::vector<int> kernel_size(inpShape.size() - 2, 1);
for (int i = 0; i < axes.size(); i++) {
int axis = axes.get<int>(i);
CV_Assert_N(axis >= 2 + i, axis < inpShape.size());
kernel_size[axis - 2] = inpShape[axis];
}
layerParams.set("kernel_size", DictValue::arrayInt(&kernel_size[0], kernel_size.size()));
}
}
else if (layer_type == "Slice")
{
@@ -546,6 +568,43 @@ void ONNXImporter::populateNet(Net dstNet)
{
replaceLayerParam(layerParams, "size", "local_size");
}
else if (layer_type == "InstanceNormalization")
{
if (node_proto.input_size() != 3)
CV_Error(Error::StsNotImplemented,
"Expected input, scale, bias");
layerParams.blobs.resize(4);
layerParams.blobs[2] = getBlob(node_proto, constBlobs, 1); // weightData
layerParams.blobs[3] = getBlob(node_proto, constBlobs, 2); // biasData
layerParams.set("has_bias", true);
layerParams.set("has_weight", true);
// Get number of channels in input
int size = layerParams.blobs[2].total();
layerParams.blobs[0] = Mat::zeros(size, 1, CV_32F); // mean
layerParams.blobs[1] = Mat::ones(size, 1, CV_32F); // std
LayerParams mvnParams;
mvnParams.name = layerParams.name + "/MVN";
mvnParams.type = "MVN";
mvnParams.set("eps", layerParams.get<float>("epsilon"));
layerParams.erase("epsilon");
//Create MVN layer
int id = dstNet.addLayer(mvnParams.name, mvnParams.type, mvnParams);
//Connect to input
layerId = layer_id.find(node_proto.input(0));
CV_Assert(layerId != layer_id.end());
dstNet.connect(layerId->second.layerId, layerId->second.outputId, id, 0);
//Add shape
layer_id.insert(std::make_pair(mvnParams.name, LayerInfo(id, 0)));
outShapes[mvnParams.name] = outShapes[node_proto.input(0)];
//Replace Batch Norm's input to MVN
node_proto.set_input(0, mvnParams.name);
layerParams.type = "BatchNorm";
}
else if (layer_type == "BatchNormalization")
{
if (node_proto.input_size() != 5)
@@ -645,42 +704,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("kernel_size"))
CV_Error(Error::StsNotImplemented,
"Required attribute 'kernel_size' is not present.");
if (layerParams.has("output_shape"))
{
const DictValue& outShape = layerParams.get("output_shape");
DictValue strides = layerParams.get("stride");
DictValue kernel = layerParams.get("kernel_size");
if (outShape.size() != 4)
CV_Error(Error::StsNotImplemented, "Output shape must have 4 elements.");
DictValue stride = layerParams.get("stride");
const int strideY = stride.getIntValue(0);
const int strideX = stride.getIntValue(1);
const int outH = outShape.getIntValue(2);
const int outW = outShape.getIntValue(3);
if (layerParams.get<String>("pad_mode") == "SAME")
String padMode;
std::vector<int> adjust_pads;
if (layerParams.has("pad_mode"))
{
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_size"))
CV_Error(Error::StsNotImplemented,
"Required attribute 'kernel_size' is not present.");
padMode = toUpperCase(layerParams.get<String>("pad_mode"));
if (padMode != "SAME" && padMode != "VALID")
CV_Error(Error::StsError, "Unsupported padding mode " + padMode);
DictValue kernel = layerParams.get("kernel_size");
layerParams.set("adj_h", (outH - kernel.getIntValue(0)) % strideY);
layerParams.set("adj_w", (outW - kernel.getIntValue(1)) % strideX);
for (int i = 0; i < strides.size(); i++)
{
int sz = outShape.get<int>(2 + i);
int stride = strides.get<int>(i);
adjust_pads.push_back(padMode == "SAME"? (sz - 1) % stride :
(sz - kernel.get<int>(i)) % stride);
}
layerParams.set("adj", DictValue::arrayInt(&adjust_pads[0], adjust_pads.size()));
}
}
else if (layerParams.has("output_padding"))
{
const DictValue& adj_pad = layerParams.get("output_padding");
if (adj_pad.size() != 2)
CV_Error(Error::StsNotImplemented, "Deconvolution3D layer is not supported");
layerParams.set("adj_w", adj_pad.get<int>(1));
layerParams.set("adj_h", adj_pad.get<int>(0));
replaceLayerParam(layerParams, "output_padding", "adj");
}
}
else if (layer_type == "Transpose")
@@ -715,11 +769,13 @@ void ONNXImporter::populateNet(Net dstNet)
if (axes.size() != 1)
CV_Error(Error::StsNotImplemented, "Multidimensional unsqueeze");
int dims[] = {1, -1};
MatShape inpShape = outShapes[node_proto.input(0)];
int axis = axes.getIntValue(0);
CV_Assert(0 <= axis && axis <= inpShape.size());
std::vector<int> outShape = inpShape;
outShape.insert(outShape.begin() + axis, 1);
layerParams.type = "Reshape";
layerParams.set("axis", axes.getIntValue(0));
layerParams.set("num_axes", 1);
layerParams.set("dim", DictValue::arrayInt(&dims[0], 2));
layerParams.set("dim", DictValue::arrayInt(&outShape[0], outShape.size()));
}
else if (layer_type == "Reshape")
{
+3 -2
View File
@@ -21,10 +21,11 @@
#define INF_ENGINE_RELEASE_2018R5 2018050000
#define INF_ENGINE_RELEASE_2019R1 2019010000
#define INF_ENGINE_RELEASE_2019R2 2019020000
#ifndef INF_ENGINE_RELEASE
#warning("IE version have not been provided via command-line. Using 2019R1 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2019R1
#warning("IE version have not been provided via command-line. Using 2019R2 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2019R2
#endif
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
@@ -1410,6 +1410,9 @@ void TFImporter::populateNet(Net dstNet)
axis = toNCHW(axis);
layerParams.set("axis", axis);
if (hasLayerAttr(layer, "num_split"))
layerParams.set("num_split", getLayerAttr(layer, "num_split").i());
int id = dstNet.addLayer(name, "Slice", layerParams);
layer_id[name] = id;
+19
View File
@@ -205,6 +205,11 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
applyTestTag(target == DNN_TARGET_CPU ? "" : CV_TEST_TAG_MEMORY_512MB);
if (backend == DNN_BACKEND_HALIDE)
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2);
#endif
Mat sample = imread(findDataFile("dnn/street.png"));
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.095 : 0.0;
@@ -224,6 +229,11 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height)
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2);
#endif
Mat sample = imread(findDataFile("dnn/street.png"));
Mat inp = blobFromImage(sample, 1.0f, Size(300, 560), Scalar(), false);
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.012 : 0.0;
@@ -238,6 +248,11 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
if (backend == DNN_BACKEND_HALIDE)
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2);
#endif
Mat sample = imread(findDataFile("dnn/street.png"));
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.013 : 2e-5;
@@ -355,6 +370,10 @@ TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2);
#endif
if (backend == DNN_BACKEND_HALIDE)
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
+24 -1
View File
@@ -561,7 +561,7 @@ TEST(Test_Caffe, shared_weights)
typedef testing::TestWithParam<tuple<std::string, Target> > opencv_face_detector;
TEST_P(opencv_face_detector, Accuracy)
{
std::string proto = findDataFile("dnn/opencv_face_detector.prototxt", false);
std::string proto = findDataFile("dnn/opencv_face_detector.prototxt");
std::string model = findDataFile(get<0>(GetParam()), false);
dnn::Target targetId = (dnn::Target)(int)get<1>(GetParam());
@@ -584,6 +584,29 @@ TEST_P(opencv_face_detector, Accuracy)
0, 1, 0.95097077, 0.51901293, 0.45863652, 0.5777427, 0.5347801);
normAssertDetections(ref, out, "", 0.5, 1e-5, 2e-4);
}
// False positives bug for large faces: https://github.com/opencv/opencv/issues/15106
TEST_P(opencv_face_detector, issue_15106)
{
std::string proto = findDataFile("dnn/opencv_face_detector.prototxt");
std::string model = findDataFile(get<0>(GetParam()), false);
dnn::Target targetId = (dnn::Target)(int)get<1>(GetParam());
Net net = readNetFromCaffe(proto, model);
Mat img = imread(findDataFile("cv/shared/lena.png"));
img = img.rowRange(img.rows / 4, 3 * img.rows / 4).colRange(img.cols / 4, 3 * img.cols / 4);
Mat blob = blobFromImage(img, 1.0, Size(300, 300), Scalar(104.0, 177.0, 123.0), false, false);
net.setPreferableBackend(DNN_BACKEND_OPENCV);
net.setPreferableTarget(targetId);
net.setInput(blob);
// Output has shape 1x1xNx7 where N - number of detections.
// An every detection is a vector of values [id, classId, confidence, left, top, right, bottom]
Mat out = net.forward();
Mat ref = (Mat_<float>(1, 7) << 0, 1, 0.9149431, 0.30424616, 0.26964942, 0.88733053, 0.99815309);
normAssertDetections(ref, out, "", 0.2, 6e-5, 1e-4);
}
INSTANTIATE_TEST_CASE_P(Test_Caffe, opencv_face_detector,
Combine(
Values("dnn/opencv_face_detector.caffemodel",
+1
View File
@@ -18,6 +18,7 @@
#define CV_TEST_TAG_DNN_SKIP_IE_2018R5 "dnn_skip_ie_2018r5"
#define CV_TEST_TAG_DNN_SKIP_IE_2019R1 "dnn_skip_ie_2019r1"
#define CV_TEST_TAG_DNN_SKIP_IE_2019R1_1 "dnn_skip_ie_2019r1_1"
#define CV_TEST_TAG_DNN_SKIP_IE_2019R2 "dnn_skip_ie_2019r2"
#define CV_TEST_TAG_DNN_SKIP_IE_OPENCL "dnn_skip_ie_ocl"
#define CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16 "dnn_skip_ie_ocl_fp16"
#define CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2 "dnn_skip_ie_myriad2"
+5 -2
View File
@@ -310,8 +310,11 @@ void initDNNTests()
CV_TEST_TAG_DNN_SKIP_IE_2018R5,
#elif INF_ENGINE_VER_MAJOR_EQ(2019010000)
CV_TEST_TAG_DNN_SKIP_IE_2019R1,
#elif INF_ENGINE_VER_MAJOR_EQ(2019010100)
CV_TEST_TAG_DNN_SKIP_IE_2019R1_1
# if INF_ENGINE_RELEASE == 2019010100
CV_TEST_TAG_DNN_SKIP_IE_2019R1_1,
# endif
#elif INF_ENGINE_VER_MAJOR_EQ(2019020000)
CV_TEST_TAG_DNN_SKIP_IE_2019R2,
#endif
CV_TEST_TAG_DNN_SKIP_IE
);
+22
View File
@@ -9,10 +9,32 @@
#ifdef HAVE_INF_ENGINE
#include <opencv2/core/utils/filesystem.hpp>
//
// Synchronize headers include statements with src/op_inf_engine.hpp
//
//#define INFERENCE_ENGINE_DEPRECATED // turn off deprecation warnings from IE
//there is no way to suppress warnigns from IE only at this moment, so we are forced to suppress warnings globally
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef _MSC_VER
#pragma warning(disable: 4996) // was declared deprecated
#endif
#if defined(__GNUC__)
#pragma GCC visibility push(default)
#endif
#include <inference_engine.hpp>
#include <ie_icnn_network.hpp>
#include <ie_extension.h>
#if defined(__GNUC__)
#pragma GCC visibility pop
#endif
namespace opencv_test { namespace {
static void initDLDTDataPath()
+20
View File
@@ -78,6 +78,26 @@ TEST(readNet, Regression)
EXPECT_FALSE(net.empty());
}
typedef testing::TestWithParam<tuple<Backend, Target> > dump;
TEST_P(dump, Regression)
{
const int backend = get<0>(GetParam());
const int target = get<1>(GetParam());
Net net = readNet(findDataFile("dnn/squeezenet_v1.1.prototxt"),
findDataFile("dnn/squeezenet_v1.1.caffemodel", false));
int size[] = {1, 3, 227, 227};
Mat input = cv::Mat::ones(4, size, CV_32F);
net.setInput(input);
net.setPreferableBackend(backend);
net.setPreferableTarget(target);
EXPECT_FALSE(net.dump().empty());
net.forward();
EXPECT_FALSE(net.dump().empty());
}
INSTANTIATE_TEST_CASE_P(/**/, dump, dnnBackendsAndTargets());
class FirstCustomLayer CV_FINAL : public Layer
{
public:
+51 -8
View File
@@ -76,6 +76,14 @@ public:
}
};
TEST_P(Test_ONNX_layers, InstanceNorm)
{
if (target == DNN_TARGET_MYRIAD)
testONNXModels("instancenorm", npy, 0, 0, false, false);
else
testONNXModels("instancenorm", npy);
}
TEST_P(Test_ONNX_layers, MaxPooling)
{
testONNXModels("maxpooling");
@@ -92,8 +100,8 @@ TEST_P(Test_ONNX_layers, Convolution3D)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
throw SkipTestException("Test is enabled starts from 2019R1");
#endif
if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
throw SkipTestException("Only DLIE backend on CPU is supported");
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
testONNXModels("conv3d");
testONNXModels("conv3d_bias");
}
@@ -119,6 +127,19 @@ TEST_P(Test_ONNX_layers, Deconvolution)
testONNXModels("deconv_adjpad_2d", npy, 0, 0, false, false);
}
TEST_P(Test_ONNX_layers, Deconvolution3D)
{
#if defined(INF_ENGINE_RELEASE)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_2018R5);
#endif
if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
throw SkipTestException("Only DLIE backend on CPU is supported");
testONNXModels("deconv3d");
testONNXModels("deconv3d_bias");
testONNXModels("deconv3d_pad");
testONNXModels("deconv3d_adjpad");
}
TEST_P(Test_ONNX_layers, Dropout)
{
testONNXModels("dropout");
@@ -141,6 +162,18 @@ TEST_P(Test_ONNX_layers, Clip)
testONNXModels("clip", npy);
}
TEST_P(Test_ONNX_layers, ReduceMean)
{
testONNXModels("reduce_mean");
}
TEST_P(Test_ONNX_layers, ReduceMean3D)
{
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
testONNXModels("reduce_mean3d");
}
TEST_P(Test_ONNX_layers, MaxPooling_Sigmoid)
{
testONNXModels("maxpooling_sigmoid");
@@ -177,8 +210,8 @@ TEST_P(Test_ONNX_layers, MaxPooling3D)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
throw SkipTestException("Test is enabled starts from 2019R1");
#endif
if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
throw SkipTestException("Only DLIE backend on CPU is supported");
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
testONNXModels("max_pool3d");
}
@@ -187,11 +220,21 @@ TEST_P(Test_ONNX_layers, AvePooling3D)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
throw SkipTestException("Test is enabled starts from 2019R1");
#endif
if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
throw SkipTestException("Only DLIE backend on CPU is supported");
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
testONNXModels("ave_pool3d");
}
TEST_P(Test_ONNX_layers, PoolConv3D)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
throw SkipTestException("Test is enabled starts from 2019R1");
#endif
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
testONNXModels("pool_conv_3d");
}
TEST_P(Test_ONNX_layers, BatchNormalization)
{
testONNXModels("batch_norm");
@@ -571,8 +614,8 @@ TEST_P(Test_ONNX_nets, Resnet34_kinetics)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
throw SkipTestException("Test is enabled starts from 2019R1");
#endif
if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
throw SkipTestException("Only DLIE backend on CPU is supported");
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
String onnxmodel = findDataFile("dnn/resnet-34_kinetics.onnx", false);
Mat image0 = imread(findDataFile("dnn/dog416.png"));
+29 -13
View File
@@ -136,8 +136,8 @@ TEST_P(Test_TensorFlow_layers, Convolution3D)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
throw SkipTestException("Test is enabled starts from 2019R1");
#endif
if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
throw SkipTestException("Only DLIE backend on CPU is supported");
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
runTensorFlowNet("conv3d");
}
@@ -243,8 +243,8 @@ TEST_P(Test_TensorFlow_layers, MaxPooling3D)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
throw SkipTestException("Test is enabled starts from 2019R1");
#endif
if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
throw SkipTestException("Only DLIE backend on CPU is supported");
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
runTensorFlowNet("max_pool3d");
}
@@ -253,8 +253,8 @@ TEST_P(Test_TensorFlow_layers, AvePooling3D)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2019010000)
throw SkipTestException("Test is enabled starts from 2019R1");
#endif
if (backend != DNN_BACKEND_INFERENCE_ENGINE || target != DNN_TARGET_CPU)
throw SkipTestException("Only DLIE backend on CPU is supported");
if (target != DNN_TARGET_CPU)
throw SkipTestException("Only CPU is supported");
runTensorFlowNet("ave_pool3d");
}
@@ -357,11 +357,11 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{
#if INF_ENGINE_VER_MAJOR_GE(2019010000)
#if INF_ENGINE_VER_MAJOR_EQ(2019010000)
if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
#else
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
#endif
}
#endif
@@ -395,12 +395,16 @@ TEST_P(Test_TensorFlow_nets, MobileNet_SSD)
TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
{
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
#if defined(INF_ENGINE_RELEASE)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X
)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
{
#if INF_ENGINE_VER_MAJOR_LE(2019010000)
if (getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X);
#else
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD);
#endif
}
#endif
checkBackend();
@@ -432,6 +436,11 @@ TEST_P(Test_TensorFlow_nets, Inception_v2_SSD)
TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2);
#endif
checkBackend();
std::string proto = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt");
std::string model = findDataFile("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", false);
@@ -506,6 +515,10 @@ TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
applyTestTag(target == DNN_TARGET_OPENCL ? CV_TEST_TAG_DNN_SKIP_IE_OPENCL : CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16);
#endif
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2019020000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE, CV_TEST_TAG_DNN_SKIP_IE_2019R2);
#endif
checkBackend();
std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt");
@@ -677,6 +690,9 @@ TEST_P(Test_TensorFlow_layers, lstm)
TEST_P(Test_TensorFlow_layers, split)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_2);
runTensorFlowNet("split");
if (backend == DNN_BACKEND_INFERENCE_ENGINE)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE);
runTensorFlowNet("split_equals");
+9 -5
View File
@@ -748,24 +748,28 @@ bool imwrite( const String& filename, InputArray _img,
static void*
imdecode_( const Mat& buf, int flags, int hdrtype, Mat* mat=0 )
{
CV_Assert(!buf.empty() && buf.isContinuous());
CV_Assert(!buf.empty());
CV_Assert(buf.isContinuous());
CV_Assert(buf.checkVector(1, CV_8U) > 0);
Mat buf_row = buf.reshape(1, 1); // decoders expects single row, avoid issues with vector columns
IplImage* image = 0;
CvMat *matrix = 0;
Mat temp, *data = &temp;
String filename;
ImageDecoder decoder = findDecoder(buf);
ImageDecoder decoder = findDecoder(buf_row);
if( !decoder )
return 0;
if( !decoder->setSource(buf) )
if( !decoder->setSource(buf_row) )
{
filename = tempfile();
FILE* f = fopen( filename.c_str(), "wb" );
if( !f )
return 0;
size_t bufSize = buf.cols*buf.rows*buf.elemSize();
if( fwrite( buf.ptr(), 1, bufSize, f ) != bufSize )
size_t bufSize = buf_row.total()*buf.elemSize();
if (fwrite(buf_row.ptr(), 1, bufSize, f) != bufSize)
{
fclose( f );
CV_Error( CV_StsError, "failed to write image data to temporary file" );
+1
View File
@@ -9,4 +9,5 @@ ocv_add_dispatched_file(color_yuv SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(median_blur SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(morph SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(smooth SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(undistort SSE2 AVX2)
ocv_define_module(imgproc opencv_core WRAP java python js)
+11
View File
@@ -290,4 +290,15 @@ PERF_TEST(Transform, getPerspectiveTransform_1000)
SANITY_CHECK_NOTHING();
}
PERF_TEST(Undistort, InitUndistortMap)
{
Size size_w_h(512 + 3, 512);
Mat k(3, 3, CV_32FC1);
Mat d(1, 14, CV_64FC1);
Mat dst(size_w_h, CV_32FC2);
declare.in(k, d, WARMUP_RNG).out(dst);
TEST_CYCLE() initUndistortRectifyMap(k, d, noArray(), k, size_w_h, CV_32FC2, dst, noArray());
SANITY_CHECK_NOTHING();
}
} // namespace
+4 -3
View File
@@ -84,6 +84,7 @@ Ptr<BaseFilter> getLinearFilter(
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
typedef int CV_DECL_ALIGNED(1) unaligned_int;
#define VEC_ALIGN CV_MALLOC_ALIGN
int FilterEngine__start(FilterEngine& this_, const Size &_wholeSize, const Size &sz, const Point &ofs)
@@ -1049,7 +1050,7 @@ struct SymmColumnVec_32s8u
s0 = v_muladd(v_cvt_f32(v_load(src[k] + i) + v_load(src[-k] + i)), v_setall_f32(ky[k]), s0);
v_int32x4 s32 = v_round(s0);
v_int16x8 s16 = v_pack(s32, s32);
*(int*)(dst + i) = v_reinterpret_as_s32(v_pack_u(s16, s16)).get0();
*(unaligned_int*)(dst + i) = v_reinterpret_as_s32(v_pack_u(s16, s16)).get0();
i += v_int32x4::nlanes;
}
}
@@ -1104,7 +1105,7 @@ struct SymmColumnVec_32s8u
s0 = v_muladd(v_cvt_f32(v_load(src[k] + i) - v_load(src[-k] + i)), v_setall_f32(ky[k]), s0);
v_int32x4 s32 = v_round(s0);
v_int16x8 s16 = v_pack(s32, s32);
*(int*)(dst + i) = v_reinterpret_as_s32(v_pack_u(s16, s16)).get0();
*(unaligned_int*)(dst + i) = v_reinterpret_as_s32(v_pack_u(s16, s16)).get0();
i += v_int32x4::nlanes;
}
}
@@ -2129,7 +2130,7 @@ struct FilterVec_8u
s0 = v_muladd(v_cvt_f32(v_reinterpret_as_s32(v_load_expand_q(src[k] + i))), v_setall_f32(kf[k]), s0);
v_int32x4 s32 = v_round(s0);
v_int16x8 s16 = v_pack(s32, s32);
*(int*)(dst + i) = v_reinterpret_as_s32(v_pack_u(s16, s16)).get0();
*(unaligned_int*)(dst + i) = v_reinterpret_as_s32(v_pack_u(s16, s16)).get0();
i += v_int32x4::nlanes;
}
return i;
+16 -16
View File
@@ -334,7 +334,7 @@ void hlineSmooth3Naba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, const
{
int src_idx = borderInterpolate(-1, len, borderType);
for (int k = 0; k < cn; k++)
((uint16_t*)dst)[k] = ((uint16_t*)m)[1] * src[k] + ((uint16_t*)m)[0] * ((uint16_t)(src[cn + k]) + (uint16_t)(src[src_idx*cn + k]));
((uint16_t*)dst)[k] = saturate_cast<uint16_t>(((uint16_t*)m)[1] * (uint32_t)(src[k]) + ((uint16_t*)m)[0] * ((uint32_t)(src[cn + k]) + (uint32_t)(src[src_idx*cn + k])));
}
else
{
@@ -354,14 +354,14 @@ void hlineSmooth3Naba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, const
v_mul_wrap(vx_load_expand(src), v_mul1));
#endif
for (; i < lencn; i++, src++, dst++)
*((uint16_t*)dst) = ((uint16_t*)m)[1] * src[0] + ((uint16_t*)m)[0] * ((uint16_t)(src[-cn]) + (uint16_t)(src[cn]));
*((uint16_t*)dst) = saturate_cast<uint16_t>(((uint16_t*)m)[1] * (uint32_t)(src[0]) + ((uint16_t*)m)[0] * ((uint32_t)(src[-cn]) + (uint32_t)(src[cn])));
// Point that fall right from border
if (borderType != BORDER_CONSTANT)// If BORDER_CONSTANT out of border values are equal to zero and could be skipped
{
int src_idx = (borderInterpolate(len, len, borderType) - (len - 1))*cn;
for (int k = 0; k < cn; k++)
((uint16_t*)dst)[k] = ((uint16_t*)m)[1] * src[k] + ((uint16_t*)m)[0] * ((uint16_t)(src[k - cn]) + (uint16_t)(src[src_idx + k]));
((uint16_t*)dst)[k] = saturate_cast<uint16_t>(((uint16_t*)m)[1] * (uint32_t)(src[k]) + ((uint16_t*)m)[0] * ((uint32_t)(src[k - cn]) + (uint32_t)(src[src_idx + k])));
}
else
{
@@ -896,8 +896,8 @@ void hlineSmooth5Nabcba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, cons
int idxp2 = borderInterpolate(3, len, borderType)*cn;
for (int k = 0; k < cn; k++)
{
((uint16_t*)dst)[k] = ((uint16_t*)m)[1] * ((uint16_t)(src[k + idxm1]) + (uint16_t)(src[k + cn])) + ((uint16_t*)m)[2] * src[k] + ((uint16_t*)m)[0] * ((uint16_t)(src[k + idxp1]) + (uint16_t)(src[k + idxm2]));
((uint16_t*)dst)[k + cn] = ((uint16_t*)m)[0] * ((uint16_t)(src[k + idxm1]) + (uint16_t)(src[k + idxp2])) + ((uint16_t*)m)[1] * ((uint16_t)(src[k]) + (uint16_t)(src[k + idxp1])) + ((uint16_t*)m)[2] * src[k + cn];
((uint16_t*)dst)[k] = saturate_cast<uint16_t>(((uint16_t*)m)[1] * ((uint32_t)(src[k + idxm1]) + (uint32_t)(src[k + cn])) + ((uint16_t*)m)[2] * (uint32_t)(src[k]) + ((uint16_t*)m)[0] * ((uint32_t)(src[k + idxp1]) + (uint32_t)(src[k + idxm2])));
((uint16_t*)dst)[k + cn] = saturate_cast<uint16_t>(((uint16_t*)m)[0] * ((uint32_t)(src[k + idxm1]) + (uint32_t)(src[k + idxp2])) + ((uint16_t*)m)[1] * ((uint32_t)(src[k]) + (uint32_t)(src[k + idxp1])) + ((uint16_t*)m)[2] * (uint32_t)(src[k + cn]));
}
}
}
@@ -907,7 +907,7 @@ void hlineSmooth5Nabcba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, cons
for (int k = 0; k < cn; k++)
{
dst[k] = m[2] * src[k] + m[1] * src[k + cn] + m[0] * src[k + 2 * cn];
((uint16_t*)dst)[k + cn] = ((uint16_t*)m)[1] * ((uint16_t)(src[k]) + (uint16_t)(src[k + 2 * cn])) + ((uint16_t*)m)[2] * src[k + cn];
((uint16_t*)dst)[k + cn] = saturate_cast<uint16_t>(((uint16_t*)m)[1] * ((uint32_t)(src[k]) + (uint32_t)(src[k + 2 * cn])) + ((uint16_t*)m)[2] * (uint32_t)(src[k + cn]));
dst[k + 2 * cn] = m[0] * src[k] + m[1] * src[k + cn] + m[2] * src[k + 2 * cn];
}
else
@@ -918,9 +918,9 @@ void hlineSmooth5Nabcba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, cons
int idxp2 = borderInterpolate(4, len, borderType)*cn;
for (int k = 0; k < cn; k++)
{
((uint16_t*)dst)[k] = ((uint16_t*)m)[2] * src[k] + ((uint16_t*)m)[1] * ((uint16_t)(src[k + cn]) + (uint16_t)(src[k + idxm1])) + ((uint16_t*)m)[0] * ((uint16_t)(src[k + 2 * cn]) + (uint16_t)(src[k + idxm2]));
((uint16_t*)dst)[k + cn] = ((uint16_t*)m)[2] * src[k + cn] + ((uint16_t*)m)[1] * ((uint16_t)(src[k]) + (uint16_t)(src[k + 2 * cn])) + ((uint16_t*)m)[0] * ((uint16_t)(src[k + idxm1]) + (uint16_t)(src[k + idxp1]));
((uint16_t*)dst)[k + 2 * cn] = ((uint16_t*)m)[0] * ((uint16_t)(src[k]) + (uint16_t)(src[k + idxp2])) + ((uint16_t*)m)[1] * ((uint16_t)(src[k + cn]) + (uint16_t)(src[k + idxp1])) + ((uint16_t*)m)[2] * src[k + 2 * cn];
((uint16_t*)dst)[k] = saturate_cast<uint16_t>(((uint16_t*)m)[2] * (uint32_t)(src[k]) + ((uint16_t*)m)[1] * ((uint32_t)(src[k + cn]) + (uint32_t)(src[k + idxm1])) + ((uint16_t*)m)[0] * ((uint32_t)(src[k + 2 * cn]) + (uint32_t)(src[k + idxm2])));
((uint16_t*)dst)[k + cn] = saturate_cast<uint16_t>(((uint16_t*)m)[2] * (uint32_t)(src[k + cn]) + ((uint16_t*)m)[1] * ((uint32_t)(src[k]) + (uint32_t)(src[k + 2 * cn])) + ((uint16_t*)m)[0] * ((uint32_t)(src[k + idxm1]) + (uint32_t)(src[k + idxp1])));
((uint16_t*)dst)[k + 2 * cn] = saturate_cast<uint16_t>(((uint16_t*)m)[0] * ((uint32_t)(src[k]) + (uint32_t)(src[k + idxp2])) + ((uint16_t*)m)[1] * ((uint32_t)(src[k + cn]) + (uint32_t)(src[k + idxp1])) + ((uint16_t*)m)[2] * (uint32_t)(src[k + 2 * cn]));
}
}
}
@@ -933,8 +933,8 @@ void hlineSmooth5Nabcba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, cons
int idxm1 = borderInterpolate(-1, len, borderType)*cn;
for (int k = 0; k < cn; k++)
{
((uint16_t*)dst)[k] = ((uint16_t*)m)[2] * src[k] + ((uint16_t*)m)[1] * ((uint16_t)(src[cn + k]) + (uint16_t)(src[idxm1 + k])) + ((uint16_t*)m)[0] * ((uint16_t)(src[2 * cn + k]) + (uint16_t)(src[idxm2 + k]));
((uint16_t*)dst)[k + cn] = ((uint16_t*)m)[1] * ((uint16_t)(src[k]) + (uint16_t)(src[2 * cn + k])) + ((uint16_t*)m)[2] * src[cn + k] + ((uint16_t*)m)[0] * ((uint16_t)(src[3 * cn + k]) + (uint16_t)(src[idxm1 + k]));
((uint16_t*)dst)[k] = saturate_cast<uint16_t>(((uint16_t*)m)[2] * (uint32_t)(src[k]) + ((uint16_t*)m)[1] * ((uint32_t)(src[cn + k]) + (uint32_t)(src[idxm1 + k])) + ((uint16_t*)m)[0] * ((uint32_t)(src[2 * cn + k]) + (uint32_t)(src[idxm2 + k])));
((uint16_t*)dst)[k + cn] = saturate_cast<uint16_t>(((uint16_t*)m)[1] * ((uint32_t)(src[k]) + (uint32_t)(src[2 * cn + k])) + ((uint16_t*)m)[2] * (uint32_t)(src[cn + k]) + ((uint16_t*)m)[0] * ((uint32_t)(src[3 * cn + k]) + (uint32_t)(src[idxm1 + k])));
}
}
else
@@ -942,7 +942,7 @@ void hlineSmooth5Nabcba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, cons
for (int k = 0; k < cn; k++)
{
dst[k] = m[2] * src[k] + m[1] * src[cn + k] + m[0] * src[2 * cn + k];
((uint16_t*)dst)[k + cn] = ((uint16_t*)m)[1] * ((uint16_t)(src[k]) + (uint16_t)(src[2 * cn + k])) + ((uint16_t*)m)[2] * src[cn + k] + ((uint16_t*)m)[0] * src[3 * cn + k];
((uint16_t*)dst)[k + cn] = saturate_cast<uint16_t>(((uint16_t*)m)[1] * ((uint32_t)(src[k]) + (uint32_t)(src[2 * cn + k])) + ((uint16_t*)m)[2] * (uint32_t)(src[cn + k]) + ((uint16_t*)m)[0] * (uint32_t)(src[3 * cn + k]));
}
}
@@ -960,7 +960,7 @@ void hlineSmooth5Nabcba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, cons
v_mul_wrap(vx_load_expand(src), v_mul2));
#endif
for (; i < lencn; i++, src++, dst++)
*((uint16_t*)dst) = ((uint16_t*)m)[0] * ((uint16_t)(src[-2 * cn]) + (uint16_t)(src[2 * cn])) + ((uint16_t*)m)[1] * ((uint16_t)(src[-cn]) + (uint16_t)(src[cn])) + ((uint16_t*)m)[2] * src[0];
*((uint16_t*)dst) = saturate_cast<uint16_t>(((uint16_t*)m)[0] * ((uint32_t)(src[-2 * cn]) + (uint32_t)(src[2 * cn])) + ((uint16_t*)m)[1] * ((uint32_t)(src[-cn]) + (uint32_t)(src[cn])) + ((uint16_t*)m)[2] * (uint32_t)(src[0]));
// Points that fall right from border
if (borderType != BORDER_CONSTANT)// If BORDER_CONSTANT out of border values are equal to zero and could be skipped
@@ -969,15 +969,15 @@ void hlineSmooth5Nabcba<uint8_t, ufixedpoint16>(const uint8_t* src, int cn, cons
int idxp2 = (borderInterpolate(len + 1, len, borderType) - (len - 2))*cn;
for (int k = 0; k < cn; k++)
{
((uint16_t*)dst)[k] = ((uint16_t*)m)[0] * ((uint16_t)(src[k - 2 * cn]) + (uint16_t)(src[idxp1 + k])) + ((uint16_t*)m)[1] * ((uint16_t)(src[k - cn]) + (uint16_t)(src[k + cn])) + ((uint16_t*)m)[2] * src[k];
((uint16_t*)dst)[k + cn] = ((uint16_t*)m)[0] * ((uint16_t)(src[k - cn]) + (uint16_t)(src[idxp2 + k])) + ((uint16_t*)m)[1] * ((uint16_t)(src[k]) + (uint16_t)(src[idxp1 + k])) + ((uint16_t*)m)[2] * src[k + cn];
((uint16_t*)dst)[k] = saturate_cast<uint16_t>(((uint16_t*)m)[0] * ((uint32_t)(src[k - 2 * cn]) + (uint32_t)(src[idxp1 + k])) + ((uint16_t*)m)[1] * ((uint32_t)(src[k - cn]) + (uint32_t)(src[k + cn])) + ((uint16_t*)m)[2] * (uint32_t)(src[k]));
((uint16_t*)dst)[k + cn] = saturate_cast<uint16_t>(((uint16_t*)m)[0] * ((uint32_t)(src[k - cn]) + (uint32_t)(src[idxp2 + k])) + ((uint16_t*)m)[1] * ((uint32_t)(src[k]) + (uint32_t)(src[idxp1 + k])) + ((uint16_t*)m)[2] * (uint32_t)(src[k + cn]));
}
}
else
{
for (int k = 0; k < cn; k++)
{
((uint16_t*)dst)[k] = ((uint16_t*)m)[0] * src[k - 2 * cn] + ((uint16_t*)m)[1] * ((uint16_t)(src[k - cn]) + (uint16_t)(src[k + cn])) + ((uint16_t*)m)[2] * src[k];
((uint16_t*)dst)[k] = saturate_cast<uint16_t>(((uint16_t*)m)[0] * (uint32_t)(src[k - 2 * cn]) + ((uint16_t*)m)[1] * ((uint32_t)(src[k - cn]) + (uint32_t)(src[k + cn])) + ((uint16_t*)m)[2] * (uint32_t)(src[k]));
dst[k + cn] = m[0] * src[k - cn] + m[1] * src[k] + m[2] * src[k + cn];
}
}
+22 -4
View File
@@ -1159,6 +1159,9 @@ getThreshVal_Otsu_8u( const Mat& _src )
const int N = 256;
int i, j, h[N] = {0};
#if CV_ENABLE_UNROLLED
int h_unrolled[3][N] = {};
#endif
for( i = 0; i < size.height; i++ )
{
const uchar* src = _src.ptr() + step*i;
@@ -1167,9 +1170,9 @@ getThreshVal_Otsu_8u( const Mat& _src )
for( ; j <= size.width - 4; j += 4 )
{
int v0 = src[j], v1 = src[j+1];
h[v0]++; h[v1]++;
h[v0]++; h_unrolled[0][v1]++;
v0 = src[j+2]; v1 = src[j+3];
h[v0]++; h[v1]++;
h_unrolled[1][v0]++; h_unrolled[2][v1]++;
}
#endif
for( ; j < size.width; j++ )
@@ -1178,7 +1181,12 @@ getThreshVal_Otsu_8u( const Mat& _src )
double mu = 0, scale = 1./(size.width*size.height);
for( i = 0; i < N; i++ )
{
#if CV_ENABLE_UNROLLED
h[i] += h_unrolled[0][i] + h_unrolled[1][i] + h_unrolled[2][i];
#endif
mu += i*(double)h[i];
}
mu *= scale;
double mu1 = 0, q1 = 0;
@@ -1223,6 +1231,9 @@ getThreshVal_Triangle_8u( const Mat& _src )
const int N = 256;
int i, j, h[N] = {0};
#if CV_ENABLE_UNROLLED
int h_unrolled[3][N] = {};
#endif
for( i = 0; i < size.height; i++ )
{
const uchar* src = _src.ptr() + step*i;
@@ -1231,9 +1242,9 @@ getThreshVal_Triangle_8u( const Mat& _src )
for( ; j <= size.width - 4; j += 4 )
{
int v0 = src[j], v1 = src[j+1];
h[v0]++; h[v1]++;
h[v0]++; h_unrolled[0][v1]++;
v0 = src[j+2]; v1 = src[j+3];
h[v0]++; h[v1]++;
h_unrolled[1][v0]++; h_unrolled[2][v1]++;
}
#endif
for( ; j < size.width; j++ )
@@ -1244,6 +1255,13 @@ getThreshVal_Triangle_8u( const Mat& _src )
int temp;
bool isflipped = false;
#if CV_ENABLE_UNROLLED
for( i = 0; i < N; i++ )
{
h[i] += h_unrolled[0][i] + h_unrolled[1][i] + h_unrolled[2][i];
}
#endif
for( i = 0; i < N; i++ )
{
if( h[i] > 0 )
-194
View File
@@ -1,194 +0,0 @@
/*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) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., 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*/
#include "precomp.hpp"
#include "undistort.hpp"
namespace cv
{
int initUndistortRectifyMapLine_AVX(float* m1f, float* m2f, short* m1, ushort* m2, double* matTilt, const double* ir,
double& _x, double& _y, double& _w, int width, int m1type,
double k1, double k2, double k3, double k4, double k5, double k6,
double p1, double p2, double s1, double s2, double s3, double s4,
double u0, double v0, double fx, double fy)
{
int j = 0;
static const __m256d __one = _mm256_set1_pd(1.0);
static const __m256d __two = _mm256_set1_pd(2.0);
const __m256d __matTilt_00 = _mm256_set1_pd(matTilt[0]);
const __m256d __matTilt_10 = _mm256_set1_pd(matTilt[3]);
const __m256d __matTilt_20 = _mm256_set1_pd(matTilt[6]);
const __m256d __matTilt_01 = _mm256_set1_pd(matTilt[1]);
const __m256d __matTilt_11 = _mm256_set1_pd(matTilt[4]);
const __m256d __matTilt_21 = _mm256_set1_pd(matTilt[7]);
const __m256d __matTilt_02 = _mm256_set1_pd(matTilt[2]);
const __m256d __matTilt_12 = _mm256_set1_pd(matTilt[5]);
const __m256d __matTilt_22 = _mm256_set1_pd(matTilt[8]);
for (; j <= width - 4; j += 4, _x += 4 * ir[0], _y += 4 * ir[3], _w += 4 * ir[6])
{
// Question: Should we load the constants first?
__m256d __w = _mm256_div_pd(__one, _mm256_set_pd(_w + 3 * ir[6], _w + 2 * ir[6], _w + ir[6], _w));
__m256d __x = _mm256_mul_pd(_mm256_set_pd(_x + 3 * ir[0], _x + 2 * ir[0], _x + ir[0], _x), __w);
__m256d __y = _mm256_mul_pd(_mm256_set_pd(_y + 3 * ir[3], _y + 2 * ir[3], _y + ir[3], _y), __w);
__m256d __x2 = _mm256_mul_pd(__x, __x);
__m256d __y2 = _mm256_mul_pd(__y, __y);
__m256d __r2 = _mm256_add_pd(__x2, __y2);
__m256d __2xy = _mm256_mul_pd(__two, _mm256_mul_pd(__x, __y));
__m256d __kr = _mm256_div_pd(
#if CV_FMA3
_mm256_fmadd_pd(_mm256_fmadd_pd(_mm256_fmadd_pd(_mm256_set1_pd(k3), __r2, _mm256_set1_pd(k2)), __r2, _mm256_set1_pd(k1)), __r2, __one),
_mm256_fmadd_pd(_mm256_fmadd_pd(_mm256_fmadd_pd(_mm256_set1_pd(k6), __r2, _mm256_set1_pd(k5)), __r2, _mm256_set1_pd(k4)), __r2, __one)
#else
_mm256_add_pd(__one, _mm256_mul_pd(_mm256_add_pd(_mm256_mul_pd(_mm256_add_pd(_mm256_mul_pd(_mm256_set1_pd(k3), __r2), _mm256_set1_pd(k2)), __r2), _mm256_set1_pd(k1)), __r2)),
_mm256_add_pd(__one, _mm256_mul_pd(_mm256_add_pd(_mm256_mul_pd(_mm256_add_pd(_mm256_mul_pd(_mm256_set1_pd(k6), __r2), _mm256_set1_pd(k5)), __r2), _mm256_set1_pd(k4)), __r2))
#endif
);
__m256d __r22 = _mm256_mul_pd(__r2, __r2);
#if CV_FMA3
__m256d __xd = _mm256_fmadd_pd(__x, __kr,
_mm256_add_pd(
_mm256_fmadd_pd(_mm256_set1_pd(p1), __2xy, _mm256_mul_pd(_mm256_set1_pd(p2), _mm256_fmadd_pd(__two, __x2, __r2))),
_mm256_fmadd_pd(_mm256_set1_pd(s1), __r2, _mm256_mul_pd(_mm256_set1_pd(s2), __r22))));
__m256d __yd = _mm256_fmadd_pd(__y, __kr,
_mm256_add_pd(
_mm256_fmadd_pd(_mm256_set1_pd(p1), _mm256_fmadd_pd(__two, __y2, __r2), _mm256_mul_pd(_mm256_set1_pd(p2), __2xy)),
_mm256_fmadd_pd(_mm256_set1_pd(s3), __r2, _mm256_mul_pd(_mm256_set1_pd(s4), __r22))));
__m256d __vecTilt2 = _mm256_fmadd_pd(__matTilt_20, __xd, _mm256_fmadd_pd(__matTilt_21, __yd, __matTilt_22));
#else
__m256d __xd = _mm256_add_pd(
_mm256_mul_pd(__x, __kr),
_mm256_add_pd(
_mm256_add_pd(
_mm256_mul_pd(_mm256_set1_pd(p1), __2xy),
_mm256_mul_pd(_mm256_set1_pd(p2), _mm256_add_pd(__r2, _mm256_mul_pd(__two, __x2)))),
_mm256_add_pd(
_mm256_mul_pd(_mm256_set1_pd(s1), __r2),
_mm256_mul_pd(_mm256_set1_pd(s2), __r22))));
__m256d __yd = _mm256_add_pd(
_mm256_mul_pd(__y, __kr),
_mm256_add_pd(
_mm256_add_pd(
_mm256_mul_pd(_mm256_set1_pd(p1), _mm256_add_pd(__r2, _mm256_mul_pd(__two, __y2))),
_mm256_mul_pd(_mm256_set1_pd(p2), __2xy)),
_mm256_add_pd(
_mm256_mul_pd(_mm256_set1_pd(s3), __r2),
_mm256_mul_pd(_mm256_set1_pd(s4), __r22))));
__m256d __vecTilt2 = _mm256_add_pd(_mm256_add_pd(
_mm256_mul_pd(__matTilt_20, __xd), _mm256_mul_pd(__matTilt_21, __yd)), __matTilt_22);
#endif
__m256d __invProj = _mm256_blendv_pd(
_mm256_div_pd(__one, __vecTilt2), __one,
_mm256_cmp_pd(__vecTilt2, _mm256_setzero_pd(), _CMP_EQ_OQ));
#if CV_FMA3
__m256d __u = _mm256_fmadd_pd(__matTilt_00, __xd, _mm256_fmadd_pd(__matTilt_01, __yd, __matTilt_02));
__u = _mm256_fmadd_pd(_mm256_mul_pd(_mm256_set1_pd(fx), __invProj), __u, _mm256_set1_pd(u0));
__m256d __v = _mm256_fmadd_pd(__matTilt_10, __xd, _mm256_fmadd_pd(__matTilt_11, __yd, __matTilt_12));
__v = _mm256_fmadd_pd(_mm256_mul_pd(_mm256_set1_pd(fy), __invProj), __v, _mm256_set1_pd(v0));
#else
__m256d __u = _mm256_add_pd(_mm256_add_pd(
_mm256_mul_pd(__matTilt_00, __xd), _mm256_mul_pd(__matTilt_01, __yd)), __matTilt_02);
__u = _mm256_add_pd(_mm256_mul_pd(_mm256_mul_pd(_mm256_set1_pd(fx), __invProj), __u), _mm256_set1_pd(u0));
__m256d __v = _mm256_add_pd(_mm256_add_pd(
_mm256_mul_pd(__matTilt_10, __xd), _mm256_mul_pd(__matTilt_11, __yd)), __matTilt_12);
__v = _mm256_add_pd(_mm256_mul_pd(_mm256_mul_pd(_mm256_set1_pd(fy), __invProj), __v), _mm256_set1_pd(v0));
#endif
if (m1type == CV_32FC1)
{
_mm_storeu_ps(&m1f[j], _mm256_cvtpd_ps(__u));
_mm_storeu_ps(&m2f[j], _mm256_cvtpd_ps(__v));
}
else if (m1type == CV_32FC2)
{
__m128 __u_float = _mm256_cvtpd_ps(__u);
__m128 __v_float = _mm256_cvtpd_ps(__v);
_mm_storeu_ps(&m1f[j * 2], _mm_unpacklo_ps(__u_float, __v_float));
_mm_storeu_ps(&m1f[j * 2 + 4], _mm_unpackhi_ps(__u_float, __v_float));
}
else // m1type == CV_16SC2
{
__u = _mm256_mul_pd(__u, _mm256_set1_pd(INTER_TAB_SIZE));
__v = _mm256_mul_pd(__v, _mm256_set1_pd(INTER_TAB_SIZE));
__m128i __iu = _mm256_cvtpd_epi32(__u);
__m128i __iv = _mm256_cvtpd_epi32(__v);
static const __m128i __INTER_TAB_SIZE_m1 = _mm_set1_epi32(INTER_TAB_SIZE - 1);
__m128i __m2 = _mm_add_epi32(
_mm_mullo_epi32(_mm_and_si128(__iv, __INTER_TAB_SIZE_m1), _mm_set1_epi32(INTER_TAB_SIZE)),
_mm_and_si128(__iu, __INTER_TAB_SIZE_m1));
__m2 = _mm_packus_epi32(__m2, __m2);
_mm_maskstore_epi64((long long int*) &m2[j], _mm_set_epi32(0, 0, 0xFFFFFFFF, 0xFFFFFFFF), __m2);
// gcc4.9 does not support _mm256_set_m128
// __m256i __m1 = _mm256_set_m128i(__iv, __iu);
__m256i __m1 = _mm256_setzero_si256();
__m1 = _mm256_inserti128_si256(__m1, __iu, 0);
__m1 = _mm256_inserti128_si256(__m1, __iv, 1);
__m1 = _mm256_srai_epi32(__m1, INTER_BITS); // v3 v2 v1 v0 u3 u2 u1 u0 (int32_t)
static const __m256i __permute_mask = _mm256_set_epi32(7, 3, 6, 2, 5, 1, 4, 0);
__m1 = _mm256_permutevar8x32_epi32(__m1, __permute_mask); // v3 u3 v2 u2 v1 u1 v0 u0 (int32_t)
__m1 = _mm256_packs_epi32(__m1, __m1); // x x x x v3 u3 v2 u2 x x x x v1 u1 v0 u0 (int16_t)
_mm_storeu_si128((__m128i*) &m1[j * 2], _mm256_extracti128_si256(_mm256_permute4x64_epi64(__m1, (2 << 2) + 0), 0));
}
}
_mm256_zeroupper();
return j;
}
}
/* End of file */
@@ -42,9 +42,14 @@
#include "precomp.hpp"
#include "opencv2/imgproc/detail/distortion_model.hpp"
#include "undistort.hpp"
cv::Mat cv::getDefaultNewCameraMatrix( InputArray _cameraMatrix, Size imgsize,
#include "undistort.simd.hpp"
#include "undistort.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content
namespace cv
{
Mat getDefaultNewCameraMatrix( InputArray _cameraMatrix, Size imgsize,
bool centerPrincipalPoint )
{
Mat cameraMatrix = _cameraMatrix.getMat();
@@ -61,134 +66,22 @@ cv::Mat cv::getDefaultNewCameraMatrix( InputArray _cameraMatrix, Size imgsize,
return newCameraMatrix;
}
class initUndistortRectifyMapComputer : public cv::ParallelLoopBody
namespace {
Ptr<ParallelLoopBody> getInitUndistortRectifyMapComputer(Size _size, Mat &_map1, Mat &_map2, int _m1type,
const double* _ir, Matx33d &_matTilt,
double _u0, double _v0, double _fx, double _fy,
double _k1, double _k2, double _p1, double _p2,
double _k3, double _k4, double _k5, double _k6,
double _s1, double _s2, double _s3, double _s4)
{
public:
initUndistortRectifyMapComputer(
cv::Size _size, cv::Mat &_map1, cv::Mat &_map2, int _m1type,
const double* _ir, cv::Matx33d &_matTilt,
double _u0, double _v0, double _fx, double _fy,
double _k1, double _k2, double _p1, double _p2,
double _k3, double _k4, double _k5, double _k6,
double _s1, double _s2, double _s3, double _s4)
: size(_size),
map1(_map1),
map2(_map2),
m1type(_m1type),
ir(_ir),
matTilt(_matTilt),
u0(_u0),
v0(_v0),
fx(_fx),
fy(_fy),
k1(_k1),
k2(_k2),
p1(_p1),
p2(_p2),
k3(_k3),
k4(_k4),
k5(_k5),
k6(_k6),
s1(_s1),
s2(_s2),
s3(_s3),
s4(_s4) {
#if CV_TRY_AVX2
useAVX2 = cv::checkHardwareSupport(CV_CPU_AVX2);
#endif
}
CV_INSTRUMENT_REGION();
void operator()( const cv::Range& range ) const CV_OVERRIDE
{
const int begin = range.start;
const int end = range.end;
CV_CPU_DISPATCH(getInitUndistortRectifyMapComputer, (_size, _map1, _map2, _m1type, _ir, _matTilt, _u0, _v0, _fx, _fy, _k1, _k2, _p1, _p2, _k3, _k4, _k5, _k6, _s1, _s2, _s3, _s4),
CV_CPU_DISPATCH_MODES_ALL);
}
}
for( int i = begin; i < end; i++ )
{
float* m1f = map1.ptr<float>(i);
float* m2f = map2.empty() ? 0 : map2.ptr<float>(i);
short* m1 = (short*)m1f;
ushort* m2 = (ushort*)m2f;
double _x = i*ir[1] + ir[2], _y = i*ir[4] + ir[5], _w = i*ir[7] + ir[8];
int j = 0;
if (m1type == CV_16SC2)
CV_Assert(m1 != NULL && m2 != NULL);
else if (m1type == CV_32FC1)
CV_Assert(m1f != NULL && m2f != NULL);
else
CV_Assert(m1 != NULL);
#if CV_TRY_AVX2
if( useAVX2 )
j = cv::initUndistortRectifyMapLine_AVX(m1f, m2f, m1, m2,
matTilt.val, ir, _x, _y, _w, size.width, m1type,
k1, k2, k3, k4, k5, k6, p1, p2, s1, s2, s3, s4, u0, v0, fx, fy);
#endif
for( ; j < size.width; j++, _x += ir[0], _y += ir[3], _w += ir[6] )
{
double w = 1./_w, x = _x*w, y = _y*w;
double x2 = x*x, y2 = y*y;
double r2 = x2 + y2, _2xy = 2*x*y;
double kr = (1 + ((k3*r2 + k2)*r2 + k1)*r2)/(1 + ((k6*r2 + k5)*r2 + k4)*r2);
double xd = (x*kr + p1*_2xy + p2*(r2 + 2*x2) + s1*r2+s2*r2*r2);
double yd = (y*kr + p1*(r2 + 2*y2) + p2*_2xy + s3*r2+s4*r2*r2);
cv::Vec3d vecTilt = matTilt*cv::Vec3d(xd, yd, 1);
double invProj = vecTilt(2) ? 1./vecTilt(2) : 1;
double u = fx*invProj*vecTilt(0) + u0;
double v = fy*invProj*vecTilt(1) + v0;
if( m1type == CV_16SC2 )
{
int iu = cv::saturate_cast<int>(u*cv::INTER_TAB_SIZE);
int iv = cv::saturate_cast<int>(v*cv::INTER_TAB_SIZE);
m1[j*2] = (short)(iu >> cv::INTER_BITS);
m1[j*2+1] = (short)(iv >> cv::INTER_BITS);
m2[j] = (ushort)((iv & (cv::INTER_TAB_SIZE-1))*cv::INTER_TAB_SIZE + (iu & (cv::INTER_TAB_SIZE-1)));
}
else if( m1type == CV_32FC1 )
{
m1f[j] = (float)u;
m2f[j] = (float)v;
}
else
{
m1f[j*2] = (float)u;
m1f[j*2+1] = (float)v;
}
}
}
}
private:
cv::Size size;
cv::Mat &map1;
cv::Mat &map2;
int m1type;
const double* ir;
cv::Matx33d &matTilt;
double u0;
double v0;
double fx;
double fy;
double k1;
double k2;
double p1;
double p2;
double k3;
double k4;
double k5;
double k6;
double s1;
double s2;
double s3;
double s4;
#if CV_TRY_AVX2
bool useAVX2;
#endif
};
void cv::initUndistortRectifyMap( InputArray _cameraMatrix, InputArray _distCoeffs,
void initUndistortRectifyMap( InputArray _cameraMatrix, InputArray _distCoeffs,
InputArray _matR, InputArray _newCameraMatrix,
Size size, int m1type, OutputArray _map1, OutputArray _map2 )
{
@@ -261,17 +154,17 @@ void cv::initUndistortRectifyMap( InputArray _cameraMatrix, InputArray _distCoef
double tauY = distCoeffs.cols + distCoeffs.rows - 1 >= 14 ? distPtr[13] : 0.;
// Matrix for trapezoidal distortion of tilted image sensor
cv::Matx33d matTilt = cv::Matx33d::eye();
cv::detail::computeTiltProjectionMatrix(tauX, tauY, &matTilt);
Matx33d matTilt = Matx33d::eye();
detail::computeTiltProjectionMatrix(tauX, tauY, &matTilt);
parallel_for_(Range(0, size.height), initUndistortRectifyMapComputer(
parallel_for_(Range(0, size.height), *getInitUndistortRectifyMapComputer(
size, map1, map2, m1type, ir, matTilt, u0, v0,
fx, fy, k1, k2, p1, p2, k3, k4, k5, k6, s1, s2, s3, s4));
}
void cv::undistort( InputArray _src, OutputArray _dst, InputArray _cameraMatrix,
InputArray _distCoeffs, InputArray _newCameraMatrix )
void undistort( InputArray _src, OutputArray _dst, InputArray _cameraMatrix,
InputArray _distCoeffs, InputArray _newCameraMatrix )
{
CV_INSTRUMENT_REGION();
@@ -317,6 +210,7 @@ void cv::undistort( InputArray _src, OutputArray _dst, InputArray _cameraMatrix,
}
}
}
CV_IMPL void
cvUndistort2( const CvArr* srcarr, CvArr* dstarr, const CvMat* Aarr, const CvMat* dist_coeffs, const CvMat* newAarr )
@@ -548,21 +442,24 @@ void cvUndistortPoints( const CvMat* _src, CvMat* _dst, const CvMat* _cameraMatr
cv::TermCriteria(cv::TermCriteria::COUNT, 5, 0.01));
}
void cv::undistortPoints( InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat )
namespace cv
{
void undistortPoints( InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat )
{
undistortPoints(_src, _dst, _cameraMatrix, _distCoeffs, _Rmat, _Pmat, TermCriteria(TermCriteria::MAX_ITER, 5, 0.01));
}
void cv::undistortPoints( InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat,
TermCriteria criteria)
void undistortPoints( InputArray _src, OutputArray _dst,
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _Rmat,
InputArray _Pmat,
TermCriteria criteria)
{
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
Mat distCoeffs = _distCoeffs.getMat(), R = _Rmat.getMat(), P = _Pmat.getMat();
@@ -590,9 +487,6 @@ void cv::undistortPoints( InputArray _src, OutputArray _dst,
cvUndistortPointsInternal(&_csrc, &_cdst, &_ccameraMatrix, pD, pR, pP, criteria);
}
namespace cv
{
static Point2f mapPointSpherical(const Point2f& p, float alpha, Vec4d* J, int projType)
{
double x = p.x, y = p.y;
@@ -658,9 +552,7 @@ static Point2f invMapPointSpherical(Point2f _p, float alpha, int projType)
return i < maxiter ? Point2f((float)q[0], (float)q[1]) : Point2f(-FLT_MAX, -FLT_MAX);
}
}
float cv::initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeffs0,
float initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeffs0,
Size imageSize, int destImageWidth, int m1type,
OutputArray _map1, OutputArray _map2, int projType, double _alpha )
{
@@ -747,4 +639,5 @@ float cv::initWideAngleProjMap( InputArray _cameraMatrix0, InputArray _distCoeff
return scale;
}
}
/* End of file */
-59
View File
@@ -1,59 +0,0 @@
/*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) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., 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*/
#ifndef OPENCV_IMGPROC_UNDISTORT_HPP
#define OPENCV_IMGPROC_UNDISTORT_HPP
namespace cv
{
#if CV_TRY_AVX2
int initUndistortRectifyMapLine_AVX(float* m1f, float* m2f, short* m1, ushort* m2, double* matTilt, const double* ir,
double& _x, double& _y, double& _w, int width, int m1type,
double k1, double k2, double k3, double k4, double k5, double k6,
double p1, double p2, double s1, double s2, double s3, double s4,
double u0, double v0, double fx, double fy);
#endif
}
#endif
/* End of file */
+324
View File
@@ -0,0 +1,324 @@
/*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) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., 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*/
#include "precomp.hpp"
#include "opencv2/core/hal/intrin.hpp"
namespace cv {
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
// forward declarations
Ptr<ParallelLoopBody> getInitUndistortRectifyMapComputer(Size _size, Mat &_map1, Mat &_map2, int _m1type,
const double* _ir, Matx33d &_matTilt,
double _u0, double _v0, double _fx, double _fy,
double _k1, double _k2, double _p1, double _p2,
double _k3, double _k4, double _k5, double _k6,
double _s1, double _s2, double _s3, double _s4);
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
namespace
{
class initUndistortRectifyMapComputer : public ParallelLoopBody
{
public:
initUndistortRectifyMapComputer(
Size _size, Mat &_map1, Mat &_map2, int _m1type,
const double* _ir, Matx33d &_matTilt,
double _u0, double _v0, double _fx, double _fy,
double _k1, double _k2, double _p1, double _p2,
double _k3, double _k4, double _k5, double _k6,
double _s1, double _s2, double _s3, double _s4)
: size(_size),
map1(_map1),
map2(_map2),
m1type(_m1type),
ir(_ir),
matTilt(_matTilt),
u0(_u0),
v0(_v0),
fx(_fx),
fy(_fy),
k1(_k1),
k2(_k2),
p1(_p1),
p2(_p2),
k3(_k3),
k4(_k4),
k5(_k5),
k6(_k6),
s1(_s1),
s2(_s2),
s3(_s3),
s4(_s4) {
#if CV_SIMD_64F
for (int i = 0; i < 2 * v_float64::nlanes; ++i)
{
s_x[i] = ir[0] * i;
s_y[i] = ir[3] * i;
s_w[i] = ir[6] * i;
}
#endif
}
void operator()( const cv::Range& range ) const CV_OVERRIDE
{
CV_INSTRUMENT_REGION();
const int begin = range.start;
const int end = range.end;
for( int i = begin; i < end; i++ )
{
float* m1f = map1.ptr<float>(i);
float* m2f = map2.empty() ? 0 : map2.ptr<float>(i);
short* m1 = (short*)m1f;
ushort* m2 = (ushort*)m2f;
double _x = i*ir[1] + ir[2], _y = i*ir[4] + ir[5], _w = i*ir[7] + ir[8];
int j = 0;
if (m1type == CV_16SC2)
CV_Assert(m1 != NULL && m2 != NULL);
else if (m1type == CV_32FC1)
CV_Assert(m1f != NULL && m2f != NULL);
else
CV_Assert(m1 != NULL);
#if CV_SIMD_64F
const v_float64 v_one = vx_setall_f64(1.0);
for (; j <= size.width - 2*v_float64::nlanes; j += 2*v_float64::nlanes, _x += 2*v_float64::nlanes * ir[0], _y += 2*v_float64::nlanes * ir[3], _w += 2*v_float64::nlanes * ir[6])
{
v_float64 m_0, m_1, m_2, m_3;
m_2 = v_one / (vx_setall_f64(_w) + vx_load(s_w));
m_3 = v_one / (vx_setall_f64(_w) + vx_load(s_w + v_float64::nlanes));
m_0 = vx_setall_f64(_x); m_1 = vx_setall_f64(_y);
v_float64 x_0 = (m_0 + vx_load(s_x)) * m_2;
v_float64 x_1 = (m_0 + vx_load(s_x + v_float64::nlanes)) * m_3;
v_float64 y_0 = (m_1 + vx_load(s_y)) * m_2;
v_float64 y_1 = (m_1 + vx_load(s_y + v_float64::nlanes)) * m_3;
v_float64 xd_0 = x_0 * x_0;
v_float64 yd_0 = y_0 * y_0;
v_float64 xd_1 = x_1 * x_1;
v_float64 yd_1 = y_1 * y_1;
v_float64 r2_0 = xd_0 + yd_0;
v_float64 r2_1 = xd_1 + yd_1;
m_1 = vx_setall_f64(k3);
m_2 = vx_setall_f64(k2);
m_3 = vx_setall_f64(k1);
m_0 = v_muladd(v_muladd(v_muladd(m_1, r2_0, m_2), r2_0, m_3), r2_0, v_one);
m_1 = v_muladd(v_muladd(v_muladd(m_1, r2_1, m_2), r2_1, m_3), r2_1, v_one);
m_3 = vx_setall_f64(k6);
m_2 = vx_setall_f64(k5);
m_0 /= v_muladd(v_muladd(v_muladd(m_3, r2_0, m_2), r2_0, vx_setall_f64(k4)), r2_0, v_one);
m_1 /= v_muladd(v_muladd(v_muladd(m_3, r2_1, m_2), r2_1, vx_setall_f64(k4)), r2_1, v_one);
x_0 *= m_0; y_0 *= m_0; x_1 *= m_1; y_1 *= m_1;
m_0 = vx_setall_f64(p1);
m_1 = vx_setall_f64(p2);
m_2 = vx_setall_f64(2.0);
xd_0 = v_muladd(v_muladd(m_2, xd_0, r2_0), m_1, x_0);
yd_0 = v_muladd(v_muladd(m_2, yd_0, r2_0), m_0, y_0);
xd_1 = v_muladd(v_muladd(m_2, xd_1, r2_1), m_1, x_1);
yd_1 = v_muladd(v_muladd(m_2, yd_1, r2_1), m_0, y_1);
m_0 *= m_2; m_1 *= m_2;
m_2 = x_0 * y_0;
m_3 = x_1 * y_1;
xd_0 = v_muladd(m_0, m_2, xd_0);
yd_0 = v_muladd(m_1, m_2, yd_0);
xd_1 = v_muladd(m_0, m_3, xd_1);
yd_1 = v_muladd(m_1, m_3, yd_1);
m_0 = r2_0 * r2_0;
m_1 = r2_1 * r2_1;
m_2 = vx_setall_f64(s2);
m_3 = vx_setall_f64(s1);
xd_0 = v_muladd(m_3, r2_0, v_muladd(m_2, m_0, xd_0));
xd_1 = v_muladd(m_3, r2_1, v_muladd(m_2, m_1, xd_1));
m_2 = vx_setall_f64(s4);
m_3 = vx_setall_f64(s3);
yd_0 = v_muladd(m_3, r2_0, v_muladd(m_2, m_0, yd_0));
yd_1 = v_muladd(m_3, r2_1, v_muladd(m_2, m_1, yd_1));
m_0 = vx_setall_f64(matTilt.val[0]);
m_1 = vx_setall_f64(matTilt.val[1]);
m_2 = vx_setall_f64(matTilt.val[2]);
x_0 = v_muladd(m_0, xd_0, v_muladd(m_1, yd_0, m_2));
x_1 = v_muladd(m_0, xd_1, v_muladd(m_1, yd_1, m_2));
m_0 = vx_setall_f64(matTilt.val[3]);
m_1 = vx_setall_f64(matTilt.val[4]);
m_2 = vx_setall_f64(matTilt.val[5]);
y_0 = v_muladd(m_0, xd_0, v_muladd(m_1, yd_0, m_2));
y_1 = v_muladd(m_0, xd_1, v_muladd(m_1, yd_1, m_2));
m_0 = vx_setall_f64(matTilt.val[6]);
m_1 = vx_setall_f64(matTilt.val[7]);
m_2 = vx_setall_f64(matTilt.val[8]);
r2_0 = v_muladd(m_0, xd_0, v_muladd(m_1, yd_0, m_2));
r2_1 = v_muladd(m_0, xd_1, v_muladd(m_1, yd_1, m_2));
m_0 = vx_setzero_f64();
r2_0 = v_select(r2_0 == m_0, v_one, v_one / r2_0);
r2_1 = v_select(r2_1 == m_0, v_one, v_one / r2_1);
m_0 = vx_setall_f64(fx);
m_1 = vx_setall_f64(u0);
m_2 = vx_setall_f64(fy);
m_3 = vx_setall_f64(v0);
x_0 = v_muladd(m_0 * r2_0, x_0, m_1);
y_0 = v_muladd(m_2 * r2_0, y_0, m_3);
x_1 = v_muladd(m_0 * r2_1, x_1, m_1);
y_1 = v_muladd(m_2 * r2_1, y_1, m_3);
if (m1type == CV_32FC1)
{
v_store(&m1f[j], v_cvt_f32(x_0, x_1));
v_store(&m2f[j], v_cvt_f32(y_0, y_1));
}
else if (m1type == CV_32FC2)
{
v_float32 mf0, mf1;
v_zip(v_cvt_f32(x_0, x_1), v_cvt_f32(y_0, y_1), mf0, mf1);
v_store(&m1f[j * 2], mf0);
v_store(&m1f[j * 2 + v_float32::nlanes], mf1);
}
else // m1type == CV_16SC2
{
m_0 = vx_setall_f64(INTER_TAB_SIZE);
x_0 *= m_0; x_1 *= m_0; y_0 *= m_0; y_1 *= m_0;
v_int32 mask = vx_setall_s32(INTER_TAB_SIZE - 1);
v_int32 iu = v_round(x_0, x_1);
v_int32 iv = v_round(y_0, y_1);
v_pack_u_store(&m2[j], (iu & mask) + (iv & mask) * vx_setall_s32(INTER_TAB_SIZE));
v_int32 out0, out1;
v_zip(iu >> INTER_BITS, iv >> INTER_BITS, out0, out1);
v_store(&m1[j * 2], v_pack(out0, out1));
}
}
vx_cleanup();
#endif
for( ; j < size.width; j++, _x += ir[0], _y += ir[3], _w += ir[6] )
{
double w = 1./_w, x = _x*w, y = _y*w;
double x2 = x*x, y2 = y*y;
double r2 = x2 + y2, _2xy = 2*x*y;
double kr = (1 + ((k3*r2 + k2)*r2 + k1)*r2)/(1 + ((k6*r2 + k5)*r2 + k4)*r2);
double xd = (x*kr + p1*_2xy + p2*(r2 + 2*x2) + s1*r2+s2*r2*r2);
double yd = (y*kr + p1*(r2 + 2*y2) + p2*_2xy + s3*r2+s4*r2*r2);
Vec3d vecTilt = matTilt*cv::Vec3d(xd, yd, 1);
double invProj = vecTilt(2) ? 1./vecTilt(2) : 1;
double u = fx*invProj*vecTilt(0) + u0;
double v = fy*invProj*vecTilt(1) + v0;
if( m1type == CV_16SC2 )
{
int iu = saturate_cast<int>(u*INTER_TAB_SIZE);
int iv = saturate_cast<int>(v*INTER_TAB_SIZE);
m1[j*2] = (short)(iu >> INTER_BITS);
m1[j*2+1] = (short)(iv >> INTER_BITS);
m2[j] = (ushort)((iv & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (iu & (INTER_TAB_SIZE-1)));
}
else if( m1type == CV_32FC1 )
{
m1f[j] = (float)u;
m2f[j] = (float)v;
}
else
{
m1f[j*2] = (float)u;
m1f[j*2+1] = (float)v;
}
}
}
}
private:
Size size;
Mat &map1;
Mat &map2;
int m1type;
const double* ir;
Matx33d &matTilt;
double u0;
double v0;
double fx;
double fy;
double k1;
double k2;
double p1;
double p2;
double k3;
double k4;
double k5;
double k6;
double s1;
double s2;
double s3;
double s4;
#if CV_SIMD_64F
double s_x[2*v_float64::nlanes];
double s_y[2*v_float64::nlanes];
double s_w[2*v_float64::nlanes];
#endif
};
}
Ptr<ParallelLoopBody> getInitUndistortRectifyMapComputer(Size _size, Mat &_map1, Mat &_map2, int _m1type,
const double* _ir, Matx33d &_matTilt,
double _u0, double _v0, double _fx, double _fy,
double _k1, double _k2, double _p1, double _p2,
double _k3, double _k4, double _k5, double _k6,
double _s1, double _s2, double _s3, double _s4)
{
CV_INSTRUMENT_REGION();
return Ptr<initUndistortRectifyMapComputer>(new initUndistortRectifyMapComputer(_size, _map1, _map2, _m1type, _ir, _matTilt, _u0, _v0, _fx, _fy,
_k1, _k2, _p1, _p2, _k3, _k4, _k5, _k6, _s1, _s2, _s3, _s4));
}
#endif
CV_CPU_OPTIMIZATION_NAMESPACE_END
}
/* End of file */
+2 -2
View File
@@ -294,14 +294,14 @@ OCL_TEST_P(CvtColor8u, GRAY2BGR555) { performTest(1, 2, CVTCODE(GRAY2BGR555)); }
// RGBA <-> mRGBA
#ifdef HAVE_IPP
#if defined(HAVE_IPP) || defined(__arm__)
#define IPP_EPS depth <= CV_32S ? 1 : 1e-3
#else
#define IPP_EPS 1e-3
#endif
OCL_TEST_P(CvtColor8u, RGBA2mRGBA) { performTest(4, 4, CVTCODE(RGBA2mRGBA), IPP_EPS); }
OCL_TEST_P(CvtColor8u, mRGBA2RGBA) { performTest(4, 4, CVTCODE(mRGBA2RGBA)); }
OCL_TEST_P(CvtColor8u, mRGBA2RGBA) { performTest(4, 4, CVTCODE(mRGBA2RGBA), IPP_EPS); }
// RGB <-> Lab
@@ -158,4 +158,12 @@ TEST(GaussianBlur_Bitexact, Linear8U)
}
}
TEST(GaussianBlur_Bitexact, regression_15015)
{
Mat src(100,100,CV_8UC3,Scalar(255,255,255));
Mat dst;
GaussianBlur(src, dst, Size(5, 5), 9);
ASSERT_EQ(0.0, cvtest::norm(dst, src, NORM_INF));
}
}} // namespace
@@ -2,6 +2,7 @@ package org.opencv.android;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import android.annotation.TargetApi;
import android.content.Context;
@@ -24,6 +25,7 @@ import android.view.ViewGroup.LayoutParams;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
/**
@@ -248,6 +250,20 @@ public class JavaCamera2View extends CameraBridgeViewBase {
}
}
public static class JavaCameraSizeAccessor implements ListItemAccessor {
@Override
public int getWidth(Object obj) {
android.util.Size size = (android.util.Size)obj;
return size.getWidth();
}
@Override
public int getHeight(Object obj) {
android.util.Size size = (android.util.Size)obj;
return size.getHeight();
}
}
boolean calcPreviewSize(final int width, final int height) {
Log.i(LOGTAG, "calcPreviewSize: " + width + "x" + height);
if (mCameraID == null) {
@@ -258,26 +274,15 @@ public class JavaCamera2View extends CameraBridgeViewBase {
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraID);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
int bestWidth = 0, bestHeight = 0;
float aspect = (float) width / height;
android.util.Size[] sizes = map.getOutputSizes(ImageReader.class);
bestWidth = sizes[0].getWidth();
bestHeight = sizes[0].getHeight();
for (android.util.Size sz : sizes) {
int w = sz.getWidth(), h = sz.getHeight();
Log.d(LOGTAG, "trying size: " + w + "x" + h);
if (width >= w && height >= h && bestWidth <= w && bestHeight <= h
&& Math.abs(aspect - (float) w / h) < 0.2) {
bestWidth = w;
bestHeight = h;
}
}
Log.i(LOGTAG, "best size: " + bestWidth + "x" + bestHeight);
assert(!(bestWidth == 0 || bestHeight == 0));
if (mPreviewSize.getWidth() == bestWidth && mPreviewSize.getHeight() == bestHeight)
List<android.util.Size> sizes_list = Arrays.asList(sizes);
Size frameSize = calculateCameraFrameSize(sizes_list, new JavaCameraSizeAccessor(), width, height);
Log.i(LOGTAG, "Selected preview size to " + Integer.valueOf((int)frameSize.width) + "x" + Integer.valueOf((int)frameSize.height));
assert(!(frameSize.width == 0 || frameSize.height == 0));
if (mPreviewSize.getWidth() == frameSize.width && mPreviewSize.getHeight() == frameSize.height)
return false;
else {
mPreviewSize = new android.util.Size(bestWidth, bestHeight);
mPreviewSize = new android.util.Size((int)frameSize.width, (int)frameSize.height);
return true;
}
} catch (CameraAccessException e) {
@@ -30,7 +30,7 @@ import android.view.SurfaceView;
public abstract class CameraBridgeViewBase extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraBridge";
private static final int MAX_UNSPECIFIED = -1;
protected static final int MAX_UNSPECIFIED = -1;
private static final int STOPPED = 0;
private static final int STARTED = 1;
@@ -481,6 +481,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
for (Object size : supportedSizes) {
int width = accessor.getWidth(size);
int height = accessor.getHeight(size);
Log.d(TAG, "trying size: " + width + "x" + height);
if (width <= maxAllowedWidth && height <= maxAllowedHeight) {
if (width >= calcWidth && height >= calcHeight) {
@@ -489,6 +490,13 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
}
}
}
if ((calcWidth == 0 || calcHeight == 0) && supportedSizes.size() > 0)
{
Log.i(TAG, "fallback to the first frame size");
Object size = supportedSizes.get(0);
calcWidth = accessor.getWidth(size);
calcHeight = accessor.getHeight(size);
}
return new Size(calcWidth, calcHeight);
}
+2 -2
View File
@@ -141,7 +141,7 @@ features2d = {'Feature2D': ['detect', 'compute', 'detectAndCompute', 'descriptor
'AKAZE': ['create', 'setDescriptorType', 'getDescriptorType', 'setDescriptorSize', 'getDescriptorSize', 'setDescriptorChannels', 'getDescriptorChannels', 'setThreshold', 'getThreshold', 'setNOctaves', 'getNOctaves', 'setNOctaveLayers', 'getNOctaveLayers', 'setDiffusivity', 'getDiffusivity', 'getDefaultName'],
'DescriptorMatcher': ['add', 'clear', 'empty', 'isMaskSupported', 'train', 'match', 'knnMatch', 'radiusMatch', 'clone', 'create'],
'BFMatcher': ['isMaskSupported', 'create'],
'': ['drawKeypoints', 'drawMatches']}
'': ['drawKeypoints', 'drawMatches', 'drawMatchesKnn']}
calib3d = {'': ['findHomography']}
@@ -562,7 +562,7 @@ class JSWrapperGenerator(object):
match = re.search(r'const std::vector<(.*)>&', arg_type)
if match:
type_in_vect = match.group(1)
if type_in_vect != 'cv::Mat':
if type_in_vect in ['int', 'float', 'double', 'char', 'uchar', 'String', 'std::string']:
casted_arg_name = 'emscripten::vecFromJSArray<' + type_in_vect + '>(' + arg_name + ')'
arg_type = re.sub(r'std::vector<(.*)>', 'emscripten::val', arg_type)
w_signature.append(arg_type + ' ' + arg_name)
+33
View File
@@ -80,3 +80,36 @@ QUnit.test('BFMatcher', function(assert) {
assert.equal(dm.size(), 67);
});
QUnit.test('Drawing', function(assert) {
// Generate key points.
let image = generateTestFrame();
let kp = new cv.KeyPointVector();
let descriptors = new cv.Mat();
let orb = new cv.ORB();
orb.detectAndCompute(image, new cv.Mat(), kp, descriptors);
assert.equal(kp.size(), 67);
let dst = new cv.Mat();
cv.drawKeypoints(image, kp, dst);
assert.equal(dst.rows, image.rows);
assert.equal(dst.cols, image.cols);
// Run a matcher.
let dm = new cv.DMatchVector();
let matcher = new cv.BFMatcher();
matcher.match(descriptors, descriptors, dm);
assert.equal(dm.size(), 67);
cv.drawMatches(image, kp, image, kp, dm, dst);
assert.equal(dst.rows, image.rows);
assert.equal(dst.cols, 2 * image.cols);
dm = new cv.DMatchVectorVector();
matcher.knnMatch(descriptors, descriptors, dm, 2);
assert.equal(dm.size(), 67);
cv.drawMatchesKnn(image, kp, image, kp, dm, dst);
assert.equal(dst.rows, image.rows);
assert.equal(dst.cols, 2 * image.cols);
});
+37 -6
View File
@@ -47,6 +47,10 @@
#include "opencv2/objdetect/objdetect_c.h"
#include "opencl_kernels_objdetect.hpp"
#if defined(_MSC_VER)
# pragma warning(disable:4458) // declaration of 'origWinSize' hides class member
#endif
namespace cv
{
@@ -537,7 +541,7 @@ bool FeatureEvaluator::setImage( InputArray _image, const std::vector<float>& _s
//---------------------------------------------- HaarEvaluator ---------------------------------------
bool HaarEvaluator::Feature :: read( const FileNode& node )
bool HaarEvaluator::Feature::read(const FileNode& node, const Size& origWinSize)
{
FileNode rnode = node[CC_RECTS];
FileNodeIterator it = rnode.begin(), it_end = rnode.end();
@@ -549,11 +553,23 @@ bool HaarEvaluator::Feature :: read( const FileNode& node )
rect[ri].weight = 0.f;
}
const int W = origWinSize.width;
const int H = origWinSize.height;
for(ri = 0; it != it_end; ++it, ri++)
{
FileNodeIterator it2 = (*it).begin();
it2 >> rect[ri].r.x >> rect[ri].r.y >>
rect[ri].r.width >> rect[ri].r.height >> rect[ri].weight;
Feature::RectWeigth& rw = rect[ri];
it2 >> rw.r.x >> rw.r.y >> rw.r.width >> rw.r.height >> rw.weight;
// input validation
{
CV_CheckGE(rw.r.x, 0, "Invalid HAAR feature");
CV_CheckGE(rw.r.y, 0, "Invalid HAAR feature");
CV_CheckLT(rw.r.x, W, "Invalid HAAR feature"); // necessary for overflow checks
CV_CheckLT(rw.r.y, H, "Invalid HAAR feature"); // necessary for overflow checks
CV_CheckLE(rw.r.x + rw.r.width, W, "Invalid HAAR feature");
CV_CheckLE(rw.r.y + rw.r.height, H, "Invalid HAAR feature");
}
}
tilted = (int)node[CC_TILTED] != 0;
@@ -598,7 +614,7 @@ bool HaarEvaluator::read(const FileNode& node, Size _origWinSize)
for(i = 0; i < n; i++, ++it)
{
if(!ff[i].read(*it))
if(!ff[i].read(*it, _origWinSize))
return false;
if( ff[i].tilted )
hasTiltedFeatures = true;
@@ -759,11 +775,24 @@ int HaarEvaluator::getSquaresOffset() const
}
//---------------------------------------------- LBPEvaluator -------------------------------------
bool LBPEvaluator::Feature :: read(const FileNode& node )
bool LBPEvaluator::Feature::read(const FileNode& node, const Size& origWinSize)
{
FileNode rnode = node[CC_RECT];
FileNodeIterator it = rnode.begin();
it >> rect.x >> rect.y >> rect.width >> rect.height;
const int W = origWinSize.width;
const int H = origWinSize.height;
// input validation
{
CV_CheckGE(rect.x, 0, "Invalid LBP feature");
CV_CheckGE(rect.y, 0, "Invalid LBP feature");
CV_CheckLT(rect.x, W, "Invalid LBP feature");
CV_CheckLT(rect.y, H, "Invalid LBP feature");
CV_CheckLE(rect.x + rect.width, W, "Invalid LBP feature");
CV_CheckLE(rect.y + rect.height, H, "Invalid LBP feature");
}
return true;
}
@@ -797,7 +826,7 @@ bool LBPEvaluator::read( const FileNode& node, Size _origWinSize )
std::vector<Feature>& ff = *features;
for(int i = 0; it != it_end; ++it, i++)
{
if(!ff[i].read(*it))
if(!ff[i].read(*it, _origWinSize))
return false;
}
nchannels = 1;
@@ -1477,6 +1506,8 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root)
origWinSize.width = (int)root[CC_WIDTH];
origWinSize.height = (int)root[CC_HEIGHT];
CV_Assert( origWinSize.height > 0 && origWinSize.width > 0 );
CV_CheckLE(origWinSize.width, 1000000, "Invalid window size (too large)");
CV_CheckLE(origWinSize.height, 1000000, "Invalid window size (too large)");
// load feature params
FileNode fn = root[CC_FEATURE_PARAMS];
+3 -3
View File
@@ -317,12 +317,12 @@ public:
struct Feature
{
Feature();
bool read( const FileNode& node );
bool read(const FileNode& node, const Size& origWinSize);
bool tilted;
enum { RECT_NUM = 3 };
struct
struct RectWeigth
{
Rect r;
float weight;
@@ -412,7 +412,7 @@ public:
Feature( int x, int y, int _block_w, int _block_h ) :
rect(x, y, _block_w, _block_h) {}
bool read(const FileNode& node );
bool read(const FileNode& node, const Size& origWinSize);
Rect rect; // weight and height for block
};
+24 -6
View File
@@ -157,14 +157,14 @@ public:
inline operator T* () CV_NOEXCEPT { return ptr; }
inline operator /*const*/ T* () const CV_NOEXCEPT { return (T*)ptr; } // there is no const correctness in Gst C API
inline T* get() CV_NOEXCEPT { return ptr; }
inline /*const*/ T* get() const CV_NOEXCEPT { CV_Assert(ptr); return (T*)ptr; } // there is no const correctness in Gst C API
T* get() { CV_Assert(ptr); return ptr; }
/*const*/ T* get() const { CV_Assert(ptr); return (T*)ptr; } // there is no const correctness in Gst C API
inline const T* operator -> () const { CV_Assert(ptr); return ptr; }
const T* operator -> () const { CV_Assert(ptr); return ptr; }
inline operator bool () const CV_NOEXCEPT { return ptr != NULL; }
inline bool operator ! () const CV_NOEXCEPT { return ptr == NULL; }
inline T** getRef() { CV_Assert(ptr == NULL); return &ptr; }
T** getRef() { CV_Assert(ptr == NULL); return &ptr; }
inline GSafePtr& reset(T* p) CV_NOEXCEPT // pass result of functions with "transfer floating" ownership
{
@@ -1313,7 +1313,21 @@ public:
num_frames(0), framerate(0)
{
}
virtual ~CvVideoWriter_GStreamer() CV_OVERRIDE { close(); }
virtual ~CvVideoWriter_GStreamer() CV_OVERRIDE
{
try
{
close();
}
catch (const std::exception& e)
{
CV_WARN("C++ exception in writer destructor: " << e.what());
}
catch (...)
{
CV_WARN("Unknown exception in writer destructor. Ignore");
}
}
int getCaptureDomain() const CV_OVERRIDE { return cv::CAP_GSTREAMER; }
@@ -1345,7 +1359,11 @@ void CvVideoWriter_GStreamer::close_()
{
handleMessage(pipeline);
if (gst_app_src_end_of_stream(GST_APP_SRC(source.get())) != GST_FLOW_OK)
if (!(bool)source)
{
CV_WARN("No source in GStreamer pipeline. Ignore");
}
else if (gst_app_src_end_of_stream(GST_APP_SRC(source.get())) != GST_FLOW_OK)
{
CV_WARN("Cannot send EOS to GStreamer pipeline");
}
+11 -1
View File
@@ -496,7 +496,8 @@ bool CvCaptureCAM_V4L::autosetup_capture_mode_v4l2()
V4L2_PIX_FMT_JPEG,
#endif
V4L2_PIX_FMT_Y16,
V4L2_PIX_FMT_GREY
V4L2_PIX_FMT_Y10,
V4L2_PIX_FMT_GREY,
};
for (size_t i = 0; i < sizeof(try_order) / sizeof(__u32); i++) {
@@ -543,6 +544,7 @@ bool CvCaptureCAM_V4L::convertableToRgb() const
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_Y16:
case V4L2_PIX_FMT_Y10:
case V4L2_PIX_FMT_GREY:
case V4L2_PIX_FMT_BGR24:
return true;
@@ -577,6 +579,7 @@ void CvCaptureCAM_V4L::v4l2_create_frame()
size.height = size.height * 3 / 2; // "1.5" channels
break;
case V4L2_PIX_FMT_Y16:
case V4L2_PIX_FMT_Y10:
depth = IPL_DEPTH_16U;
/* fallthru */
case V4L2_PIX_FMT_GREY:
@@ -1451,6 +1454,13 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer &currentBuffer)
cv::cvtColor(temp, destination, COLOR_GRAY2BGR);
return;
}
case V4L2_PIX_FMT_Y10:
{
cv::Mat temp(imageSize, CV_8UC1, buffers[MAX_V4L_BUFFERS].start);
cv::Mat(imageSize, CV_16UC1, currentBuffer.start).convertTo(temp, CV_8U, 1.0 / 4);
cv::cvtColor(temp, destination, COLOR_GRAY2BGR);
return;
}
case V4L2_PIX_FMT_GREY:
cv::cvtColor(cv::Mat(imageSize, CV_8UC1, currentBuffer.start), destination, COLOR_GRAY2BGR);
break;
+1 -1
View File
@@ -608,7 +608,7 @@ void VideoWriter_create(CvVideoWriter*& writer, Ptr<IVideoWriter>& iwriter, Vide
CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): trying ...\n", #backend_func)); \
iwriter = backend_func; \
if (param_VIDEOIO_DEBUG || param_VIDEOWRITER_DEBUG) \
CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): result=%p isOpened=%d...\n", #backend_func, iwriter.empty() ? NULL : iwriter.get(), iwriter.empty() ? iwriter->isOpened() : -1)); \
CV_LOG_WARNING(NULL, cv::format("VIDEOIO(%s): result=%p isOpened=%d...\n", #backend_func, iwriter.empty() ? NULL : iwriter.get(), iwriter.empty() ? -1 : iwriter->isOpened())); \
} catch(const cv::Exception& e) { \
CV_LOG_ERROR(NULL, cv::format("VIDEOIO(%s): raised OpenCV exception:\n\n%s\n", #backend_func, e.what())); \
} catch (const std::exception& e) { \
+58
View File
@@ -527,4 +527,62 @@ static vector<Ext_Fourcc_API> generate_Ext_Fourcc_API()
INSTANTIATE_TEST_CASE_P(videoio, Videoio_Writer, testing::ValuesIn(generate_Ext_Fourcc_API()));
typedef Videoio_Writer Videoio_Writer_bad_fourcc;
TEST_P(Videoio_Writer_bad_fourcc, nocrash)
{
if (!isBackendAvailable(apiPref, cv::videoio_registry::getStreamBackends()))
throw SkipTestException(cv::String("Backend is not available/disabled: ") + cv::videoio_registry::getBackendName(apiPref));
VideoWriter writer;
EXPECT_NO_THROW(writer.open(video_file, apiPref, fourcc, fps, frame_size, true));
ASSERT_FALSE(writer.isOpened());
EXPECT_NO_THROW(writer.release());
}
static vector<Ext_Fourcc_API> generate_Ext_Fourcc_API_nocrash()
{
static const Ext_Fourcc_API params[] = {
#ifdef HAVE_MSMF_DISABLED // MSMF opens writer stream
{"wmv", "aaaa", CAP_MSMF},
{"mov", "aaaa", CAP_MSMF},
#endif
#ifdef HAVE_QUICKTIME
{"mov", "aaaa", CAP_QT},
{"avi", "aaaa", CAP_QT},
{"mkv", "aaaa", CAP_QT},
#endif
#ifdef HAVE_AVFOUNDATION
{"mov", "aaaa", CAP_AVFOUNDATION},
{"mp4", "aaaa", CAP_AVFOUNDATION},
{"m4v", "aaaa", CAP_AVFOUNDATION},
#endif
#ifdef HAVE_FFMPEG
{"avi", "aaaa", CAP_FFMPEG},
{"mkv", "aaaa", CAP_FFMPEG},
#endif
#ifdef HAVE_GSTREAMER
{"avi", "aaaa", CAP_GSTREAMER},
{"mkv", "aaaa", CAP_GSTREAMER},
#endif
{"avi", "aaaa", CAP_OPENCV_MJPEG},
};
const size_t N = sizeof(params)/sizeof(params[0]);
vector<Ext_Fourcc_API> result; result.reserve(N);
for (size_t i = 0; i < N; i++)
{
const Ext_Fourcc_API& src = params[i];
Ext_Fourcc_API e = { src.ext, src.fourcc, src.api };
result.push_back(e);
}
return result;
}
INSTANTIATE_TEST_CASE_P(videoio, Videoio_Writer_bad_fourcc, testing::ValuesIn(generate_Ext_Fourcc_API_nocrash()));
} // namespace
@@ -0,0 +1,12 @@
if(WINCE)
# CommCtrl.lib does not exist in headless WINCE Adding this will make CMake
# Try_Compile succeed and therefore also C/C++ ABI Detetection work
# https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/Platform/Windows-
# MSVC.cmake
set(CMAKE_C_STANDARD_LIBRARIES_INIT "coredll.lib")
set(CMAKE_CXX_STANDARD_LIBRARIES_INIT ${CMAKE_C_STANDARD_LIBRARIES_INIT})
foreach(ID EXE SHARED MODULE)
string(APPEND CMAKE_${ID}_LINKER_FLAGS_INIT
" /NODEFAULTLIB:libc.lib /NODEFAULTLIB:oldnames.lib")
endforeach()
endif()
+35
View File
@@ -0,0 +1,35 @@
set(CMAKE_SYSTEM_NAME WindowsCE)
if(NOT CMAKE_SYSTEM_VERSION)
set(CMAKE_SYSTEM_VERSION 8.0)
endif()
if(NOT CMAKE_SYSTEM_PROCESSOR)
set(CMAKE_SYSTEM_PROCESSOR armv7-a)
endif()
if(NOT CMAKE_GENERATOR_TOOLSET)
set(CMAKE_GENERATOR_TOOLSET CE800)
endif()
# Needed to make try_compile to succeed
if(BUILD_HEADLESS)
set(CMAKE_USER_MAKE_RULES_OVERRIDE
${CMAKE_CURRENT_LIST_DIR}/arm-wince-headless-overrides.cmake)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
endif()
+62
View File
@@ -0,0 +1,62 @@
# Building OpenCV from Source for Windows Embedded Compact (WINCE/WEC)
## Requirements
CMake 3.1.0 or higher
Windows Embedded Compact SDK
## Configuring
To configure CMake for Windows Embedded, specify Visual Studio 2013 as generator and the name of your installed SDK:
`cmake -G "Visual Studio 12 2013" -A "MySDK WEC2013" -DCMAKE_TOOLCHAIN_FILE:FILEPATH=../platforms/wince/arm-wince.toolchain.cmake`
If you are building for a headless WINCE, specify `-DBUILD_HEADLESS=ON` when configuring. This will remove the `commctrl.lib` dependency.
If you are building for anything else than WINCE800, you need to specify that in the configuration step. Example:
```
-DCMAKE_SYSTEM_VERSION=7.0 -DCMAKE_GENERATOR_TOOLSET=CE700 -DCMAKE_SYSTEM_PROCESSOR=arm-v4
```
For headless WEC2013, this configuration may not be limited to but is known to work:
```
-DBUILD_EXAMPLES=OFF `
-DBUILD_opencv_apps=OFF `
-DBUILD_opencv_calib3d=OFF `
-DBUILD_opencv_highgui=OFF `
-DBUILD_opencv_features2d=OFF `
-DBUILD_opencv_flann=OFF `
-DBUILD_opencv_ml=OFF `
-DBUILD_opencv_objdetect=OFF `
-DBUILD_opencv_photo=OFF `
-DBUILD_opencv_shape=OFF `
-DBUILD_opencv_stitching=OFF `
-DBUILD_opencv_superres=OFF `
-DBUILD_opencv_ts=OFF `
-DBUILD_opencv_video=OFF `
-DBUILD_opencv_videoio=OFF `
-DBUILD_opencv_videostab=OFF `
-DBUILD_opencv_dnn=OFF `
-DBUILD_opencv_java=OFF `
-DBUILD_opencv_python2=OFF `
-DBUILD_opencv_python3=OFF `
-DBUILD_opencv_java_bindings_generator=OFF `
-DBUILD_opencv_python_bindings_generator=OFF `
-DBUILD_TIFF=OFF `
-DCV_TRACE=OFF `
-DWITH_OPENCL=OFF `
-DHAVE_OPENCL=OFF `
-DWITH_QT=OFF `
-DWITH_GTK=OFF `
-DWITH_QUIRC=OFF `
-DWITH_JASPER=OFF `
-DWITH_WEBP=OFF `
-DWITH_PROTOBUF=OFF `
-DBUILD_SHARED_LIBS=OFF `
-DWITH_OPENEXR=OFF `
-DWITH_TIFF=OFF `
```
## Building
You are required to build using Unicode:
`cmake --build . -- /p:CharacterSet=Unicode`
+7
View File
@@ -57,6 +57,13 @@ foreach(sample_filename ${cpp_samples})
if(HAVE_OPENGL AND sample_filename MATCHES "detect_mser")
target_compile_definitions(${tgt} PRIVATE HAVE_OPENGL)
endif()
if(sample_filename MATCHES "simd_")
# disabled intentionally - demonstation purposes only
#target_include_directories(${tgt} PRIVATE "${CMAKE_CURRENT_LIST_DIR}")
#target_compile_definitions(${tgt} PRIVATE OPENCV_SIMD_CONFIG_HEADER=opencv_simd_config_custom.hpp)
#target_compile_definitions(${tgt} PRIVATE OPENCV_SIMD_CONFIG_INCLUDE_DIR=1)
#target_compile_options(${tgt} PRIVATE -mavx2)
endif()
endforeach()
include("tutorial_code/calib3d/real_time_pose_estimation/CMakeLists.txt" OPTIONAL)
+49
View File
@@ -0,0 +1,49 @@
#include "opencv2/core.hpp"
#include "opencv2/core/simd_intrinsics.hpp"
using namespace cv;
int main(int /*argc*/, char** /*argv*/)
{
printf("================== macro dump ===================\n");
#ifdef CV_SIMD
printf("CV_SIMD is defined: " CVAUX_STR(CV_SIMD) "\n");
#ifdef CV_SIMD_WIDTH
printf("CV_SIMD_WIDTH is defined: " CVAUX_STR(CV_SIMD_WIDTH) "\n");
#endif
#ifdef CV_SIMD128
printf("CV_SIMD128 is defined: " CVAUX_STR(CV_SIMD128) "\n");
#endif
#ifdef CV_SIMD256
printf("CV_SIMD256 is defined: " CVAUX_STR(CV_SIMD256) "\n");
#endif
#ifdef CV_SIMD512
printf("CV_SIMD512 is defined: " CVAUX_STR(CV_SIMD512) "\n");
#endif
#ifdef CV_SIMD_64F
printf("CV_SIMD_64F is defined: " CVAUX_STR(CV_SIMD_64F) "\n");
#endif
#ifdef CV_SIMD_FP16
printf("CV_SIMD_FP16 is defined: " CVAUX_STR(CV_SIMD_FP16) "\n");
#endif
#else
printf("CV_SIMD is NOT defined\n");
#endif
#ifdef CV_SIMD
printf("================= sizeof checks =================\n");
printf("sizeof(v_uint8) = %d\n", (int)sizeof(v_uint8));
printf("sizeof(v_int32) = %d\n", (int)sizeof(v_int32));
printf("sizeof(v_float32) = %d\n", (int)sizeof(v_float32));
printf("================== arithm check =================\n");
v_uint8 a = vx_setall_u8(10);
v_uint8 c = a + vx_setall_u8(45);
printf("(vx_setall_u8(10) + vx_setall_u8(45)).get0() => %d\n", (int)c.get0());
#else
printf("\nSIMD intrinsics are not available. Check compilation target and passed build options.\n");
#endif
printf("===================== done ======================\n");
return 0;
}
+2 -2
View File
@@ -892,7 +892,7 @@ layer {
}
convolution_param {
num_output: 128
pad: 1
pad: 0
kernel_size: 3
stride: 1
weight_filler {
@@ -958,7 +958,7 @@ layer {
}
convolution_param {
num_output: 128
pad: 1
pad: 0
kernel_size: 3
stride: 1
weight_filler {
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -69,7 +69,7 @@ function recognize(face) {
function loadModels(callback) {
var utils = new Utils('');
var proto = 'https://raw.githubusercontent.com/opencv/opencv/3.4/samples/dnn/face_detector/deploy.prototxt';
var proto = 'https://raw.githubusercontent.com/opencv/opencv/3.4/samples/dnn/face_detector/deploy_lowres.prototxt';
var weights = 'https://raw.githubusercontent.com/opencv/opencv_3rdparty/dnn_samples_face_detector_20180205_fp16/res10_300x300_ssd_iter_140000_fp16.caffemodel';
var recognModel = 'https://raw.githubusercontent.com/pyannote/pyannote-data/master/openface.nn4.small2.v1.t7';
utils.createFileFromUrl('face_detector.prototxt', proto, () => {