Merge pull request #12113 from dkurt:dnn_fix_ssd_on_myriad
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Tue, 31 Jul 2018 14:55:18 +0000 (14:55 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Tue, 31 Jul 2018 14:55:18 +0000 (14:55 +0000)
37 files changed:
CMakeLists.txt
cmake/OpenCVDetectInferenceEngine.cmake
doc/opencv.bib
doc/tutorials/imgproc/out_of_focus_deblur_filter/images/original.jpg [new file with mode: 0755]
doc/tutorials/imgproc/out_of_focus_deblur_filter/images/psf.png [new file with mode: 0755]
doc/tutorials/imgproc/out_of_focus_deblur_filter/images/recovered.jpg [new file with mode: 0755]
doc/tutorials/imgproc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.markdown [new file with mode: 0755]
doc/tutorials/imgproc/table_of_content_imgproc.markdown
modules/core/include/opencv2/core/hal/intrin.hpp
modules/core/include/opencv2/core/hal/intrin_avx.hpp
modules/core/include/opencv2/core/hal/intrin_neon.hpp
modules/core/include/opencv2/core/hal/intrin_sse.hpp
modules/core/src/arithm.cpp
modules/core/src/copy.cpp
modules/core/src/matrix.cpp
modules/core/src/mean.cpp
modules/core/src/ocl.cpp
modules/core/src/rand.cpp
modules/core/test/test_arithm.cpp
modules/core/test/test_concatenation.cpp
modules/core/test/test_intrin.avx2.cpp [new file with mode: 0644]
modules/core/test/test_intrin.cpp
modules/core/test/test_intrin.fp16.cpp
modules/core/test/test_intrin.simd.hpp [new file with mode: 0644]
modules/core/test/test_intrin_utils.hpp
modules/core/test/test_rand.cpp
modules/dnn/CMakeLists.txt
modules/dnn/src/op_inf_engine.cpp
modules/dnn/src/op_inf_engine.hpp
modules/highgui/src/window_w32.cpp
modules/imgproc/include/opencv2/imgproc.hpp
modules/videoio/include/opencv2/videoio.hpp
modules/videoio/src/cap_dshow.cpp
modules/videoio/src/cap_gstreamer.cpp
modules/videoio/src/cap_msmf.cpp
modules/videoio/src/cap_vfw.cpp
samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp [new file with mode: 0755]

index 898a837..f436fc2 100644 (file)
@@ -1407,15 +1407,19 @@ if(WITH_HALIDE OR HAVE_HALIDE)
   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()
index 366509e..e5e64fc 100644 (file)
@@ -1,83 +1,87 @@
 # 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()
index edb7033..7c8303f 100644 (file)
   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={Изд-во НГТУ Новосибирск}
+}
diff --git a/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/original.jpg b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/original.jpg
new file mode 100755 (executable)
index 0000000..ecd23c8
Binary files /dev/null and b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/original.jpg differ
diff --git a/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/psf.png b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/psf.png
new file mode 100755 (executable)
index 0000000..3835124
Binary files /dev/null and b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/psf.png differ
diff --git a/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/recovered.jpg b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/recovered.jpg
new file mode 100755 (executable)
index 0000000..2794d42
Binary files /dev/null and b/doc/tutorials/imgproc/out_of_focus_deblur_filter/images/recovered.jpg differ
diff --git a/doc/tutorials/imgproc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.markdown b/doc/tutorials/imgproc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.markdown
new file mode 100755 (executable)
index 0000000..abab071
--- /dev/null
@@ -0,0 +1,112 @@
+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
index 59c985e..3d82c0c 100644 (file)
@@ -292,3 +292,13 @@ In this section you will learn about the image processing (manipulation) functio
     *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.
index 9569e61..263659d 100644 (file)
@@ -165,7 +165,7 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
 // 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"
@@ -225,14 +225,16 @@ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
     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) \
@@ -327,7 +329,7 @@ template<typename _Tp> struct V_RegTraits
     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;
