status(" Halide:" HAVE_HALIDE THEN "YES (${HALIDE_LIBRARIES} ${HALIDE_INCLUDE_DIRS})" ELSE NO)
endif()
-if(WITH_INF_ENGINE OR HAVE_INF_ENGINE)
- if(HAVE_INF_ENGINE)
- set(__msg "YES")
- if(DEFINED INF_ENGINE_VERSION)
- set(__msg "YES (ver ${INF_ENGINE_VERSION})")
+if(WITH_INF_ENGINE OR INF_ENGINE_TARGET)
+ if(INF_ENGINE_TARGET)
+ set(__msg "YES (${INF_ENGINE_RELEASE} / ${INF_ENGINE_VERSION})")
+ get_target_property(_lib ${INF_ENGINE_TARGET} IMPORTED_LOCATION)
+ if(NOT _lib)
+ get_target_property(_lib_rel ${INF_ENGINE_TARGET} IMPORTED_IMPLIB_RELEASE)
+ get_target_property(_lib_dbg ${INF_ENGINE_TARGET} IMPORTED_IMPLIB_DEBUG)
+ set(_lib "${_lib_rel} / ${_lib_dbg}")
endif()
+ get_target_property(_inc ${INF_ENGINE_TARGET} INTERFACE_INCLUDE_DIRECTORIES)
status(" Inference Engine:" "${__msg}")
- status(" libs:" "${INF_ENGINE_LIBRARIES}")
- status(" includes:" "${INF_ENGINE_INCLUDE_DIRS}")
+ status(" libs:" "${_lib}")
+ status(" includes:" "${_inc}")
else()
status(" Inference Engine:" "NO")
endif()
# The script detects Intel(R) Inference Engine installation
#
-# Parameters:
-# INTEL_CVSDK_DIR - Path to Inference Engine root folder
-# IE_PLUGINS_PATH - Path to folder with Inference Engine plugins
+# Cache variables:
+# INF_ENGINE_OMP_DIR - directory with OpenMP library to link with (needed by some versions of IE)
+# INF_ENGINE_RELEASE - a number reflecting IE source interface (linked with OpenVINO release)
#
-# On return this will define:
+# Detect parameters:
+# 1. Native cmake IE package:
+# - enironment variable InferenceEngine_DIR is set to location of cmake module
+# 2. Custom location:
+# - INF_ENGINE_INCLUDE_DIRS - headers search location
+# - INF_ENGINE_LIB_DIRS - library search location
+# 3. OpenVINO location:
+# - environment variable INTEL_CVSDK_DIR is set to location of OpenVINO installation dir
+# - INF_ENGINE_PLATFORM - part of name of library directory representing its platform (default ubuntu_16.04)
#
-# HAVE_INF_ENGINE - True if Intel Inference Engine was found
-# INF_ENGINE_INCLUDE_DIRS - Inference Engine include folder
-# INF_ENGINE_LIBRARIES - Inference Engine libraries and it's dependencies
+# Result:
+# INF_ENGINE_TARGET - set to name of imported library target representing InferenceEngine
#
-macro(ie_fail)
- set(HAVE_INF_ENGINE FALSE)
- return()
-endmacro()
if(NOT HAVE_CXX11)
message(WARNING "DL Inference engine requires C++11. You can turn it on via ENABLE_CXX11=ON CMake flag.")
- ie_fail()
-endif()
-
-find_package(InferenceEngine QUIET)
-if(InferenceEngine_FOUND)
- set(INF_ENGINE_LIBRARIES "${InferenceEngine_LIBRARIES}")
- set(INF_ENGINE_INCLUDE_DIRS "${InferenceEngine_INCLUDE_DIRS}")
- set(INF_ENGINE_VERSION "${InferenceEngine_VERSION}")
- set(HAVE_INF_ENGINE TRUE)
- return()
+ return()
endif()
-ocv_check_environment_variables(INTEL_CVSDK_DIR INF_ENGINE_ROOT_DIR IE_PLUGINS_PATH)
+# =======================
-if(NOT INF_ENGINE_ROOT_DIR OR NOT EXISTS "${INF_ENGINE_ROOT_DIR}/include/inference_engine.hpp")
- set(ie_root_paths "${INF_ENGINE_ROOT_DIR}")
- if(DEFINED INTEL_CVSDK_DIR)
- list(APPEND ie_root_paths "${INTEL_CVSDK_DIR}/")
- list(APPEND ie_root_paths "${INTEL_CVSDK_DIR}/deployment_tools/inference_engine")
- endif()
+function(add_custom_ie_build _inc _lib _lib_rel _lib_dbg _msg)
+ if(NOT _inc OR NOT (_lib OR _lib_rel OR _lib_dbg))
+ return()
+ endif()
+ add_library(inference_engine UNKNOWN IMPORTED)
+ set_target_properties(inference_engine PROPERTIES
+ IMPORTED_LOCATION "${_lib}"
+ IMPORTED_IMPLIB_RELEASE "${_lib_rel}"
+ IMPORTED_IMPLIB_DEBUG "${_lib_dbg}"
+ INTERFACE_INCLUDE_DIRECTORIES "${_inc}"
+ )
+ find_library(omp_lib iomp5 PATHS "${INF_ENGINE_OMP_DIR}" NO_DEFAULT_PATH)
+ if(NOT omp_lib)
+ message(WARNING "OpenMP for IE have not been found. Set INF_ENGINE_OMP_DIR variable if you experience build errors.")
+ else()
+ set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${omp_lib}")
+ endif()
+ set(INF_ENGINE_VERSION "Unknown" CACHE STRING "")
+ set(INF_ENGINE_TARGET inference_engine PARENT_SCOPE)
+ message(STATUS "Detected InferenceEngine: ${_msg}")
+endfunction()
- if(NOT ie_root_paths)
- list(APPEND ie_root_paths "/opt/intel/computer_vision_sdk/deployment_tools/inference_engine/")
- endif()
+# ======================
- find_path(INF_ENGINE_ROOT_DIR include/inference_engine.hpp PATHS ${ie_root_paths})
- if(INF_ENGINE_ROOT_DIR MATCHES "-NOTFOUND$")
- unset(INF_ENGINE_ROOT_DIR CACHE)
- endif()
+find_package(InferenceEngine QUIET)
+if(InferenceEngine_FOUND)
+ set(INF_ENGINE_TARGET IE::inference_engine)
+ set(INF_ENGINE_VERSION "${InferenceEngine_VERSION}" CACHE STRING "")
+ message(STATUS "Detected InferenceEngine: cmake package")
endif()
-set(INF_ENGINE_INCLUDE_DIRS "${INF_ENGINE_ROOT_DIR}/include" CACHE PATH "Path to Inference Engine include directory")
-
-if(NOT INF_ENGINE_ROOT_DIR
- OR NOT EXISTS "${INF_ENGINE_ROOT_DIR}"
- OR NOT EXISTS "${INF_ENGINE_ROOT_DIR}/include/inference_engine.hpp"
-)
- message(WARNING "DL IE: Can't detect INF_ENGINE_ROOT_DIR location.")
- ie_fail()
+if(NOT INF_ENGINE_TARGET AND INF_ENGINE_LIB_DIRS AND INF_ENGINE_INCLUDE_DIRS)
+ find_path(ie_custom_inc "inference_engine.hpp" PATHS "${INF_ENGINE_INCLUDE_DIRS}" NO_DEFAULT_PATH)
+ find_library(ie_custom_lib "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}" NO_DEFAULT_PATH)
+ find_library(ie_custom_lib_rel "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}/Release" NO_DEFAULT_PATH)
+ find_library(ie_custom_lib_dbg "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}/Debug" NO_DEFAULT_PATH)
+ add_custom_ie_build("${ie_custom_inc}" "${ie_custom_lib}" "${ie_custom_lib_rel}" "${ie_custom_lib_dbg}" "INF_ENGINE_{INCLUDE,LIB}_DIRS")
endif()
-set(INF_ENGINE_LIBRARIES "")
-
-set(ie_lib_list inference_engine)
-
-if(NOT IS_ABSOLUTE "${IE_PLUGINS_PATH}")
- set(IE_PLUGINS_PATH "${INF_ENGINE_ROOT_DIR}/${IE_PLUGINS_PATH}")
+set(_loc "$ENV{INTEL_CVSDK_DIR}")
+if(NOT INF_ENGINE_TARGET AND _loc)
+ set(INF_ENGINE_PLATFORM "ubuntu_16.04" CACHE STRING "InferenceEngine platform (library dir)")
+ find_path(ie_custom_env_inc "inference_engine.hpp" PATHS "${_loc}/deployment_tools/inference_engine/include" NO_DEFAULT_PATH)
+ find_library(ie_custom_env_lib "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/${INF_ENGINE_PLATFORM}/intel64" NO_DEFAULT_PATH)
+ find_library(ie_custom_env_lib_rel "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Release" NO_DEFAULT_PATH)
+ find_library(ie_custom_env_lib_dbg "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Debug" NO_DEFAULT_PATH)
+ add_custom_ie_build("${ie_custom_env_inc}" "${ie_custom_env_lib}" "${ie_custom_env_lib_rel}" "${ie_custom_env_lib_dbg}" "OpenVINO (${_loc})")
endif()
-link_directories(
- ${INF_ENGINE_ROOT_DIR}/external/mkltiny_lnx/lib
- ${INF_ENGINE_ROOT_DIR}/external/cldnn/lib
-)
-
-foreach(lib ${ie_lib_list})
- find_library(${lib} NAMES ${lib} HINTS ${IE_PLUGINS_PATH})
- if(NOT ${lib})
- message(WARNING "DL IE: Can't find library: '${lib}'")
- ie_fail()
- endif()
- list(APPEND INF_ENGINE_LIBRARIES ${${lib}})
-endforeach()
+# Add more features to the target
-set(HAVE_INF_ENGINE TRUE)
+if(INF_ENGINE_TARGET)
+ if(NOT INF_ENGINE_RELEASE)
+ message(WARNING "InferenceEngine version have not been set, 2018R2 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
+ endif()
+ set(INF_ENGINE_RELEASE "2018020000" 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}"
+ )
+endif()
year = {2017},
organization = {IEEE}
}
+
+@ARTICLE{gonzalez,
+ title={Digital Image Fundamentals, Digital Imaging Processing},
+ author={Gonzalez, Rafael C and others},
+ year={1987},
+ publisher={Addison Wesley Publishing Company}
+}
+
+@ARTICLE{gruzman,
+ title={Цифровая обработка изображений в информационных системах},
+ author={Грузман, И.С. and Киричук, В.С. and Косых, В.П. and Перетягин, Г.И. and Спектор, А.А.},
+ year={2000},
+ publisher={Изд-во НГТУ Новосибирск}
+}
--- /dev/null
+Out-of-focus Deblur Filter {#tutorial_out_of_focus_deblur_filter}
+==========================
+
+Goal
+----
+
+In this tutorial you will learn:
+
+- what is a degradation image model
+- what is PSF of out-of-focus image
+- how to restore a blurred image
+- what is Wiener filter
+
+Theory
+------
+
+@note The explanation is based on the books @cite gonzalez and @cite gruzman. Also, you can refer to Matlab's tutorial [Image Deblurring in Matlab] and an article [SmartDeblur].
+@note An out-of-focus image on this page is a real world image. An out-of-focus was done manually by camera optics.
+
+### What is a degradation image model?
+
+A mathematical model of the image degradation in frequency domain representation is:
+
+\f[S = H\cdot U + N\f]
+
+where
+\f$S\f$ is a spectrum of blurred (degraded) image,
+\f$U\f$ is a spectrum of original true (undegraded) image,
+\f$H\f$ is frequency response of point spread function (PSF),
+\f$N\f$ is a spectrum of additive noise.
+
+Circular PSF is a good approximation of out-of-focus distortion. Such PSF is specified by only one parameter - radius \f$R\f$. Circular PSF is used in this work.
+
+![Circular point spread function](psf.png)
+
+### How to restore an blurred image?
+
+The objective of restoration (deblurring) is to obtain an estimate of the original image. Restoration formula in frequency domain is:
+
+\f[U' = H_w\cdot S\f]
+
+where
+\f$U'\f$ is spectrum of estimation of original image \f$U\f$,
+\f$H_w\f$ is restoration filter, for example, Wiener filter.
+
+### What is Wiener filter?
+
+Wiener filter is a way to restore a blurred image. Let's suppose that PSF is a real and symmetric signal, a power spectrum of the original true image and noise are not known,
+then simplified Wiener formula is:
+
+\f[H_w = \frac{H}{|H|^2+\frac{1}{SNR}} \f]
+
+where
+\f$SNR\f$ is signal-to-noise ratio.
+
+So, in order to recover an out-of-focus image by Wiener filter, it needs to know \f$SNR\f$ and \f$R\f$ of circular PSF.
+
+
+Source code
+-----------
+
+You can find source code in the `samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp` of the OpenCV source code library.
+
+@include cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp
+
+Explanation
+-----------
+
+An out-of-focus image recovering algorithm consists of PSF generation, Wiener filter generation and filtering an blurred image in frequency domain:
+@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp main
+
+A function calcPSF() forms an circular PSF according to input parameter radius \f$R\f$:
+@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp calcPSF
+
+A function calcWnrFilter() synthesizes simplified Wiener filter \f$H_w\f$ according to formula described above:
+@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp calcWnrFilter
+
+A function fftshift() rearranges PSF. This code was just copied from tutorial @ref tutorial_discrete_fourier_transform "Discrete Fourier Transform":
+@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp fftshift
+
+A function filter2DFreq() filters an blurred image in frequency domain:
+@snippet samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp filter2DFreq
+
+Result
+------
+
+Below you can see real out-of-focus image:
+![Out-of-focus image](images/original.jpg)
+
+
+Below result was done by \f$R\f$ = 53 and \f$SNR\f$ = 5200 parameters:
+![The restored (deblurred) image](images/recovered.jpg)
+
+The Wiener filter was used, values of \f$R\f$ and \f$SNR\f$ were selected manually to give the best possible visual result.
+We can see that the result is not perfect, but it gives us a hint to the image content. With some difficulty, the text is readable.
+
+@note The parameter \f$R\f$ is the most important. So you should adjust \f$R\f$ first, then \f$SNR\f$.
+@note Sometimes you can observe the ringing effect in an restored image. This effect can be reduced by several methods. For example, you can taper input image edges.
+
+You can also find a quick video demonstration of this on
+[YouTube](https://youtu.be/0bEcE4B0XP4).
+@youtube{0bEcE4B0XP4}
+
+References
+------
+- [Image Deblurring in Matlab] - Image Deblurring in Matlab
+- [SmartDeblur] - SmartDeblur site
+
+<!-- invisible references list -->
+[Digital Image Processing]: http://web.ipac.caltech.edu/staff/fmasci/home/astro_refs/Digital_Image_Processing_2ndEd.pdf
+[Image Deblurring in Matlab]: https://www.mathworks.com/help/images/image-deblurring.html
+[SmartDeblur]: http://yuzhikov.com/articles/BlurredImagesRestoration1.htm
*Author:* Theodore Tsesmelis
Where we learn to segment objects using Laplacian filtering, the Distance Transformation and the Watershed algorithm.
+
+- @subpage tutorial_out_of_focus_deblur_filter
+
+ *Languages:* C++
+
+ *Compatibility:* \> OpenCV 2.0
+
+ *Author:* Karpushin Vladislav
+
+ You will learn how to recover an out-of-focus image by Wiener filter.
// but some of AVX2 intrinsics get v256_ prefix instead of v_, e.g. v256_load() vs v_load().
// Correspondingly, the wide intrinsics (which are mapped to the "widest"
// available instruction set) will get vx_ prefix
-// (and will be mapped to v256_ counterparts) (e.g. vx_load() => v245_load())
+// (and will be mapped to v256_ counterparts) (e.g. vx_load() => v256_load())
#if CV_AVX2
#include "opencv2/core/hal/intrin_avx.hpp"
inline vtyp vx_setzero_##short_typ() { return prefix##_setzero_##short_typ(); } \
inline vtyp vx_##loadsfx(const typ* ptr) { return prefix##_##loadsfx(ptr); } \
inline vtyp vx_##loadsfx##_aligned(const typ* ptr) { return prefix##_##loadsfx##_aligned(ptr); } \
+ inline vtyp vx_##loadsfx##_low(const typ* ptr) { return prefix##_##loadsfx##_low(ptr); } \
+ inline vtyp vx_##loadsfx##_halves(const typ* ptr0, const typ* ptr1) { return prefix##_##loadsfx##_halves(ptr0, ptr1); } \
inline void vx_store(typ* ptr, const vtyp& v) { return v_store(ptr, v); } \
inline void vx_store_aligned(typ* ptr, const vtyp& v) { return v_store_aligned(ptr, v); }
#define CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(typ, wtyp, prefix) \
-inline wtyp vx_load_expand(const typ* ptr) { return prefix##_load_expand(ptr); }
+ inline wtyp vx_load_expand(const typ* ptr) { return prefix##_load_expand(ptr); }
#define CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND_Q(typ, qtyp, prefix) \
-inline qtyp vx_load_expand_q(const typ* ptr) { return prefix##_load_expand_q(ptr); }
+ inline qtyp vx_load_expand_q(const typ* ptr) { return prefix##_load_expand_q(ptr); }
#define CV_INTRIN_DEFINE_WIDE_INTRIN_WITH_EXPAND(typ, vtyp, short_typ, wtyp, qtyp, prefix, loadsfx) \
CV_INTRIN_DEFINE_WIDE_INTRIN(typ, vtyp, short_typ, prefix, loadsfx) \
CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(v256)
CV_INTRIN_DEFINE_WIDE_INTRIN(double, v_float64, f64, v256, load)
inline void vx_cleanup() { v256_cleanup(); }
-#elif CV_SIMD128
+#elif CV_SIMD128 || CV_SIMD128_CPP
typedef v_uint8x16 v_uint8;
typedef v_int8x16 v_int8;
typedef v_uint16x8 v_uint16;
inline v_float16x16 v256_load_f16_aligned(const short* ptr)
{ return v_float16x16(_mm256_load_si256((const __m256i*)ptr)); }
+inline v_float16x16 v256_load_f16_low(const short* ptr)
+{ return v_float16x16(v256_load_low(ptr).val); }
+inline v_float16x16 v256_load_f16_halves(const short* ptr0, const short* ptr1)
+{ return v_float16x16(v256_load_halves(ptr0, ptr1).val); }
+
inline void v_store(short* ptr, const v_float16x16& a)
{ _mm256_storeu_si256((__m256i*)ptr, a.val); }
inline void v_store_aligned(short* ptr, const v_float16x16& a)
template<int imm>
inline v_uint8x32 v_rotate_left(const v_uint8x32& a, const v_uint8x32& b)
{
- __m256i swap = _mm256_permute2x128_si256(a.val, b.val, 0x03);
-
- switch(imm)
- {
- case 0: return a;
- case 32: return b;
- case 16: return v_uint8x32(swap);
- }
+ enum {IMM_R = (16 - imm) & 0xFF};
+ enum {IMM_R2 = (32 - imm) & 0xFF};
- if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(a.val, swap, 16 - imm));
- if (imm < 32) return v_uint8x32(_mm256_alignr_epi8(swap, b.val, 32 - imm));
+ if (imm == 0) return a;
+ if (imm == 32) return b;
+ if (imm > 32) return v_uint8x32();
- return v_uint8x32();
+ __m256i swap = _mm256_permute2x128_si256(a.val, b.val, 0x03);
+ if (imm == 16) return v_uint8x32(swap);
+ if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(a.val, swap, IMM_R));
+ return v_uint8x32(_mm256_alignr_epi8(swap, b.val, IMM_R2)); // imm < 32
}
template<int imm>
inline v_uint8x32 v_rotate_right(const v_uint8x32& a, const v_uint8x32& b)
{
- __m256i swap = _mm256_permute2x128_si256(a.val, b.val, 0x21);
-
- switch(imm)
- {
- case 0: return a;
- case 32: return b;
- case 16: return v_uint8x32(swap);
- }
+ enum {IMM_L = (imm - 16) & 0xFF};
- if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(swap, a.val, imm));
- if (imm < 32) return v_uint8x32(_mm256_alignr_epi8(b.val, swap, imm - 16));
+ if (imm == 0) return a;
+ if (imm == 32) return b;
+ if (imm > 32) return v_uint8x32();
- return v_uint8x32();
+ __m256i swap = _mm256_permute2x128_si256(a.val, b.val, 0x21);
+ if (imm == 16) return v_uint8x32(swap);
+ if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(swap, a.val, imm));
+ return v_uint8x32(_mm256_alignr_epi8(b.val, swap, IMM_L));
}
template<int imm>
inline v_uint8x32 v_rotate_left(const v_uint8x32& a)
{
- v_uint8x32 res;
+ enum {IMM_L = (imm - 16) & 0xFF};
+ enum {IMM_R = (16 - imm) & 0xFF};
+
+ if (imm == 0) return a;
+ if (imm > 32) return v_uint8x32();
+
// ESAC control[3] ? [127:0] = 0
__m256i swapz = _mm256_permute2x128_si256(a.val, a.val, _MM_SHUFFLE(0, 0, 2, 0));
-
- if (imm == 0)
- return a;
- if (imm == 16)
- res.val = swapz;
- else if (imm < 16)
- res.val = _mm256_alignr_epi8(a.val, swapz, 16 - imm);
- else if (imm < 32)
- res.val = _mm256_slli_si256(swapz, imm - 16);
- else
- return v_uint8x32();
- return res;
+ if (imm == 16) return v_uint8x32(swapz);
+ if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(a.val, swapz, IMM_R));
+ return v_uint8x32(_mm256_slli_si256(swapz, IMM_L));
}
template<int imm>
inline v_uint8x32 v_rotate_right(const v_uint8x32& a)
{
- v_uint8x32 res;
+ enum {IMM_L = (imm - 16) & 0xFF};
+
+ if (imm == 0) return a;
+ if (imm > 32) return v_uint8x32();
+
// ESAC control[3] ? [127:0] = 0
__m256i swapz = _mm256_permute2x128_si256(a.val, a.val, _MM_SHUFFLE(2, 0, 0, 1));
-
- if (imm == 0)
- return a;
- if (imm == 16)
- res.val = swapz;
- else if (imm < 16)
- res.val = _mm256_alignr_epi8(swapz, a.val, imm);
- else if (imm < 32)
- res.val = _mm256_srli_si256(swapz, imm - 16);
- else
- return v_uint8x32();
- return res;
-}
-
-#define OPENCV_HAL_IMPL_AVX_ROTATE_CAST(intrin, _Tpvec, cast) \
- template<int imm> \
- inline _Tpvec intrin(const _Tpvec& a, const _Tpvec& b) \
- { \
- const int w = sizeof(typename _Tpvec::lane_type); \
- v_uint8x32 ret = intrin<imm*w>(v_reinterpret_as_u8(a), \
- v_reinterpret_as_u8(b)); \
- return _Tpvec(cast(ret.val)); \
- } \
- template<int imm> \
- inline _Tpvec intrin(const _Tpvec& a) \
- { \
- const int w = sizeof(typename _Tpvec::lane_type); \
- v_uint8x32 ret = intrin<imm*w>(v_reinterpret_as_u8(a)); \
- return _Tpvec(cast(ret.val)); \
+ if (imm == 16) return v_uint8x32(swapz);
+ if (imm < 16) return v_uint8x32(_mm256_alignr_epi8(swapz, a.val, imm));
+ return v_uint8x32(_mm256_srli_si256(swapz, IMM_L));
+}
+
+#define OPENCV_HAL_IMPL_AVX_ROTATE_CAST(intrin, _Tpvec, cast) \
+ template<int imm> \
+ inline _Tpvec intrin(const _Tpvec& a, const _Tpvec& b) \
+ { \
+ enum {IMMxW = imm * sizeof(typename _Tpvec::lane_type)}; \
+ v_uint8x32 ret = intrin<IMMxW>(v_reinterpret_as_u8(a), \
+ v_reinterpret_as_u8(b)); \
+ return _Tpvec(cast(ret.val)); \
+ } \
+ template<int imm> \
+ inline _Tpvec intrin(const _Tpvec& a) \
+ { \
+ enum {IMMxW = imm * sizeof(typename _Tpvec::lane_type)}; \
+ v_uint8x32 ret = intrin<IMMxW>(v_reinterpret_as_u8(a)); \
+ return _Tpvec(cast(ret.val)); \
}
#define OPENCV_HAL_IMPL_AVX_ROTATE(_Tpvec) \
#endif
}
+#ifndef vdup_n_f16
+ #define vdup_n_f16(v) (float16x4_t){v, v, v, v}
+#endif
struct v_float16x8
{
inline v_float16x8 v_load_f16_aligned(const short* ptr)
{ return v_float16x8(cv_vld1q_f16(ptr)); }
+inline v_float16x8 v_load_f16_low(const short* ptr)
+{ return v_float16x8(vcombine_f16(cv_vld1_f16(ptr), vdup_n_f16((float16_t)0))); }
+inline v_float16x8 v_load_f16_halves(const short* ptr0, const short* ptr1)
+{ return v_float16x8(vcombine_f16(cv_vld1_f16(ptr0), cv_vld1_f16(ptr1))); }
+
inline void v_store(short* ptr, const v_float16x8& a)
{ cv_vst1q_f16(ptr, a.val); }
inline void v_store_aligned(short* ptr, const v_float16x8& a)
inline v_float16x8 v_load_f16_aligned(const short* ptr)
{ return v_float16x8(_mm_load_si128((const __m128i*)ptr)); }
+inline v_float16x8 v_load_f16_low(const short* ptr)
+{ return v_float16x8(v_load_low(ptr).val); }
+inline v_float16x8 v_load_f16_halves(const short* ptr0, const short* ptr1)
+{ return v_float16x8(v_load_halves(ptr0, ptr1).val); }
+
inline void v_store(short* ptr, const v_float16x8& a)
{ _mm_storeu_si128((__m128i*)ptr, a.val); }
inline void v_store_aligned(short* ptr, const v_float16x8& a)
CV_Assert( op == CMP_LT || op == CMP_LE || op == CMP_EQ ||
op == CMP_NE || op == CMP_GE || op == CMP_GT );
- if(_src1.empty() || _src2.empty())
+ CV_Assert(_src1.empty() == _src2.empty());
+ if (_src1.empty() && _src2.empty())
{
_dst.release();
return;
{
CV_INSTRUMENT_REGION()
- if (empty()) return *this;
+ if (this->empty())
+ return *this;
const Mat* arrays[] = { this };
uchar* dptr;
void Mat::push_back_(const void* elem)
{
- int r = size.p[0];
+ size_t r = size.p[0];
if( isSubmatrix() || dataend + step.p[0] > datalimit )
reserve( std::max(r + 1, (r*3+1)/2) );
size_t esz = elemSize();
memcpy(data + r*step.p[0], elem, esz);
- size.p[0] = r + 1;
+ size.p[0] = int(r + 1);
dataend += step.p[0];
uint64 tsz = size.p[0];
for( int i = 1; i < dims; i++ )
void Mat::push_back(const Mat& elems)
{
- int r = size.p[0], delta = elems.size.p[0];
+ size_t r = size.p[0];
+ size_t delta = elems.size.p[0];
if( delta == 0 )
return;
if( this == &elems )
size.p[0] = elems.size.p[0];
bool eq = size == elems.size;
- size.p[0] = r;
+ size.p[0] = int(r);
if( !eq )
CV_Error(CV_StsUnmatchedSizes, "Pushed vector length is not equal to matrix row length");
if( type() != elems.type() )
if( isSubmatrix() || dataend + step.p[0]*delta > datalimit )
reserve( std::max(r + delta, (r*3+1)/2) );
- size.p[0] += delta;
+ size.p[0] += int(delta);
dataend += step.p[0]*delta;
//updateContinuityFlag(*this);
memcpy(data + r*step.p[0], elems.data, elems.total()*elems.elemSize());
else
{
- Mat part = rowRange(r, r + delta);
+ Mat part = rowRange(int(r), int(r + delta));
elems.copyTo(part);
}
}
{
CV_INSTRUMENT_REGION()
+ CV_Assert(!_src.empty());
+ CV_Assert( _mask.empty() || _mask.type() == CV_8UC1 );
+
CV_OCL_RUN(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2,
ocl_meanStdDev(_src, _mean, _sdv, _mask))
Mat src = _src.getMat(), mask = _mask.getMat();
- CV_Assert( mask.empty() || mask.type() == CV_8UC1 );
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_MEAN_STDDEV>(src.cols, src.rows),
openvx_meanStdDev(src, _mean, _sdv, mask))
static void CL_CALLBACK oclCleanupCallback(cl_event e, cl_int, void *p)
{
- ((cv::ocl::Kernel::Impl*)p)->finit(e);
+ try
+ {
+ ((cv::ocl::Kernel::Impl*)p)->finit(e);
+ }
+ catch (const cv::Exception& exc)
+ {
+ CV_LOG_ERROR(NULL, "OCL: Unexpected OpenCV exception in OpenCL callback: " << exc.what());
+ }
+ catch (const std::exception& exc)
+ {
+ CV_LOG_ERROR(NULL, "OCL: Unexpected C++ exception in OpenCL callback: " << exc.what());
+ }
+ catch (...)
+ {
+ CV_LOG_ERROR(NULL, "OCL: Unexpected unknown C++ exception in OpenCL callback");
+ }
}
}
void RNG::fill( InputOutputArray _mat, int disttype,
InputArray _param1arg, InputArray _param2arg, bool saturateRange )
{
- if (_mat.empty())
- return;
+ CV_Assert(!_mat.empty());
+
Mat mat = _mat.getMat(), _param1 = _param1arg.getMat(), _param2 = _param2arg.getMat();
int depth = mat.depth(), cn = mat.channels();
AutoBuffer<double> _parambuf;
TEST(Compare, empty)
{
cv::Mat temp, dst1, dst2;
- cv::compare(temp, temp, dst1, cv::CMP_EQ);
- dst2 = temp > 5;
-
+ EXPECT_NO_THROW(cv::compare(temp, temp, dst1, cv::CMP_EQ));
EXPECT_TRUE(dst1.empty());
- EXPECT_TRUE(dst2.empty());
+ EXPECT_THROW(dst2 = temp > 5, cv::Exception);
}
TEST(Compare, regression_8999)
Mat_<double> A(4,1); A << 1, 3, 2, 4;
Mat_<double> B(1,1); B << 2;
Mat C;
- ASSERT_ANY_THROW({
- cv::compare(A, B, C, CMP_LT);
- });
+ EXPECT_THROW(cv::compare(A, B, C, CMP_LT), cv::Exception);
}
namespace opencv_test { namespace {
-class Core_ConcatenationTest : public cvtest::BaseTest
+TEST(Core_Concatenation, empty)
{
-public:
- Core_ConcatenationTest(bool horizontal, bool firstEmpty, bool secondEmpty);
-protected:
- int prepare_test_case( int );
- void run_func();
- int validate_test_results( int );
+ const Mat mat0x5(0,5, CV_8U, Scalar::all(1));
+ const Mat mat10x5(10,5, CV_8U, Scalar::all(1));
+ const Mat mat20x5(20,5, CV_8U, Scalar::all(1));
- Mat mat0x5;
- Mat mat10x5;
- Mat mat20x5;
-
- Mat mat5x0;
- Mat mat5x10;
- Mat mat5x20;
+ const Mat mat5x0(5,0, CV_8U, Scalar::all(1));
+ const Mat mat5x10(5,10, CV_8U, Scalar::all(1));
+ const Mat mat5x20(5,20, CV_8U, Scalar::all(1));
Mat result;
- bool horizontal;
- bool firstEmpty;
- bool secondEmpty;
-
-private:
- static bool areEqual(const Mat& m1, const Mat& m2);
-
-};
-
-Core_ConcatenationTest::Core_ConcatenationTest(bool horizontal_, bool firstEmpty_, bool secondEmpty_)
- : horizontal(horizontal_)
- , firstEmpty(firstEmpty_)
- , secondEmpty(secondEmpty_)
-{
- test_case_count = 1;
-
- mat0x5 = Mat::ones(0,5, CV_8U);
- mat10x5 = Mat::ones(10,5, CV_8U);
- mat20x5 = Mat::ones(20,5, CV_8U);
-
- mat5x0 = Mat::ones(5,0, CV_8U);
- mat5x10 = Mat::ones(5,10, CV_8U);
- mat5x20 = Mat::ones(5,20, CV_8U);
-}
-
-int Core_ConcatenationTest::prepare_test_case( int test_case_idx )
-{
- cvtest::BaseTest::prepare_test_case( test_case_idx );
- return 1;
-}
-
-void Core_ConcatenationTest::run_func()
-{
- if (horizontal)
- {
- cv::hconcat((firstEmpty ? mat5x0 : mat5x10),
- (secondEmpty ? mat5x0 : mat5x10),
- result);
- } else {
- cv::vconcat((firstEmpty ? mat0x5 : mat10x5),
- (secondEmpty ? mat0x5 : mat10x5),
- result);
- }
-}
-
-int Core_ConcatenationTest::validate_test_results( int )
-{
- Mat expected;
-
- if (firstEmpty && secondEmpty)
- expected = (horizontal ? mat5x0 : mat0x5);
- else if ((firstEmpty && !secondEmpty) || (!firstEmpty && secondEmpty))
- expected = (horizontal ? mat5x10 : mat10x5);
- else
- expected = (horizontal ? mat5x20 : mat20x5);
-
- if (areEqual(expected, result))
- {
- return cvtest::TS::OK;
- } else
- {
- ts->printf( cvtest::TS::LOG, "Concatenation failed");
- ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
- }
-
- return cvtest::TS::OK;
-}
-
-bool Core_ConcatenationTest::areEqual(const Mat &m1, const Mat &m2)
-{
- return m1.size() == m2.size()
- && m1.type() == m2.type()
- && countNonZero(m1 != m2) == 0;
+ cv::hconcat(mat5x0, mat5x0, result);
+ EXPECT_MAT_N_DIFF(result, mat5x0, 0);
+ cv::hconcat(mat5x0, mat5x10, result);
+ EXPECT_MAT_N_DIFF(result, mat5x10, 0);
+ cv::hconcat(mat5x10, mat5x0, result);
+ EXPECT_MAT_N_DIFF(result, mat5x10, 0);
+ cv::hconcat(mat5x10, mat5x10, result);
+ EXPECT_MAT_N_DIFF(result, mat5x20, 0);
+
+ cv::vconcat(mat0x5, mat0x5, result);
+ EXPECT_MAT_N_DIFF(result, mat0x5, 0);
+ cv::vconcat(mat0x5, mat10x5, result);
+ EXPECT_MAT_N_DIFF(result, mat10x5, 0);
+ cv::vconcat(mat10x5, mat0x5, result);
+ EXPECT_MAT_N_DIFF(result, mat10x5, 0);
+ cv::vconcat(mat10x5, mat10x5, result);
+ EXPECT_MAT_N_DIFF(result, mat20x5, 0);
}
-TEST(Core_Concatenation, hconcat_empty_nonempty) { Core_ConcatenationTest test(true, true, false); test.safe_run(); }
-TEST(Core_Concatenation, hconcat_nonempty_empty) { Core_ConcatenationTest test(true, false, true); test.safe_run(); }
-TEST(Core_Concatenation, hconcat_empty_empty) { Core_ConcatenationTest test(true, true, true); test.safe_run(); }
-
-TEST(Core_Concatenation, vconcat_empty_nonempty) { Core_ConcatenationTest test(false, true, false); test.safe_run(); }
-TEST(Core_Concatenation, vconcat_nonempty_empty) { Core_ConcatenationTest test(false, false, true); test.safe_run(); }
-TEST(Core_Concatenation, vconcat_empty_empty) { Core_ConcatenationTest test(false, true, true); test.safe_run(); }
-
}} // namespace
--- /dev/null
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+#include "test_precomp.hpp"
+#include "test_intrin.simd.hpp"
\ No newline at end of file
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
+#include "test_intrin.simd.hpp"
-#include "test_intrin_utils.hpp"
-
-#define CV_CPU_SIMD_FILENAME "test_intrin_utils.hpp"
+#define CV_CPU_SIMD_FILENAME "test_intrin.simd.hpp"
#define CV_CPU_DISPATCH_MODE FP16
#include "opencv2/core/private/cv_cpu_include_simd_declarations.hpp"
-
-using namespace cv;
+#define CV_CPU_DISPATCH_MODE AVX2
+#include "opencv2/core/private/cv_cpu_include_simd_declarations.hpp"
namespace opencv_test { namespace hal {
using namespace CV_CPU_OPTIMIZATION_NAMESPACE;
-//============= 8-bit integer =====================================================================
-
-TEST(hal_intrin, uint8x16) {
- TheTest<v_uint8x16>()
- .test_loadstore()
- .test_interleave()
- .test_expand()
- .test_expand_q()
- .test_addsub()
- .test_addsub_wrap()
- .test_cmp()
- .test_logic()
- .test_min_max()
- .test_absdiff()
- .test_mask()
- .test_popcount()
- .test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()
- .test_pack_u<1>().test_pack_u<2>().test_pack_u<3>().test_pack_u<8>()
- .test_unpack()
- .test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()
- .test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()
- ;
-}
+TEST(hal_intrin, uint8x16)
+{ test_hal_intrin_uint8(); }
-TEST(hal_intrin, int8x16) {
- TheTest<v_int8x16>()
- .test_loadstore()
- .test_interleave()
- .test_expand()
- .test_expand_q()
- .test_addsub()
- .test_addsub_wrap()
- .test_cmp()
- .test_logic()
- .test_min_max()
- .test_absdiff()
- .test_abs()
- .test_mask()
- .test_popcount()
- .test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()
- .test_unpack()
- .test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()
- .test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()
- ;
-}
+TEST(hal_intrin, int8x16)
+{ test_hal_intrin_int8(); }
-//============= 16-bit integer =====================================================================
-
-TEST(hal_intrin, uint16x8) {
- TheTest<v_uint16x8>()
- .test_loadstore()
- .test_interleave()
- .test_expand()
- .test_addsub()
- .test_addsub_wrap()
- .test_mul()
- .test_mul_expand()
- .test_cmp()
- .test_shift<1>()
- .test_shift<8>()
- .test_logic()
- .test_min_max()
- .test_absdiff()
- .test_reduce()
- .test_mask()
- .test_popcount()
- .test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()
- .test_pack_u<1>().test_pack_u<2>().test_pack_u<7>().test_pack_u<16>()
- .test_unpack()
- .test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()
- .test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()
- ;
-}
+TEST(hal_intrin, uint16x8)
+{ test_hal_intrin_uint16(); }
-TEST(hal_intrin, int16x8) {
- TheTest<v_int16x8>()
- .test_loadstore()
- .test_interleave()
- .test_expand()
- .test_addsub()
- .test_addsub_wrap()
- .test_mul()
- .test_mul_expand()
- .test_cmp()
- .test_shift<1>()
- .test_shift<8>()
- .test_dot_prod()
- .test_logic()
- .test_min_max()
- .test_absdiff()
- .test_abs()
- .test_reduce()
- .test_mask()
- .test_popcount()
- .test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()
- .test_unpack()
- .test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()
- .test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()
- ;
-}
+TEST(hal_intrin, int16x8)
+{ test_hal_intrin_int16(); }
-//============= 32-bit integer =====================================================================
-
-TEST(hal_intrin, uint32x4) {
- TheTest<v_uint32x4>()
- .test_loadstore()
- .test_interleave()
- .test_expand()
- .test_addsub()
- .test_mul()
- .test_mul_expand()
- .test_cmp()
- .test_shift<1>()
- .test_shift<8>()
- .test_logic()
- .test_min_max()
- .test_absdiff()
- .test_reduce()
- .test_mask()
- .test_popcount()
- .test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()
- .test_unpack()
- .test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
- .test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
- .test_transpose()
- ;
-}
+TEST(hal_intrin, int32x4)
+{ test_hal_intrin_int32(); }
-TEST(hal_intrin, int32x4) {
- TheTest<v_int32x4>()
- .test_loadstore()
- .test_interleave()
- .test_expand()
- .test_addsub()
- .test_mul()
- .test_abs()
- .test_cmp()
- .test_popcount()
- .test_shift<1>().test_shift<8>()
- .test_logic()
- .test_min_max()
- .test_absdiff()
- .test_reduce()
- .test_mask()
- .test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()
- .test_unpack()
- .test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
- .test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
- .test_float_cvt32()
- .test_float_cvt64()
- .test_transpose()
- ;
-}
+TEST(hal_intrin, uint32x4)
+{ test_hal_intrin_uint32(); }
-//============= 64-bit integer =====================================================================
-
-TEST(hal_intrin, uint64x2) {
- TheTest<v_uint64x2>()
- .test_loadstore()
- .test_addsub()
- .test_shift<1>().test_shift<8>()
- .test_logic()
- .test_extract<0>().test_extract<1>()
- .test_rotate<0>().test_rotate<1>()
- ;
-}
+TEST(hal_intrin, uint64x2)
+{ test_hal_intrin_uint64(); }
-TEST(hal_intrin, int64x2) {
- TheTest<v_int64x2>()
- .test_loadstore()
- .test_addsub()
- .test_shift<1>().test_shift<8>()
- .test_logic()
- .test_extract<0>().test_extract<1>()
- .test_rotate<0>().test_rotate<1>()
- ;
-}
+TEST(hal_intrin, int64x2)
+{ test_hal_intrin_int64(); }
-//============= Floating point =====================================================================
-
-TEST(hal_intrin, float32x4) {
- TheTest<v_float32x4>()
- .test_loadstore()
- .test_interleave()
- .test_interleave_2channel()
- .test_addsub()
- .test_mul()
- .test_div()
- .test_cmp()
- .test_sqrt_abs()
- .test_min_max()
- .test_float_absdiff()
- .test_reduce()
- .test_mask()
- .test_unpack()
- .test_float_math()
- .test_float_cvt64()
- .test_matmul()
- .test_transpose()
- .test_reduce_sum4()
- .test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
- .test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
- ;
-}
+TEST(hal_intrin, float32x4)
+{ test_hal_intrin_float32(); }
-#if CV_SIMD128_64F
-TEST(hal_intrin, float64x2) {
- TheTest<v_float64x2>()
- .test_loadstore()
- .test_addsub()
- .test_mul()
- .test_div()
- .test_cmp()
- .test_sqrt_abs()
- .test_min_max()
- .test_float_absdiff()
- .test_mask()
- .test_unpack()
- .test_float_math()
- .test_float_cvt32()
- .test_extract<0>().test_extract<1>()
- .test_rotate<0>().test_rotate<1>()
- ;
-}
-#endif
+TEST(hal_intrin, float64x2)
+{ test_hal_intrin_float64(); }
-TEST(hal_intrin,float16)
+TEST(hal_intrin, float16x8)
{
CV_CPU_CALL_FP16_(test_hal_intrin_float16, ());
throw SkipTestException("Unsupported hardware: FP16 is not available");
}
-}}
+#define DISPATCH_SIMD_MODES AVX2
+#define DISPATCH_SIMD_NAME "SIMD256"
+#define DISPATCH_SIMD(fun) \
+ do { \
+ CV_CPU_DISPATCH(fun, (), DISPATCH_SIMD_MODES); \
+ throw SkipTestException( \
+ "Unsupported hardware: " \
+ DISPATCH_SIMD_NAME \
+ " is not available" \
+ ); \
+ } while(0)
+
+TEST(hal_intrin256, uint8x32)
+{ DISPATCH_SIMD(test_hal_intrin_uint8); }
+
+TEST(hal_intrin256, int8x32)
+{ DISPATCH_SIMD(test_hal_intrin_int8); }
+
+TEST(hal_intrin256, uint16x16)
+{ DISPATCH_SIMD(test_hal_intrin_uint16); }
+
+TEST(hal_intrin256, int16x16)
+{ DISPATCH_SIMD(test_hal_intrin_int16); }
+
+TEST(hal_intrin256, uint32x8)
+{ DISPATCH_SIMD(test_hal_intrin_uint32); }
+
+TEST(hal_intrin256, int32x8)
+{ DISPATCH_SIMD(test_hal_intrin_int32); }
+
+TEST(hal_intrin256, uint64x4)
+{ DISPATCH_SIMD(test_hal_intrin_uint64); }
+
+TEST(hal_intrin256, int64x4)
+{ DISPATCH_SIMD(test_hal_intrin_int64); }
+
+TEST(hal_intrin256, float32x8)
+{ DISPATCH_SIMD(test_hal_intrin_float32); }
+
+TEST(hal_intrin256, float64x4)
+{ DISPATCH_SIMD(test_hal_intrin_float64); }
+
+TEST(hal_intrin256, float16x16)
+{
+ if (!CV_CPU_HAS_SUPPORT_FP16)
+ throw SkipTestException("Unsupported hardware: FP16 is not available");
+ DISPATCH_SIMD(test_hal_intrin_float16);
+}
+
+}} // namespace
\ No newline at end of file
void test_hal_intrin_float16()
{
- TheTest<v_float16x8>()
+ TheTest<v_float16>()
.test_loadstore_fp16()
.test_float_cvt_fp16()
;
--- /dev/null
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+#include "test_precomp.hpp"
+#include "test_intrin_utils.hpp"
+
+namespace opencv_test { namespace hal {
+CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
+
+void test_hal_intrin_uint8();
+void test_hal_intrin_int8();
+void test_hal_intrin_uint16();
+void test_hal_intrin_int16();
+void test_hal_intrin_uint32();
+void test_hal_intrin_int32();
+void test_hal_intrin_uint64();
+void test_hal_intrin_int64();
+void test_hal_intrin_float32();
+void test_hal_intrin_float64();
+
+#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
+
+//============= 8-bit integer =====================================================================
+
+void test_hal_intrin_uint8()
+{
+ TheTest<v_uint8>()
+ .test_loadstore()
+ .test_interleave()
+ .test_expand()
+ .test_expand_q()
+ .test_addsub()
+ .test_addsub_wrap()
+ .test_cmp()
+ .test_logic()
+ .test_min_max()
+ .test_absdiff()
+ .test_mask()
+ .test_popcount()
+ .test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()
+ .test_pack_u<1>().test_pack_u<2>().test_pack_u<3>().test_pack_u<8>()
+ .test_unpack()
+ .test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()
+ .test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()
+ ;
+
+#if CV_SIMD256
+ TheTest<v_uint8>()
+ .test_pack<9>().test_pack<10>().test_pack<13>().test_pack<15>()
+ .test_pack_u<9>().test_pack_u<10>().test_pack_u<13>().test_pack_u<15>()
+ .test_extract<16>().test_extract<17>().test_extract<23>().test_extract<31>()
+ .test_rotate<16>().test_rotate<17>().test_rotate<23>().test_rotate<31>()
+ ;
+#endif
+}
+
+void test_hal_intrin_int8()
+{
+ TheTest<v_int8>()
+ .test_loadstore()
+ .test_interleave()
+ .test_expand()
+ .test_expand_q()
+ .test_addsub()
+ .test_addsub_wrap()
+ .test_cmp()
+ .test_logic()
+ .test_min_max()
+ .test_absdiff()
+ .test_abs()
+ .test_mask()
+ .test_popcount()
+ .test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()
+ .test_unpack()
+ .test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()
+ .test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()
+ ;
+}
+
+//============= 16-bit integer =====================================================================
+
+void test_hal_intrin_uint16()
+{
+ TheTest<v_uint16>()
+ .test_loadstore()
+ .test_interleave()
+ .test_expand()
+ .test_addsub()
+ .test_addsub_wrap()
+ .test_mul()
+ .test_mul_expand()
+ .test_cmp()
+ .test_shift<1>()
+ .test_shift<8>()
+ .test_logic()
+ .test_min_max()
+ .test_absdiff()
+ .test_reduce()
+ .test_mask()
+ .test_popcount()
+ .test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()
+ .test_pack_u<1>().test_pack_u<2>().test_pack_u<7>().test_pack_u<16>()
+ .test_unpack()
+ .test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()
+ .test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()
+ ;
+}
+
+void test_hal_intrin_int16()
+{
+ TheTest<v_int16>()
+ .test_loadstore()
+ .test_interleave()
+ .test_expand()
+ .test_addsub()
+ .test_addsub_wrap()
+ .test_mul()
+ .test_mul_expand()
+ .test_cmp()
+ .test_shift<1>()
+ .test_shift<8>()
+ .test_dot_prod()
+ .test_logic()
+ .test_min_max()
+ .test_absdiff()
+ .test_abs()
+ .test_reduce()
+ .test_mask()
+ .test_popcount()
+ .test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()
+ .test_unpack()
+ .test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()
+ .test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()
+ ;
+}
+
+//============= 32-bit integer =====================================================================
+
+void test_hal_intrin_uint32()
+{
+ TheTest<v_uint32>()
+ .test_loadstore()
+ .test_interleave()
+ .test_expand()
+ .test_addsub()
+ .test_mul()
+ .test_mul_expand()
+ .test_cmp()
+ .test_shift<1>()
+ .test_shift<8>()
+ .test_logic()
+ .test_min_max()
+ .test_absdiff()
+ .test_reduce()
+ .test_mask()
+ .test_popcount()
+ .test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()
+ .test_unpack()
+ .test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
+ .test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
+ .test_transpose()
+ ;
+}
+
+void test_hal_intrin_int32()
+{
+ TheTest<v_int32>()
+ .test_loadstore()
+ .test_interleave()
+ .test_expand()
+ .test_addsub()
+ .test_mul()
+ .test_abs()
+ .test_cmp()
+ .test_popcount()
+ .test_shift<1>().test_shift<8>()
+ .test_logic()
+ .test_min_max()
+ .test_absdiff()
+ .test_reduce()
+ .test_mask()
+ .test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()
+ .test_unpack()
+ .test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
+ .test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
+ .test_float_cvt32()
+ .test_float_cvt64()
+ .test_transpose()
+ ;
+}
+
+//============= 64-bit integer =====================================================================
+
+void test_hal_intrin_uint64()
+{
+ TheTest<v_uint64>()
+ .test_loadstore()
+ .test_addsub()
+ .test_shift<1>().test_shift<8>()
+ .test_logic()
+ .test_extract<0>().test_extract<1>()
+ .test_rotate<0>().test_rotate<1>()
+ ;
+}
+
+void test_hal_intrin_int64()
+{
+ TheTest<v_int64>()
+ .test_loadstore()
+ .test_addsub()
+ .test_shift<1>().test_shift<8>()
+ .test_logic()
+ .test_extract<0>().test_extract<1>()
+ .test_rotate<0>().test_rotate<1>()
+ ;
+}
+
+//============= Floating point =====================================================================
+void test_hal_intrin_float32()
+{
+ TheTest<v_float32>()
+ .test_loadstore()
+ .test_interleave()
+ .test_interleave_2channel()
+ .test_addsub()
+ .test_mul()
+ .test_div()
+ .test_cmp()
+ .test_sqrt_abs()
+ .test_min_max()
+ .test_float_absdiff()
+ .test_reduce()
+ .test_mask()
+ .test_unpack()
+ .test_float_math()
+ .test_float_cvt64()
+ .test_matmul()
+ .test_transpose()
+ .test_reduce_sum4()
+ .test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
+ .test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
+ ;
+
+#if CV_SIMD256
+ TheTest<v_float32>()
+ .test_extract<4>().test_extract<5>().test_extract<6>().test_extract<7>()
+ .test_rotate<4>().test_rotate<5>().test_rotate<6>().test_rotate<7>()
+ ;
+#endif
+}
+
+void test_hal_intrin_float64()
+{
+#if CV_SIMD_64F
+ TheTest<v_float64>()
+ .test_loadstore()
+ .test_addsub()
+ .test_mul()
+ .test_div()
+ .test_cmp()
+ .test_sqrt_abs()
+ .test_min_max()
+ .test_float_absdiff()
+ .test_mask()
+ .test_unpack()
+ .test_float_math()
+ .test_float_cvt32()
+ .test_extract<0>().test_extract<1>()
+ .test_rotate<0>().test_rotate<1>()
+ ;
+
+#if CV_SIMD256
+ TheTest<v_float64>()
+ .test_extract<2>().test_extract<3>()
+ .test_rotate<2>().test_rotate<3>()
+ ;
+#endif //CV_SIMD256
+
+#endif
+}
+
+#if CV_FP16 && CV_SIMD_WIDTH > 16
+void test_hal_intrin_float16()
+{
+ TheTest<v_float16>()
+ .test_loadstore_fp16()
+ .test_float_cvt_fp16()
+ ;
+}
+#endif
+
+#endif //CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
+
+CV_CPU_OPTIMIZATION_NAMESPACE_END
+
+}} //namespace
\ No newline at end of file
template <typename R> struct Data;
template <int N> struct initializer;
+template <> struct initializer<64>
+{
+ template <typename R> static R init(const Data<R> & d)
+ {
+ return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15],
+ d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31],
+ d[32], d[33], d[34], d[35], d[36], d[37], d[38], d[39], d[40], d[41], d[42], d[43], d[44], d[45], d[46], d[47],
+ d[48], d[49], d[50], d[51], d[52], d[53], d[54], d[55], d[56], d[57], d[58], d[59], d[50], d[51], d[52], d[53],
+ d[54], d[55], d[56], d[57], d[58], d[59], d[60], d[61], d[62], d[63]);
+ }
+};
+
+template <> struct initializer<32>
+{
+ template <typename R> static R init(const Data<R> & d)
+ {
+ return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15],
+ d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31]);
+ }
+};
+
template <> struct initializer<16>
{
template <typename R> static R init(const Data<R> & d)
{
return d + R::nlanes / 2;
}
+ LaneType sum(int s, int c)
+ {
+ LaneType res = 0;
+ for (int i = s; i < s + c; ++i)
+ res += d[i];
+ return res;
+ }
+ LaneType sum()
+ {
+ return sum(0, R::nlanes);
+ }
bool operator==(const Data<R> & other) const
{
for (int i = 0; i < R::nlanes; ++i)
return false;
return true;
}
-
LaneType d[R::nlanes];
};
template<typename R> struct AlignedData
{
- Data<R> CV_DECL_ALIGNED(16) a; // aligned
+ Data<R> CV_DECL_ALIGNED(CV_SIMD_WIDTH) a; // aligned
char dummy;
Data<R> u; // unaligned
};
AlignedData<R> out;
// check if addresses are aligned and unaligned respectively
- EXPECT_EQ((size_t)0, (size_t)&data.a.d % 16);
- EXPECT_NE((size_t)0, (size_t)&data.u.d % 16);
- EXPECT_EQ((size_t)0, (size_t)&out.a.d % 16);
- EXPECT_NE((size_t)0, (size_t)&out.u.d % 16);
+ EXPECT_EQ((size_t)0, (size_t)&data.a.d % CV_SIMD_WIDTH);
+ EXPECT_NE((size_t)0, (size_t)&data.u.d % CV_SIMD_WIDTH);
+ EXPECT_EQ((size_t)0, (size_t)&out.a.d % CV_SIMD_WIDTH);
+ EXPECT_NE((size_t)0, (size_t)&out.u.d % CV_SIMD_WIDTH);
// check some initialization methods
R r1 = data.a;
- R r2 = v_load(data.u.d);
- R r3 = v_load_aligned(data.a.d);
+ R r2 = vx_load(data.u.d);
+ R r3 = vx_load_aligned(data.a.d);
R r4(r2);
EXPECT_EQ(data.a[0], r1.get0());
EXPECT_EQ(data.u[0], r2.get0());
EXPECT_EQ(data.a[0], r3.get0());
EXPECT_EQ(data.u[0], r4.get0());
- R r_low = v_load_low((LaneType*)data.u.d);
+ R r_low = vx_load_low((LaneType*)data.u.d);
EXPECT_EQ(data.u[0], r_low.get0());
v_store(out.u.d, r_low);
for (int i = 0; i < R::nlanes/2; ++i)
EXPECT_EQ((LaneType)data.u[i], (LaneType)out.u[i]);
}
- R r_low_align8byte = v_load_low((LaneType*)((char*)data.u.d + 8));
+ R r_low_align8byte = vx_load_low((LaneType*)((char*)data.u.d + (CV_SIMD_WIDTH / 2)));
EXPECT_EQ(data.u[R::nlanes/2], r_low_align8byte.get0());
v_store(out.u.d, r_low_align8byte);
for (int i = 0; i < R::nlanes/2; ++i)
// check halves load correctness
res.clear();
- R r6 = v_load_halves(d.d, d.mid());
+ R r6 = vx_load_halves(d.d, d.mid());
v_store(res.d, r6);
EXPECT_EQ(d, res);
}
// reinterpret_as
- v_uint8x16 vu8 = v_reinterpret_as_u8(r1); out.a.clear(); v_store((uchar*)out.a.d, vu8); EXPECT_EQ(data.a, out.a);
- v_int8x16 vs8 = v_reinterpret_as_s8(r1); out.a.clear(); v_store((schar*)out.a.d, vs8); EXPECT_EQ(data.a, out.a);
- v_uint16x8 vu16 = v_reinterpret_as_u16(r1); out.a.clear(); v_store((ushort*)out.a.d, vu16); EXPECT_EQ(data.a, out.a);
- v_int16x8 vs16 = v_reinterpret_as_s16(r1); out.a.clear(); v_store((short*)out.a.d, vs16); EXPECT_EQ(data.a, out.a);
- v_uint32x4 vu32 = v_reinterpret_as_u32(r1); out.a.clear(); v_store((unsigned*)out.a.d, vu32); EXPECT_EQ(data.a, out.a);
- v_int32x4 vs32 = v_reinterpret_as_s32(r1); out.a.clear(); v_store((int*)out.a.d, vs32); EXPECT_EQ(data.a, out.a);
- v_uint64x2 vu64 = v_reinterpret_as_u64(r1); out.a.clear(); v_store((uint64*)out.a.d, vu64); EXPECT_EQ(data.a, out.a);
- v_int64x2 vs64 = v_reinterpret_as_s64(r1); out.a.clear(); v_store((int64*)out.a.d, vs64); EXPECT_EQ(data.a, out.a);
- v_float32x4 vf32 = v_reinterpret_as_f32(r1); out.a.clear(); v_store((float*)out.a.d, vf32); EXPECT_EQ(data.a, out.a);
-#if CV_SIMD128_64F
- v_float64x2 vf64 = v_reinterpret_as_f64(r1); out.a.clear(); v_store((double*)out.a.d, vf64); EXPECT_EQ(data.a, out.a);
+ v_uint8 vu8 = v_reinterpret_as_u8(r1); out.a.clear(); v_store((uchar*)out.a.d, vu8); EXPECT_EQ(data.a, out.a);
+ v_int8 vs8 = v_reinterpret_as_s8(r1); out.a.clear(); v_store((schar*)out.a.d, vs8); EXPECT_EQ(data.a, out.a);
+ v_uint16 vu16 = v_reinterpret_as_u16(r1); out.a.clear(); v_store((ushort*)out.a.d, vu16); EXPECT_EQ(data.a, out.a);
+ v_int16 vs16 = v_reinterpret_as_s16(r1); out.a.clear(); v_store((short*)out.a.d, vs16); EXPECT_EQ(data.a, out.a);
+ v_uint32 vu32 = v_reinterpret_as_u32(r1); out.a.clear(); v_store((unsigned*)out.a.d, vu32); EXPECT_EQ(data.a, out.a);
+ v_int32 vs32 = v_reinterpret_as_s32(r1); out.a.clear(); v_store((int*)out.a.d, vs32); EXPECT_EQ(data.a, out.a);
+ v_uint64 vu64 = v_reinterpret_as_u64(r1); out.a.clear(); v_store((uint64*)out.a.d, vu64); EXPECT_EQ(data.a, out.a);
+ v_int64 vs64 = v_reinterpret_as_s64(r1); out.a.clear(); v_store((int64*)out.a.d, vs64); EXPECT_EQ(data.a, out.a);
+ v_float32 vf32 = v_reinterpret_as_f32(r1); out.a.clear(); v_store((float*)out.a.d, vf32); EXPECT_EQ(data.a, out.a);
+#if CV_SIMD_64F
+ v_float64 vf64 = v_reinterpret_as_f64(r1); out.a.clear(); v_store((double*)out.a.d, vf64); EXPECT_EQ(data.a, out.a);
#endif
return *this;
Data<R> dataA;
R a = dataA;
- Data<Rx2> resB = v_load_expand(dataA.d);
+ Data<Rx2> resB = vx_load_expand(dataA.d);
Rx2 c, d;
v_expand(a, c, d);
{
typedef typename V_RegTraits<R>::q_reg Rx4;
Data<R> data;
- Data<Rx4> out = v_load_expand_q(data.d);
+ Data<Rx4> out = vx_load_expand_q(data.d);
const int n = Rx4::nlanes;
for (int i = 0; i < n; ++i)
EXPECT_EQ(data[i], out[i]);
TheTest & test_popcount()
{
- static unsigned popcountTable[] = {0, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17, 20, 22, 25, 28, 32, 33};
+ static unsigned popcountTable[] = {
+ 0, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17, 20, 22, 25, 28, 32, 33,
+ 35, 37, 40, 42, 45, 48, 52, 54, 57, 60, 64, 67, 71, 75, 80, 81,
+ 83, 85, 88, 90, 93, 96, 100, 102, 105, 108, 112, 115, 119, 123,
+ 128, 130, 133, 136, 140, 143, 147, 151, 156, 159, 163, 167, 172,
+ 176, 181, 186, 192, 193
+ };
Data<R> dataA;
R a = dataA;
TheTest & test_float_cvt32()
{
- typedef v_float32x4 Rt;
+ typedef v_float32 Rt;
Data<R> dataA;
dataA *= 1.1;
R a = dataA;
TheTest & test_float_cvt64()
{
-#if CV_SIMD128_64F
- typedef v_float64x2 Rt;
+#if CV_SIMD_64F
+ typedef v_float64 Rt;
Data<R> dataA;
dataA *= 1.1;
R a = dataA;
R v = dataV, a = dataA, b = dataB, c = dataC, d = dataD;
Data<R> res = v_matmul(v, a, b, c, d);
- for (int i = 0; i < R::nlanes; ++i)
+ for (int i = 0; i < R::nlanes; i += 4)
{
- LaneType val = dataV[0] * dataA[i]
- + dataV[1] * dataB[i]
- + dataV[2] * dataC[i]
- + dataV[3] * dataD[i];
- EXPECT_DOUBLE_EQ(val, res[i]);
+ for (int j = i; j < i + 4; ++j)
+ {
+ LaneType val = dataV[i] * dataA[j]
+ + dataV[i + 1] * dataB[j]
+ + dataV[i + 2] * dataC[j]
+ + dataV[i + 3] * dataD[j];
+ EXPECT_COMPARE_EQ(val, res[j]);
+ }
}
Data<R> resAdd = v_matmuladd(v, a, b, c, d);
- for (int i = 0; i < R::nlanes; ++i)
+ for (int i = 0; i < R::nlanes; i += 4)
{
- LaneType val = dataV[0] * dataA[i]
- + dataV[1] * dataB[i]
- + dataV[2] * dataC[i]
- + dataD[i];
- EXPECT_DOUBLE_EQ(val, resAdd[i]);
+ for (int j = i; j < i + 4; ++j)
+ {
+ LaneType val = dataV[i] * dataA[j]
+ + dataV[i + 1] * dataB[j]
+ + dataV[i + 2] * dataC[j]
+ + dataD[j];
+ EXPECT_COMPARE_EQ(val, resAdd[j]);
+ }
}
return *this;
}
e, f, g, h);
Data<R> res[4] = {e, f, g, h};
- for (int i = 0; i < R::nlanes; ++i)
+ for (int i = 0; i < R::nlanes; i += 4)
{
- EXPECT_EQ(dataA[i], res[i][0]);
- EXPECT_EQ(dataB[i], res[i][1]);
- EXPECT_EQ(dataC[i], res[i][2]);
- EXPECT_EQ(dataD[i], res[i][3]);
+ for (int j = 0; j < 4; ++j)
+ {
+ EXPECT_EQ(dataA[i + j], res[j][i]);
+ EXPECT_EQ(dataB[i + j], res[j][i + 1]);
+ EXPECT_EQ(dataC[i + j], res[j][i + 2]);
+ EXPECT_EQ(dataD[i + j], res[j][i + 3]);
+ }
}
return *this;
}
TheTest & test_reduce_sum4()
{
- R a(0.1f, 0.02f, 0.003f, 0.0004f);
- R b(1, 20, 300, 4000);
- R c(10, 2, 0.3f, 0.04f);
- R d(1, 2, 3, 4);
-
- R sum = v_reduce_sum4(a, b, c, d);
-
- Data<R> res = sum;
- EXPECT_EQ(0.1234f, res[0]);
- EXPECT_EQ(4321.0f, res[1]);
- EXPECT_EQ(12.34f, res[2]);
- EXPECT_EQ(10.0f, res[3]);
+ Data<R> dataA, dataB, dataC, dataD;
+ dataB *= 0.01f;
+ dataC *= 0.001f;
+ dataD *= 0.002f;
+
+ R a = dataA, b = dataB, c = dataC, d = dataD;
+ Data<R> res = v_reduce_sum4(a, b, c, d);
+
+ for (int i = 0; i < R::nlanes; i += 4)
+ {
+ EXPECT_COMPARE_EQ(dataA.sum(i, 4), res[i]);
+ EXPECT_COMPARE_EQ(dataB.sum(i, 4), res[i + 1]);
+ EXPECT_COMPARE_EQ(dataC.sum(i, 4), res[i + 2]);
+ EXPECT_COMPARE_EQ(dataD.sum(i, 4), res[i + 3]);
+ }
return *this;
}
AlignedData<R> out;
// check if addresses are aligned and unaligned respectively
- EXPECT_EQ((size_t)0, (size_t)&data.a.d % 16);
- EXPECT_NE((size_t)0, (size_t)&data.u.d % 16);
- EXPECT_EQ((size_t)0, (size_t)&out.a.d % 16);
- EXPECT_NE((size_t)0, (size_t)&out.u.d % 16);
+ EXPECT_EQ((size_t)0, (size_t)&data.a.d % CV_SIMD_WIDTH);
+ EXPECT_NE((size_t)0, (size_t)&data.u.d % CV_SIMD_WIDTH);
+ EXPECT_EQ((size_t)0, (size_t)&out.a.d % CV_SIMD_WIDTH);
+ EXPECT_NE((size_t)0, (size_t)&out.u.d % CV_SIMD_WIDTH);
// check some initialization methods
R r1 = data.u;
- R r2 = v_load_f16(data.a.d);
+ R r2 = vx_load_f16(data.a.d);
R r3(r2);
EXPECT_EQ(data.u[0], r1.get0());
EXPECT_EQ(data.a[0], r2.get0());
dsz = slice+1 < maxSlice ? (int)(cvtest::randInt(rng) % (SZ - sz) + 1) : SZ - sz;
Mat aslice = arr[k].colRange(sz, sz + dsz);
tested_rng.fill(aslice, dist_type, A, B);
- //printf("%d - %d\n", sz, sz + dsz);
}
}
set(sources_options EXCLUDE_OPENCL)
endif()
-if(HAVE_INF_ENGINE)
- add_definitions(-DHAVE_INF_ENGINE=1)
- list(APPEND include_dirs ${INF_ENGINE_INCLUDE_DIRS})
- list(APPEND libs ${INF_ENGINE_LIBRARIES})
-endif()
-
ocv_module_include_directories(${include_dirs})
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
ocv_append_source_files_cxx_compiler_options(fw_srcs "-Wno-suggest-override") # GCC
ocv_append_source_files_cxx_compiler_options(fw_srcs "-Wno-inconsistent-missing-override") # Clang
endif()
ocv_glob_module_sources(${sources_options} SOURCES ${fw_srcs})
-ocv_create_module(${libs})
+ocv_create_module(${libs} ${INF_ENGINE_TARGET})
ocv_add_samples()
-ocv_add_accuracy_tests()
+ocv_add_accuracy_tests(${INF_ENGINE_TARGET})
ocv_add_perf_tests()
ocv_option(${the_module}_PERF_CAFFE "Add performance tests of Caffe framework" OFF)
endif()
endif()
endif()
-
-# Test Intel's Inference Engine models
-if(HAVE_INF_ENGINE AND TARGET opencv_test_dnn)
- ocv_target_include_directories(opencv_test_dnn PRIVATE ${INF_ENGINE_INCLUDE_DIRS})
- ocv_target_link_libraries(opencv_test_dnn LINK_PRIVATE ${INF_ENGINE_LIBRARIES})
-endif()
return 0;
}
+#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R2)
InferenceEngine::StatusCode InfEngineBackendNet::AddExtension(const InferenceEngine::IShapeInferExtensionPtr &extension, InferenceEngine::ResponseDesc *resp) noexcept
{
CV_Error(Error::StsNotImplemented, "");
CV_Error(Error::StsNotImplemented, "");
return InferenceEngine::StatusCode::OK;
}
+#endif
void InfEngineBackendNet::init(int targetId)
{
#if defined(__GNUC__) && __GNUC__ >= 5
//#pragma GCC diagnostic pop
#endif
+
+#define INF_ENGINE_RELEASE_2018R1 2018010000
+#define INF_ENGINE_RELEASE_2018R2 2018020000
+
+#ifndef INF_ENGINE_RELEASE
+#warning("IE version have not been provided via command-line. Using 2018R2 by default")
+#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2018R2
+#endif
+
+#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
+
#endif // HAVE_INF_ENGINE
namespace cv { namespace dnn {
virtual size_t getBatchSize() const noexcept CV_OVERRIDE;
+#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R2)
virtual InferenceEngine::StatusCode AddExtension(const InferenceEngine::IShapeInferExtensionPtr& extension, InferenceEngine::ResponseDesc* resp) noexcept;
-
virtual InferenceEngine::StatusCode reshape(const InputShapes& inputShapes, InferenceEngine::ResponseDesc* resp) noexcept;
+#endif
void init(int targetId);
{
HKEY hkey;
char szKey[1024];
- strcpy( szKey, icvWindowPosRootKey );
- strcat( szKey, name );
+ strcpy_s( szKey, 1024, icvWindowPosRootKey );
+ strcat_s( szKey, 1024, name );
rect.x = rect.y = CW_USEDEFAULT;
rect.width = rect.height = 320;
HKEY hkey;
char szKey[1024];
char rootKey[1024];
- strcpy( szKey, icvWindowPosRootKey );
- strcat( szKey, name );
+ strcpy_s( szKey, 1024, icvWindowPosRootKey );
+ strcat_s( szKey, 1024, name );
if( RegOpenKeyEx( HKEY_CURRENT_USER,szKey,0,KEY_READ,&hkey) != ERROR_SUCCESS )
{
char oldestKey[1024];
char currentKey[1024];
- strcpy( rootKey, icvWindowPosRootKey );
+ strcpy_s( rootKey, 1024, icvWindowPosRootKey );
rootKey[strlen(rootKey)-1] = '\0';
if( RegCreateKeyEx(HKEY_CURRENT_USER, rootKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ+KEY_WRITE, 0, &hroot, NULL) != ERROR_SUCCESS )
//RegOpenKeyEx( HKEY_CURRENT_USER,rootKey,0,KEY_READ,&hroot) != ERROR_SUCCESS )
oldestTime.dwLowDateTime > accesstime.dwLowDateTime) )
{
oldestTime = accesstime;
- strcpy( oldestKey, currentKey );
+ strcpy_s( oldestKey, 1024, currentKey );
}
}
rgn = CreateRectRgn(0, 0, wrc.right, wrc.bottom);
rgn1 = CreateRectRgn(cr.left, cr.top, cr.right, cr.bottom);
rgn2 = CreateRectRgn(tr.left, tr.top, tr.right, tr.bottom);
+ CV_Assert(rgn != 0, rgn1 != 0, rgn2 != 0);
+
ret = CombineRgn(rgn, rgn, rgn1, RGN_DIFF);
ret = CombineRgn(rgn, rgn, rgn2, RGN_DIFF);
size as src .
@param blockSize Neighborhood size (see the details on #cornerEigenValsAndVecs ).
@param ksize Aperture parameter for the Sobel operator.
-@param k Harris detector free parameter. See the formula below.
+@param k Harris detector free parameter. See the formula above.
@param borderType Pixel extrapolation method. See #BorderTypes.
*/
CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize,
/** @brief Writes the next video frame
- @param image The written frame
+ @param image The written frame. In general, color images are expected in BGR format.
The function/method writes the specified image to video file. It must have the same size as has
been specified when opening the video writer.
IEnumPins *pins = NULL;
PIN_INFO pininfo;
HRESULT hr = pBF->EnumPins(&pins);
+ if (hr != S_OK || !pins)
+ return;
pins->Reset();
while (hr == NOERROR)
{
pP->Release();
}
}
- if (pins) pins->Release();
+ pins->Release();
}
(pGraph) = 0;
}
- //delete our pointers
- delete pDestFilter;
- delete pVideoInputFilter;
- delete pGrabberF;
- delete pGrabber;
- delete pControl;
- delete streamConf;
- delete pMediaEvent;
- delete pCaptureGraph;
- delete pGraph;
-
DebugPrintOut("SETUP: Device %i disconnected and freed\n\n",myID);
}
IAMVideoProcAmp *pAMVideoProcAmp = NULL;
hr = VD->pVideoInputFilter->QueryInterface(IID_IAMVideoProcAmp, (void**)&pAMVideoProcAmp);
- if(FAILED(hr)){
+ if(FAILED(hr) || !pAMVideoProcAmp){
DebugPrintOut("setVideoSetting - QueryInterface Error\n");
#if 0
if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release();
hr = pAMVideoProcAmp->Get(Property, ¤tValue, &flags);
}
- if(pAMVideoProcAmp)pAMVideoProcAmp->Release();
+ pAMVideoProcAmp->Release();
#if 0
if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release();
if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL;
IAMCameraControl *pIAMCameraControl = NULL;
hr = VD->pVideoInputFilter->QueryInterface(IID_IAMCameraControl, (void**)&pIAMCameraControl);
- if(FAILED(hr)){
+ if(FAILED(hr) || !pIAMCameraControl){
DebugPrintOut("setVideoSetting - QueryInterface Error\n");
#if 0
if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release();
hr = pIAMCameraControl->Get(Property, ¤tValue, &flags);
}
- if(pIAMCameraControl)pIAMCameraControl->Release();
+ pIAMCameraControl->Release();
#if 0
if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release();
if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL;
//we do this because webcams don't have a preview mode
hr = VD->pCaptureGraph->FindInterface(&CAPTURE_MODE, &MEDIATYPE_Video, VD->pVideoInputFilter, IID_IAMStreamConfig, (void **)&VD->streamConf);
- if(FAILED(hr)){
+ if(FAILED(hr) || !VD->streamConf){
DebugPrintOut("ERROR: Couldn't config the stream!\n");
stopDevice(deviceID);
return hr;
//lets try freeing our stream conf here too
//this will fail if the device is already running
- if(VD->streamConf){
- VD->streamConf->Release();
- VD->streamConf = NULL;
- }else{
- DebugPrintOut("ERROR: connecting device - prehaps it is already being used?\n");
- stopDevice(deviceID);
- return S_FALSE;
- }
+ VD->streamConf->Release();
+ VD->streamConf = NULL;
//NULL RENDERER//
IAMCrossbar *pXBar1 = NULL;
HRESULT hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pVidFilter,
IID_IAMCrossbar, (void**)&pXBar1);
- if (SUCCEEDED(hr))
+ if (SUCCEEDED(hr) && pXBar1)
{
bool foundDevice = false;
//we were getting a crash otherwise
//if(Crossbar)Crossbar->Release();
//if(Crossbar)Crossbar = NULL;
-
- if(pXBar1)pXBar1->Release();
- if(pXBar1)pXBar1 = NULL;
-
}else{
DebugPrintOut("SETUP: You are a webcam or snazzy firewire cam! No Crossbar needed\n");
return hr;
class CvVideoWriter_GStreamer : public CvVideoWriter
{
public:
- CvVideoWriter_GStreamer() { init(); }
+ CvVideoWriter_GStreamer()
+ : pipeline(0), source(0), encodebin(0), file(0), buffer(0), input_pix_fmt(0),
+ num_frames(0), framerate(0)
+ {
+ }
virtual ~CvVideoWriter_GStreamer() CV_OVERRIDE { close(); }
virtual bool open( const char* filename, int fourcc,
virtual void close();
virtual bool writeFrame( const IplImage* image ) CV_OVERRIDE;
protected:
- void init();
const char* filenameToMimetype(const char* filename);
GstElement* pipeline;
GstElement* source;
};
/*!
- * \brief CvVideoWriter_GStreamer::init
- * initialise all variables
- */
-void CvVideoWriter_GStreamer::init()
-{
- pipeline = NULL;
- source = NULL;
- encodebin = NULL;
- file = NULL;
- buffer = NULL;
-
- num_frames = 0;
- framerate = 0;
-}
-
-/*!
* \brief CvVideoWriter_GStreamer::close
* ends the pipeline by sending EOS and destroys the pipeline and all
* elements afterwards
//wait for EOS to trickle down the pipeline. This will let all elements finish properly
GstBus* bus = gst_element_get_bus(pipeline);
GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
- if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
+ if (!msg || GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR)
{
CV_WARN("Error during VideoWriter finalization\n");
+ if(msg != NULL)
+ {
+ gst_message_unref(msg);
+ g_object_unref(G_OBJECT(bus));
+ }
return;
}
- if(msg != NULL)
- {
- gst_message_unref(msg);
- g_object_unref(G_OBJECT(bus));
- }
+ gst_message_unref(msg);
+ g_object_unref(G_OBJECT(bus));
status = gst_element_set_state (pipeline, GST_STATE_NULL);
if (status == GST_STATE_CHANGE_ASYNC)
static FN_MFCreateDXGIDeviceManager pMFCreateDXGIDeviceManager = NULL;
static void init_MFCreateDXGIDeviceManager()
{
- HMODULE h = LoadLibraryA("mfplat.dll");
+ HMODULE h = LoadLibraryExA("mfplat.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (h)
{
pMFCreateDXGIDeviceManager = (FN_MFCreateDXGIDeviceManager)GetProcAddress(h, "MFCreateDXGIDeviceManager");
return setTime(duration * value, true);
break;
case CV_CAP_PROP_POS_FRAMES:
- if (getFramerate(nativeFormat) != 0)
+ if (std::fabs(getFramerate(nativeFormat)) > 0)
return setTime(value * 1e7 / getFramerate(nativeFormat), false);
break;
case CV_CAP_PROP_POS_MSEC:
CvVideoWriter_MSMF::CvVideoWriter_MSMF():
MF(Media_Foundation::getInstance()),
- initiated(false)
+ videoWidth(0),
+ videoHeight(0),
+ fps(0),
+ bitRate(0),
+ frameSize(0),
+ encodingFormat(),
+ inputFormat(),
+ streamIndex(0),
+ initiated(false),
+ rtStart(0),
+ rtDuration(0)
{
}
if (!hWnd) return FALSE;
capture = (CvCaptureCAM_VFW*)capGetUserData(hWnd);
+ if (!capture) return (LRESULT)FALSE;
capture->hdr = hdr;
-
return (LRESULT)TRUE;
}
--- /dev/null
+/**
+* @brief You will learn how to recover an out-of-focus image by Wiener filter
+* @author Karpushin Vladislav, karpushin@ngs.ru, https://github.com/VladKarpushin
+*/
+#include <iostream>
+#include "opencv2/imgproc.hpp"
+#include "opencv2/imgcodecs.hpp"
+
+using namespace cv;
+using namespace std;
+
+void help();
+void calcPSF(Mat& outputImg, Size filterSize, int R);
+void fftshift(const Mat& inputImg, Mat& outputImg);
+void filter2DFreq(const Mat& inputImg, Mat& outputImg, const Mat& H);
+void calcWnrFilter(const Mat& input_h_PSF, Mat& output_G, double nsr);
+
+const String keys =
+"{help h usage ? | | print this message }"
+"{image |original.JPG | input image name }"
+"{R |53 | radius }"
+"{SNR |5200 | signal to noise ratio}"
+;
+
+int main(int argc, char *argv[])
+{
+ help();
+ CommandLineParser parser(argc, argv, keys);
+ if (parser.has("help"))
+ {
+ parser.printMessage();
+ return 0;
+ }
+
+ int R = parser.get<int>("R");
+ int snr = parser.get<int>("SNR");
+ string strInFileName = parser.get<String>("image");
+
+ if (!parser.check())
+ {
+ parser.printErrors();
+ return 0;
+ }
+
+ Mat imgIn;
+ imgIn = imread(strInFileName, IMREAD_GRAYSCALE);
+ if (imgIn.empty()) //check whether the image is loaded or not
+ {
+ cout << "ERROR : Image cannot be loaded..!!" << endl;
+ return -1;
+ }
+
+ Mat imgOut;
+
+//! [main]
+ // it needs to process even image only
+ Rect roi = Rect(0, 0, imgIn.cols & -2, imgIn.rows & -2);
+
+ //Hw calculation (start)
+ Mat Hw, h;
+ calcPSF(h, roi.size(), R);
+ calcWnrFilter(h, Hw, 1.0 / double(snr));
+ //Hw calculation (stop)
+
+ // filtering (start)
+ filter2DFreq(imgIn(roi), imgOut, Hw);
+ // filtering (stop)
+//! [main]
+
+ imgOut.convertTo(imgOut, CV_8U);
+ normalize(imgOut, imgOut, 0, 255, NORM_MINMAX);
+ imwrite("result.jpg", imgOut);
+ return 0;
+}
+
+void help()
+{
+ cout << "2018-07-12" << endl;
+ cout << "DeBlur_v8" << endl;
+ cout << "You will learn how to recover an out-of-focus image by Wiener filter" << endl;
+}
+
+//! [calcPSF]
+void calcPSF(Mat& outputImg, Size filterSize, int R)
+{
+ Mat h(filterSize, CV_32F, Scalar(0));
+ Point point(filterSize.width / 2, filterSize.height / 2);
+ circle(h, point, R, 255, -1, 8);
+ Scalar summa = sum(h);
+ outputImg = h / summa[0];
+}
+//! [calcPSF]
+
+//! [fftshift]
+void fftshift(const Mat& inputImg, Mat& outputImg)
+{
+ outputImg = inputImg.clone();
+ int cx = outputImg.cols / 2;
+ int cy = outputImg.rows / 2;
+ Mat q0(outputImg, Rect(0, 0, cx, cy));
+ Mat q1(outputImg, Rect(cx, 0, cx, cy));
+ Mat q2(outputImg, Rect(0, cy, cx, cy));
+ Mat q3(outputImg, Rect(cx, cy, cx, cy));
+ Mat tmp;
+ q0.copyTo(tmp);
+ q3.copyTo(q0);
+ tmp.copyTo(q3);
+ q1.copyTo(tmp);
+ q2.copyTo(q1);
+ tmp.copyTo(q2);
+}
+//! [fftshift]
+
+//! [filter2DFreq]
+void filter2DFreq(const Mat& inputImg, Mat& outputImg, const Mat& H)
+{
+ Mat planes[2] = { Mat_<float>(inputImg.clone()), Mat::zeros(inputImg.size(), CV_32F) };
+ Mat complexI;
+ merge(planes, 2, complexI);
+ dft(complexI, complexI, DFT_SCALE);
+
+ Mat planesH[2] = { Mat_<float>(H.clone()), Mat::zeros(H.size(), CV_32F) };
+ Mat complexH;
+ merge(planesH, 2, complexH);
+ Mat complexIH;
+ mulSpectrums(complexI, complexH, complexIH, 0);
+
+ idft(complexIH, complexIH);
+ split(complexIH, planes);
+ outputImg = planes[0];
+}
+//! [filter2DFreq]
+
+//! [calcWnrFilter]
+void calcWnrFilter(const Mat& input_h_PSF, Mat& output_G, double nsr)
+{
+ Mat h_PSF_shifted;
+ fftshift(input_h_PSF, h_PSF_shifted);
+ Mat planes[2] = { Mat_<float>(h_PSF_shifted.clone()), Mat::zeros(h_PSF_shifted.size(), CV_32F) };
+ Mat complexI;
+ merge(planes, 2, complexI);
+ dft(complexI, complexI);
+ split(complexI, planes);
+ Mat denom;
+ pow(abs(planes[0]), 2, denom);
+ denom += nsr;
+ divide(planes[0], denom, output_G);
+}
+//! [calcWnrFilter]