mirror of
https://github.com/opencv/opencv.git
synced 2026-07-22 03:43:03 +04:00
Compare commits
50 Commits
4.1.1-openvino
...
3.4.7
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a7ca5a291 | |||
| 7295983964 | |||
| 39a6889767 | |||
| 0db4fb1835 | |||
| ac425f67e4 | |||
| a2125594ea | |||
| 416c693b3f | |||
| 321c74ccd6 | |||
| 6158bd2afa | |||
| d2911a8d41 | |||
| 2ee00e7f7d | |||
| ad092bf1ce | |||
| 557990fdcf | |||
| a66a1a24d7 | |||
| 099f4f9e7c | |||
| 8bac8b513c | |||
| 781f4d439e | |||
| a8a71eb200 | |||
| 61f589ddd0 | |||
| c6de84d868 | |||
| 228af2d617 | |||
| 002904e445 | |||
| e0f8bb83a6 | |||
| 12fdaf895e | |||
| c12e26ff28 | |||
| 0d2bc7b5fd | |||
| e4e0bb533d | |||
| f5e01f7b49 | |||
| c9fcc12e3b | |||
| 4ea8526e9f | |||
| 5ccb2a4cbd | |||
| c3b838b738 | |||
| 054c796213 | |||
| 245c256b1c | |||
| 6aa07cdc7e | |||
| 894ad33bf4 | |||
| 34f6b05467 | |||
| 32c6e58bdb | |||
| 8bcd7e122a | |||
| 3c086fb2fe | |||
| 32b6ebb670 | |||
| 4997a6bf06 | |||
| 1e9e2aa95c | |||
| b9399a5df8 | |||
| eedbd1ad59 | |||
| 7589225fc0 | |||
| 39a975cb29 | |||
| 594a95839c | |||
| 3998b41d68 | |||
| 57fae4a6a1 |
Vendored
+1
-1
@@ -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.
|
||||
|
||||
Vendored
+7
-5
@@ -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
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ¶ms);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(¶ms.kernel[0], 3);
|
||||
DictValue stride = DictValue::arrayInt(¶ms.stride[0], 3);
|
||||
DictValue pad = DictValue::arrayInt(¶ms.pad[0], 6);
|
||||
DictValue dilation = DictValue::arrayInt(¶ms.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
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 ¶ms)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -148,13 +148,12 @@ void getPoolingKernelParams(const LayerParams ¶ms, 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 ¶ms, 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 ¶ms, 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);
|
||||
|
||||
@@ -60,7 +60,8 @@ namespace cv
|
||||
namespace dnn
|
||||
{
|
||||
void getConvolutionKernelParams(const LayerParams ¶ms, 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 ¶ms, 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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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" );
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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 ¤tBuffer)
|
||||
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;
|
||||
|
||||
@@ -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) { \
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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`
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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, () => {
|
||||
|
||||
Reference in New Issue
Block a user