index fc2fd7c..c64ff99 100644 (file)
@@ -429,6 +429,11 @@ inline v_float16x16 v256_load_f16(const short* ptr)
 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)
@@ -841,94 +846,80 @@ OPENCV_HAL_IMPL_AVX_BIN_FUNC(v_max, v_float64x4, _mm256_max_pd)
 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)                                  \
index b601e3e..73ca948 100644 (file)
@@ -319,6 +319,9 @@ static inline void cv_vst1_f16(void* ptr, float16x4_t a)
 #endif
 }
 
+#ifndef vdup_n_f16
+    #define vdup_n_f16(v) (float16x4_t){v, v, v, v}
+#endif
 
 struct v_float16x8
 {
@@ -893,6 +896,11 @@ inline v_float16x8 v_load_f16(const short* ptr)
 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)
index 6e07940..d1f24d1 100644 (file)
@@ -1330,6 +1330,11 @@ inline v_float16x8 v_load_f16(const short* ptr)
 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)
index e3ded85..dbfcc5c 100644 (file)
@@ -1233,7 +1233,8 @@ void cv::compare(InputArray _src1, InputArray _src2, OutputArray _dst, int op)
     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;
index 8775bff..e89a17b 100644 (file)
@@ -411,7 +411,8 @@ Mat& Mat::operator = (const Scalar& s)
 {
     CV_INSTRUMENT_REGION()
 
-    if (empty()) return *this;
+    if (this->empty())
+        return *this;
 
     const Mat* arrays[] = { this };
     uchar* dptr;
index 65ac200..2da6ca6 100644 (file)
@@ -602,13 +602,13 @@ void Mat::pop_back(size_t nelems)
 
 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++ )
@@ -709,7 +709,8 @@ void Mat::resize(size_t nelems, const Scalar& s)
 
 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 )
@@ -726,7 +727,7 @@ void Mat::push_back(const Mat& 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() )
@@ -735,7 +736,7 @@ void Mat::push_back(const Mat& elems)
     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);
@@ -744,7 +745,7 @@ void Mat::push_back(const Mat& elems)
         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);
     }
 }
index d0029b3..dcf1ae2 100644 (file)
@@ -766,11 +766,13 @@ void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, Input
 {
     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))
index cc6feac..05f128b 100644 (file)
@@ -2834,7 +2834,22 @@ extern "C" {
 
 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");
+    }
 }
 
 }
index a456c72..cc46345 100644 (file)
@@ -511,8 +511,8 @@ static RandnScaleFunc randnScaleTab[] =
 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;
index dd2ed9a..9ca48a0 100644 (file)
@@ -1967,11 +1967,9 @@ TEST(Subtract, scalarc4_matc4)
 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)
@@ -1979,9 +1977,7 @@ 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);
 }
 
 
index 1470094..201bf0e 100644 (file)
 
 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
diff --git a/modules/core/test/test_intrin.avx2.cpp b/modules/core/test/test_intrin.avx2.cpp
new file mode 100644 (file)
index 0000000..9ebfcdf
--- /dev/null
@@ -0,0 +1,5 @@
+// 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
index 9a1130f..6610e33 100644 (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
index 893c5f1..9f6416b 100644 (file)
@@ -9,7 +9,7 @@ CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
 
 void test_hal_intrin_float16()
 {
-    TheTest<v_float16x8>()
+    TheTest<v_float16>()
         .test_loadstore_fp16()
         .test_float_cvt_fp16()
         ;
diff --git a/modules/core/test/test_intrin.simd.hpp b/modules/core/test/test_intrin.simd.hpp
new file mode 100644 (file)
index 0000000..4e0d3a0
--- /dev/null
@@ -0,0 +1,296 @@
+// 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
index 2f8c1cf..5f3175b 100644 (file)
@@ -13,6 +13,27 @@ void test_hal_intrin_float16();
 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)
@@ -125,6 +146,17 @@ template <typename R> struct Data
     {
         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)
@@ -147,13 +179,12 @@ template <typename R> struct Data
                 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
 };
@@ -207,22 +238,22 @@ template<typename R> struct TheTest
         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)
@@ -230,7 +261,7 @@ template<typename R> struct TheTest
             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)
@@ -255,7 +286,7 @@ template<typename R> struct TheTest
 
         // 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);
 
@@ -270,17 +301,17 @@ template<typename R> struct TheTest
         }
 
         // 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;
@@ -357,7 +388,7 @@ template<typename R> struct TheTest
         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);
@@ -378,7 +409,7 @@ template<typename R> struct TheTest
     {
         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]);
@@ -610,7 +641,13 @@ template<typename R> struct TheTest
 
     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;
 
@@ -918,7 +955,7 @@ template<typename R> struct TheTest
 
     TheTest & test_float_cvt32()
     {
-        typedef v_float32x4 Rt;
+        typedef v_float32 Rt;
         Data<R> dataA;
         dataA *= 1.1;
         R a = dataA;
@@ -934,8 +971,8 @@ template<typename R> struct TheTest
 
     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;
@@ -965,23 +1002,29 @@ template<typename R> struct TheTest
         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;
     }
@@ -998,30 +1041,36 @@ template<typename R> struct TheTest
                        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;
     }
 
@@ -1032,14 +1081,14 @@ template<typename R> struct TheTest
         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());
index 6504649..49062ff 100644 (file)
@@ -173,7 +173,6 @@ void Core_RandTest::run( int )
                 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);
             }
         }
 
index a4cdc18..64fefb3 100644 (file)
@@ -85,12 +85,6 @@ else()
   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
@@ -98,9 +92,9 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
   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)
@@ -120,9 +114,3 @@ if(BUILD_PERF_TESTS)
     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()
index eb409ee..7d94b9d 100644 (file)
@@ -334,6 +334,7 @@ size_t InfEngineBackendNet::getBatchSize() const noexcept
     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, "");
@@ -345,6 +346,7 @@ InferenceEngine::StatusCode InfEngineBackendNet::reshape(const InferenceEngine::
     CV_Error(Error::StsNotImplemented, "");
     return InferenceEngine::StatusCode::OK;
 }
+#endif
 
 void InfEngineBackendNet::init(int targetId)
 {
index a5ad63f..a811f4e 100644 (file)
 #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 {
@@ -92,9 +103,10 @@ public:
 
     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);
 
index ea7b461..945b2e6 100644 (file)
@@ -307,8 +307,8 @@ icvLoadWindowPos( const char* name, CvRect& rect )
 {
     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;
@@ -368,8 +368,8 @@ icvSaveWindowPos( const char* name, CvRect rect )
     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 )
     {
@@ -379,7 +379,7 @@ icvSaveWindowPos( const char* name, CvRect rect )
         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 )
@@ -398,7 +398,7 @@ icvSaveWindowPos( const char* name, CvRect rect )
                 oldestTime.dwLowDateTime > accesstime.dwLowDateTime) )
             {
                 oldestTime = accesstime;
-                strcpy( oldestKey, currentKey );
+                strcpy_s( oldestKey, 1024, currentKey );
             }
         }
 
@@ -1500,6 +1500,8 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
             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);
 
index c760a54..a831d0e 100644 (file)
@@ -1771,7 +1771,7 @@ Corners in the image can be found as the local maxima of this response map.
 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,
index eef840b..2628609 100644 (file)
@@ -905,7 +905,7 @@ public:
 
     /** @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.
index 3a92a81..03cb5a4 100644 (file)
@@ -811,6 +811,8 @@ void videoDevice::NukeDownstream(IBaseFilter *pBF){
     IEnumPins *pins = NULL;
     PIN_INFO pininfo;
     HRESULT hr = pBF->EnumPins(&pins);
+    if (hr != S_OK || !pins)
+        return;
     pins->Reset();
     while (hr == NOERROR)
     {
@@ -838,7 +840,7 @@ void videoDevice::NukeDownstream(IBaseFilter *pBF){
             pP->Release();
         }
     }
-    if (pins) pins->Release();
+    pins->Release();
 }
 
 
@@ -999,17 +1001,6 @@ videoDevice::~videoDevice(){
                                 (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);
 }
 
@@ -1654,7 +1645,7 @@ bool videoInput::getVideoSettingFilter(int deviceID, long Property, long &min, l
     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();
@@ -1676,7 +1667,7 @@ bool videoInput::getVideoSettingFilter(int deviceID, long Property, long &min, l
         hr = pAMVideoProcAmp->Get(Property, &currentValue, &flags);
     }
 
-    if(pAMVideoProcAmp)pAMVideoProcAmp->Release();
+    pAMVideoProcAmp->Release();
 #if 0
     if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release();
     if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL;
@@ -1881,7 +1872,7 @@ bool videoInput::getVideoSettingCamera(int deviceID, long Property, long &min, l
     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();
@@ -1902,7 +1893,7 @@ bool videoInput::getVideoSettingCamera(int deviceID, long Property, long &min, l
         hr = pIAMCameraControl->Get(Property, &currentValue, &flags);
     }
 
-    if(pIAMCameraControl)pIAMCameraControl->Release();
+    pIAMCameraControl->Release();
 #if 0
     if(VD->pVideoInputFilter)VD->pVideoInputFilter->Release();
     if(VD->pVideoInputFilter)VD->pVideoInputFilter = NULL;
@@ -2595,7 +2586,7 @@ int videoInput::start(int deviceID, videoDevice *VD){
 
     //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;
@@ -2737,14 +2728,8 @@ int videoInput::start(int deviceID, videoDevice *VD){
 
     //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//
@@ -3093,7 +3078,7 @@ HRESULT videoInput::routeCrossbar(ICaptureGraphBuilder2 **ppBuild, IBaseFilter *
     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;
@@ -3163,10 +3148,6 @@ HRESULT videoInput::routeCrossbar(ICaptureGraphBuilder2 **ppBuild, IBaseFilter *
         //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;
index c3100f5..8758b21 100644 (file)
@@ -1224,7 +1224,11 @@ Ptr<IVideoCapture> cv::createGStreamerCapture(int index)
 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,
@@ -1232,7 +1236,6 @@ public:
     virtual void close();
     virtual bool writeFrame( const IplImage* image ) CV_OVERRIDE;
 protected:
-    void init();
     const char* filenameToMimetype(const char* filename);
     GstElement* pipeline;
     GstElement* source;
@@ -1246,22 +1249,6 @@ protected:
 };
 
 /*!
- * \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
@@ -1282,17 +1269,19 @@ void CvVideoWriter_GStreamer::close()
         //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)
index 35043ee..863f46b 100644 (file)
@@ -91,7 +91,7 @@ static bool pMFCreateDXGIDeviceManager_initialized = false;
 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");
@@ -1720,7 +1720,7 @@ bool CvCapture_MSMF::setProperty( int property_id, double value )
                 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:
@@ -1978,7 +1978,17 @@ private:
 
 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)
 {
 }
 
index 0d71a0c..f62baf4 100644 (file)
@@ -377,8 +377,8 @@ LRESULT PASCAL CvCaptureCAM_VFW::frameCallback( HWND hWnd, VIDEOHDR* hdr )
     if (!hWnd) return FALSE;
 
     capture = (CvCaptureCAM_VFW*)capGetUserData(hWnd);
+    if (!capture) return (LRESULT)FALSE;
     capture->hdr = hdr;
-
     return (LRESULT)TRUE;
 }
 
diff --git a/samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp b/samples/cpp/tutorial_code/ImgProc/out_of_focus_deblur_filter/out_of_focus_deblur_filter.cpp
new file mode 100755 (executable)
index 0000000..059df8b
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+* @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]