1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-25 21:33:04 +04:00

Compare commits

...

91 Commits

Author SHA1 Message Date
Alexander Alekhin c9ad5779f2 release: OpenCV 4.0.1 (version++) 2018-12-22 07:03:30 +00:00
Alexander Alekhin 26c5b0c71f Merge tag '4.0.1-openvino'
OpenCV 4.0.1 for Intel(R) OpenVINO(TM) toolkit
2018-12-22 07:01:13 +00:00
Alexander Alekhin 1dee705074 Merge branch '3.4' into merge-3.4 2018-12-22 05:40:15 +00:00
Alexander Alekhin c0e11bb50e imgproc: revert "Speedup filter2d by loop unrolling"
Commit: 124011c321
PR: https://github.com/opencv/opencv/pull/13392

Sobel filter with 16S/16U datatype is broken.
2018-12-22 05:37:29 +00:00
Alexander Alekhin f35e043cf9 Merge tag '3.4.5' 2018-12-21 21:48:03 +03:00
Alexander Alekhin 8f1356c3c5 OpenCV version++ (3.4.5)
OpenCV 3.4.5
2018-12-21 17:31:20 +03:00
Alexander Alekhin 14633bc857 Merge pull request #13497 from dkurt:dnn_torch_bn_train 2018-12-21 14:29:10 +00:00
Alexander Alekhin 578ea4bae9 Merge pull request #13386 from alalek:android_gradle 2018-12-21 13:56:03 +00:00
Alexander Alekhin 2bba0f297b Merge pull request #13493 from dkurt:dnn_ie_r5 2018-12-21 12:18:23 +00:00
Alexander Alekhin 6c1638b132 Merge pull request #13487 from alalek:videoio_test_frame_size_changing 2018-12-21 12:17:06 +00:00
Alexander Alekhin 1a6c2b37ea Merge pull request #13499 from alalek:issue_13498 2018-12-21 12:15:59 +00:00
Dmitry Kurtaev 840c892abd Batch normalization in training phase from Torch 2018-12-21 14:36:55 +03:00
Alexander Alekhin 09d8bbb138 Merge pull request #13467 from alalek:issue_12594 2018-12-21 11:01:25 +00:00
Alexander Alekhin 832217907f Merge pull request #13435 from alalek:issue_13434 2018-12-21 11:01:04 +00:00
Alexander Alekhin 26c5b846e6 Merge pull request #13392 from terfendail:filter_wintr 2018-12-21 11:00:44 +00:00
Dmitry Kurtaev 59ce1d80a5 Fix dnn tests for Inference Engine R5 2018-12-21 12:33:30 +03:00
Alexander Alekhin 2f3e06ac1f objdetect(qrcode): don't process small/non-regular images 2018-12-21 12:19:35 +03:00
Alexander Alekhin 37a63ca02b Merge pull request #13488 from alalek:fix_videoio_v4l2_build 2018-12-21 09:07:38 +00:00
Alexander Alekhin 0d63bd575c Merge pull request #13489 from alalek:openvino_2018r5 2018-12-21 10:05:04 +03:00
Dmitry Kurtaev 257f60582a Add serialize method for IE net wrapper
backport 4ba4901ca9
2018-12-21 05:52:27 +00:00
Alexander Alekhin bbdc987fc6 dnn: add OpenVINO 2018R5 defines
https://software.intel.com/en-us/openvino-toolkit
2018-12-21 05:52:27 +00:00
Vitaly Tuzov 124011c321 Speedup filter2d by loop unrolling 2018-12-20 21:18:42 +03:00
Alexander Alekhin 8456d096d2 videoio(v4l2): fix build due missing V4L2_CID_ISO_SENSITIVITY 2018-12-20 16:28:12 +03:00
Alexander Alekhin 32c975b533 Merge pull request #13484 from va-sorokin:fix-v4l-size 2018-12-20 12:55:41 +00:00
Alexander Alekhin a3a3670027 videoio(test): test V4L frame size changing manual test 2018-12-20 15:14:20 +03:00
Vasiliy Sorokin b6a72826dd videio: Fix new frame size appling in v4l. 2018-12-20 14:59:39 +03:00
Dmitry Kurtaev 6bcf0b5519 Merge pull request #13482 from dkurt:fix_python_bindings_without_stitching
* Fix python bindings without stitching module

* stitching: move stitching specific code into modules/stitching/misc
2018-12-19 23:37:55 +03:00
Alexander Alekhin 3d5cebb3ac Merge pull request #13478 from terfendail:medianblur_fix 2018-12-19 16:03:55 +00:00
Alexander Alekhin e82d03ef61 Merge pull request #13480 from dbudniko:dbudniko/gapi_ocl_backend_internal_umat_size_fix 2018-12-19 15:50:32 +00:00
Vitaly Tuzov 131c09cf76 Fixed medianBlur implementation for hi-resolution images 2018-12-19 18:05:42 +03:00
Vitaly Tuzov 06f32e3b3e Reworked separable filter to use wide universal intrinsics 2018-12-19 17:50:09 +03:00
Dmitry Budnikov eedd7bfd50 fix size 2018-12-19 17:45:00 +03:00
Alexander Alekhin cbf80117af eliminate build warnings 2018-12-19 15:42:38 +03:00
Alexander Alekhin 2b35c1708b android: gradle-based package and samples
- drop hello-android sample
2018-12-19 14:59:48 +03:00
Alexander Alekhin e093a19c70 Merge pull request #13471 from dkurt:fix_enum_struct_java 2018-12-19 11:53:41 +00:00
Dmitry Kurtaev 6fbcb283b9 Try to fix "enum struct" wrapping for Java 2018-12-19 13:16:43 +03:00
Alexander Alekhin 7fb70e1701 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2018-12-18 19:07:43 +00:00
LaurentBerger 2fb409b286 Merge pull request #13267 from LaurentBerger:StitchPython
* Python wrapper for detail

* hide pyrotationwrapper

* copy code in pyopencv_rotationwarper.hpp

* move ImageFeatures MatchInfo and CameraParams in core/misc/

* add python test for detail

* move test_detail in test_stitching

* rename
2018-12-18 21:49:16 +03:00
Alexander Alekhin b0a08cced9 Merge pull request #13466 from pstieber:AddTuringCudaGeneration 2018-12-18 18:35:47 +00:00
Alexander Alekhin 82b7803a7a Merge pull request #13456 from alalek:fix_eigen2cv_type_check 2018-12-18 18:35:27 +00:00
Peter J. Stieber 50ef9830e2 Added Turing to the _generations list. 2018-12-18 08:52:15 -08:00
Alexander Alekhin d5f430cc11 android: gradle wrapper
https://github.com/gradle/gradle/tree/v4.6.0

License: Apache 2.0
2018-12-18 15:45:45 +03:00
Alexander Alekhin 8ed4fb9405 Merge pull request #13464 from alalek:ocl_max_group_size_parameter 2018-12-18 12:06:14 +00:00
Alexander Alekhin de82d9da9e Merge pull request #13458 from alalek:fix_python_install_path 2018-12-18 11:46:03 +00:00
Quentin Chateau fd27d5ea00 Merge pull request #13449 from Tytan:stitching-warp-interpolation
Stitching: added functions to set warp interpolation mode (#13449)

* Added functions to set warp interpolation mode

* Use InterpolationFlags enum

* Improved getter/setter naming
2018-12-18 14:43:05 +03:00
vishwesh5 715f8fcce0 Merge pull request #13432 from vishwesh5:patch-1
* Create text_detection.py

#12270 #13429
**Deep Learning text detection sample (Python)**
- Tested on **Ubuntu 18.04** - OpenCV 3.4.3, OpenCV 3.4.4, OpenCV 4.0 (master branch)
- Python version supported - Python 2 and Python 3

* Fix trailing whitespaces

* Update text_detection.py

* Remove whitespace

* Remove comments

* Remove unused packages

* Update description
2018-12-18 13:40:04 +03:00
Alexander Alekhin 3f3c8823ac features2d: fix retainBest() implementation 2018-12-18 05:33:21 +00:00
Alexander Alekhin d9d9b05912 core(ocl): add parameter to limit device max workgroup size
used by OpenCV
2018-12-17 18:33:05 +00:00
Alexander Alekhin 55171b25f8 Merge pull request #13463 from vishwesh5:patch-2 2018-12-17 18:08:20 +00:00
vishwesh5 3eb2c940de Fix Scharr and Sobel functions
Resolves #13375
2018-12-17 20:39:22 +05:30
Rostislav Vasilikhin 493611ace5 Merge pull request #13440 from savuor:rgb_wide
* conversions of color_rgb.cpp vectorized

* CL impl: coeffs updated

* unused constants removed

* CUDA color coeffs updated
2018-12-17 17:22:38 +03:00
Alexander Alekhin bb8c19aad3 cmake: fix python install paths 2018-12-17 14:32:29 +03:00
Alexander Alekhin b571f03016 Merge pull request #13455 from alalek:issue_13454 2018-12-16 10:16:19 +00:00
Alexander Alekhin f605898bae core: fix eigen2cv() - don't change fixed type of 'dst' 2018-12-16 06:43:08 +00:00
Alexander Alekhin 5736bf5dd5 stitching: fix l_gains data type from Eigen solver (float / double) 2018-12-16 06:29:18 +00:00
Alexander Alekhin 4f9c1da806 Merge pull request #13447 from alalek:issue_13445 2018-12-15 21:17:17 +00:00
Alexander Alekhin eb1f3733ee videoio(dc1394): use lazy initialization on demand 2018-12-15 07:58:39 +00:00
Alexander Alekhin d993b9c1df Merge pull request #13443 from seiko2plus:issue13442 2018-12-14 22:31:35 +00:00
Sayed Adel 4e16ae9a1f core:vsx fix build failure on GCC<=6 due implementation of v_reduce_sum(v_float64x2) 2018-12-14 19:24:12 +00:00
Quentin Chateau ab86f15ba0 Merge pull request #13400 from Tytan:optimize_exposure_compensation
Optimize exposure compensation (#13400)

* Added perf test

* Optimized gains computation

* Use Eigen for gains calculation
2018-12-14 21:37:00 +03:00
Alexander Alekhin e058febaad Merge pull request #13441 from paroj:capimg 2018-12-14 15:41:40 +00:00
Alexander Alekhin 0a801354b1 Merge pull request #13438 from madan-ram:patch-2 2018-12-14 14:35:56 +00:00
Pavel Rojtberg d7f60f69f1 videoio: fix CAP_IMAGES
broken in 11eafca3e2
2018-12-14 15:32:33 +01:00
Rostislav Vasilikhin d99a4af229 Merge pull request #13379 from savuor:color_5x5
RGB to/from Gray rewritten to wide intrinsics (#13379)

* 5x5 to RGB added

* RGB25x5 added

* Gray2RGB added

* Gray2RGB5x5 added

* vx_set moved out of loops

* RGB5x52Gray added

* RGB2Gray written

* warnings fixed (int -> (u)short conversion)

* warning fixed

* warning fixed

* "i < n-vsize+1" to "i <= n-vsize"

* RGBA2mRGBA vectorized

* try to fix ARM builds

* fixed ARM build for RGB2RGB5x5

* mRGBA2RGBA: saturation, vectorization

* fixed CL implementation of mRGBA2RGBA (saturation added)
2018-12-14 17:01:01 +03:00
Alexander Alekhin 4b33910449 Merge pull request #13428 from rgarnov:gapi_add_kernels_pass_stage 2018-12-14 12:30:36 +00:00
Madan Ram c1e9a7ee4b Update template_matching.markdown
Replaced CV_TM_SQDIFF to TM_SQDIFF and the rest since methods are renamed in opencv 3.4
2018-12-14 16:34:58 +05:30
Alexander Alekhin 82a02d8585 Merge pull request #13436 from alalek:cmake_with_msmf_dxva_3.4 2018-12-14 10:36:39 +00:00
Alexander Alekhin 8d907d2e32 cmake(java): add OPENCV_JAVA_SOURCE_VERSION/OPENCV_JAVA_TARGET_VERSION 2018-12-14 00:15:57 +00:00
Alexander Alekhin 0c16d8f6c3 Merge remote-tracking branch 'upstream/3.4' into merge-3.4 2018-12-13 15:12:26 +03:00
Alexander Alekhin b7bb79c7c8 videoio(MSMF): backport WITH_MSMF_DXVA flag 2018-12-13 14:56:20 +03:00
Ruslan Garnov 5340073770 Removed UNUSED macro 2018-12-13 14:39:33 +03:00
Vitaly Tuzov 3903174f7c Merge pull request #13334 from terfendail:histogram_wintr
* added performance test for compareHist

* compareHist reworked to use wide universal intrinsics

* Disabled vectorization for CV_COMP_CORREL and CV_COMP_BHATTACHARYYA if f64 is unsupported
2018-12-13 14:20:22 +03:00
Alexander Alekhin a9771078df Merge pull request #13427 from dkurt:dnn_onnx_dynamic_reshape 2018-12-13 11:15:51 +00:00
Alexander Alekhin eb1f7797e4 Merge pull request #13387 from dkurt:dnn_minor_ie_fixes 2018-12-13 10:08:34 +00:00
Alexander Alekhin aa666dfa9c Merge pull request #13430 from tomoaki0705:fixCudaJetsonTX2file 2018-12-13 09:14:26 +00:00
Tomoaki Teshima 3e710d8eec use correct CC value for Jetson Xavier 2018-12-13 13:35:19 +09:00
Alexander Alekhin 384ac63490 Merge pull request #13425 from alalek:issue_13277 2018-12-12 16:21:46 +00:00
Alexander Alekhin 954098d1cb Merge pull request #13423 from alalek:issue_13418 2018-12-12 15:38:47 +00:00
Dmitry Kurtaev e71758cfdf Operate with shapes in ONNX models 2018-12-12 18:34:22 +03:00
Alexander Alekhin cea3289bd4 Merge pull request #13420 from ThadHouse:Windows7shlwapi 2018-12-12 14:58:51 +00:00
Adrian Kashivskyy 00285a5e88 Merge pull request #13424 from akashivskyy:pr/ios-nonfree
Add ability to build iOS and macOS frameworks with nonfree modules (#13424)

* Allow building ios framework with nonfree

* Allow building osx framework with nonfree
2018-12-12 17:32:19 +03:00
Ruslan Garnov d38676085a Added "kernels" pass stage to compiler, removed unused opaque from cv::gimpl::Op 2018-12-12 17:22:52 +03:00
Alexander Alekhin d8583b2c7a dnn: fix vulkan backend builds with Clang 2018-12-12 15:25:39 +03:00
Alexander Alekhin 82227b5ace Merge pull request #13419 from seanm:SemiWarnings 2018-12-12 11:07:00 +00:00
Alexander Alekhin 6fa23f330f cmake: fix compiler flags filtering 2018-12-12 13:35:43 +03:00
Alexander Alekhin c8f934b5b1 Merge pull request #13415 from alalek:issue_13406
* python: add checks for drawKeypoints() symbol

* python: more hacks in hdr_parser.py
2018-12-12 13:26:31 +03:00
Thad House 857fba0878 Remove MinCore_Downlevel, replace with Shlwapi
On windows 7, MinCore_Downlevel does not work correctly. However, the only API used was QISearch, which can be found in Shlwapi.

Closes #12010
2018-12-11 17:06:01 -08:00
Sean McBride a4111fab39 Fixed -Wextra-semi warnings in public headers 2018-12-11 14:45:27 -05:00
Alexander Alekhin 54de51ef3c Merge pull request #13416 from alalek:avoid_cv2_in_docs 2018-12-11 17:47:41 +03:00
Alexander Alekhin 0915df5b18 python: don't use 'cv2.' in documentation 2018-12-11 16:05:12 +03:00
Dmitry Kurtaev 53f6198f27 Minor fixes in IE backend tests 2018-12-10 20:08:13 +03:00
165 changed files with 5126 additions and 3716 deletions
+2
View File
@@ -12,6 +12,8 @@ elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64.*|AARCH64.*")
set(AARCH64 TRUE)
endif()
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-function)
set(TEGRA_COMPILER_FLAGS "")
if(CV_GCC OR CV_CLANG)
+1
View File
@@ -30,6 +30,7 @@
#include <sys/cdefs.h>
#include <stdint.h>
#include <string.h>
__BEGIN_DECLS
+6 -2
View File
@@ -341,9 +341,12 @@ OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON
OCV_OPTION(WITH_DSHOW "Build VideoIO with DirectShow support" ON
VISIBLE_IF WIN32 AND NOT ARM AND NOT WINRT
VERIFY HAVE_DSHOW)
OCV_OPTION(WITH_MSMF "Build VideoIO with Media Foundation support" ON
OCV_OPTION(WITH_MSMF "Build VideoIO with Media Foundation support" NOT MINGW
VISIBLE_IF WIN32
VERIFY HAVE_MSMF)
OCV_OPTION(WITH_MSMF_DXVA "Enable hardware acceleration in Media Foundation backend" WITH_MSMF
VISIBLE_IF WIN32
VERIFY HAVE_MSMF_DXVA)
OCV_OPTION(WITH_XIMEA "Include XIMEA cameras support" OFF
VISIBLE_IF NOT ANDROID AND NOT WINRT
VERIFY HAVE_XIMEA)
@@ -590,7 +593,7 @@ else()
ocv_update(OPENCV_OTHER_INSTALL_PATH "${CMAKE_INSTALL_DATAROOTDIR}/opencv4")
ocv_update(OPENCV_LICENSES_INSTALL_PATH "${CMAKE_INSTALL_DATAROOTDIR}/licenses/opencv4")
endif()
ocv_update(OPENCV_PYTHON_INSTALL_PATH "python")
#ocv_update(OPENCV_PYTHON_INSTALL_PATH "python") # no default value, see https://github.com/opencv/opencv/issues/13202
endif()
ocv_update(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_LIB_INSTALL_PATH}")
@@ -1447,6 +1450,7 @@ endif()
if(WITH_MSMF OR HAVE_MSMF)
status(" Media Foundation:" HAVE_MSMF THEN YES ELSE NO)
status(" DXVA:" HAVE_MSMF_DXVA THEN YES ELSE NO)
endif()
if(WITH_XIMEA OR HAVE_XIMEA)
+3
View File
@@ -1,3 +1,6 @@
set(OPENCV_JAVA_SOURCE_VERSION "" CACHE STRING "Java source version (javac Ant target)")
set(OPENCV_JAVA_TARGET_VERSION "" CACHE STRING "Java target version (javac Ant target)")
file(TO_CMAKE_PATH "$ENV{ANT_DIR}" ANT_DIR_ENV_PATH)
file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH)
+2 -2
View File
@@ -52,7 +52,7 @@ if(CUDA_FOUND)
message(STATUS "CUDA detected: " ${CUDA_VERSION})
set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta")
set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing")
if(NOT CMAKE_CROSSCOMPILING)
list(APPEND _generations "Auto")
endif()
@@ -115,7 +115,7 @@ if(CUDA_FOUND)
string(REGEX REPLACE ".*\n" "" _nvcc_out "${_nvcc_out}") #Strip leading warning messages, if any
if(NOT _nvcc_res EQUAL 0)
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
set(__cuda_arch_bin "5.3 6.2 7.0 7.5")
set(__cuda_arch_bin "5.3 6.2 7.2")
else()
set(__cuda_arch_bin "${_nvcc_out}")
string(REPLACE "2.1" "2.1(2.0)" __cuda_arch_bin "${__cuda_arch_bin}")
+2 -2
View File
@@ -78,9 +78,9 @@ endif()
if(INF_ENGINE_TARGET)
if(NOT INF_ENGINE_RELEASE)
message(WARNING "InferenceEngine version have not been set, 2018R4 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
message(WARNING "InferenceEngine version have not been set, 2018R5 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
endif()
set(INF_ENGINE_RELEASE "2018040000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
set(INF_ENGINE_RELEASE "2018050000" 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}"
)
+8 -7
View File
@@ -246,14 +246,15 @@ endif(WITH_DSHOW)
ocv_clear_vars(HAVE_MSMF)
if(WITH_MSMF)
check_include_file(Mfapi.h HAVE_MSMF)
check_include_file(D3D11.h D3D11_found)
check_include_file(D3d11_4.h D3D11_4_found)
if(D3D11_found AND D3D11_4_found)
set(HAVE_DXVA YES)
else()
set(HAVE_DXVA NO)
set(HAVE_MSMF_DXVA "")
if(WITH_MSMF_DXVA)
check_include_file(D3D11.h D3D11_found)
check_include_file(D3d11_4.h D3D11_4_found)
if(D3D11_found AND D3D11_4_found)
set(HAVE_MSMF_DXVA YES)
endif()
endif()
endif(WITH_MSMF)
endif()
# --- Extra HighGUI and VideoIO libs on Windows ---
if(WIN32)
+17 -4
View File
@@ -43,11 +43,24 @@ else()
endif()
file(RELATIVE_PATH OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG
"${CMAKE_INSTALL_PREFIX}/${OPENCV_SETUPVARS_INSTALL_PATH}/" "${CMAKE_INSTALL_PREFIX}/")
if(IS_ABSOLUTE "${OPENCV_PYTHON_INSTALL_PATH}")
set(OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG "${OPENCV_PYTHON_INSTALL_PATH}")
message(WARNING "CONFIGURATION IS NOT SUPPORTED: validate setupvars script in install directory")
if(DEFINED OPENCV_PYTHON_INSTALL_PATH)
set(__python_path "${OPENCV_PYTHON_INSTALL_PATH}")
elseif(DEFINED OPENCV_PYTHON_INSTALL_PATH_SETUPVARS)
set(__python_path "${OPENCV_PYTHON_INSTALL_PATH_SETUPVARS}")
endif()
if(DEFINED __python_path)
if(IS_ABSOLUTE "${__python_path}")
set(OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG "${__python_path}")
message(WARNING "CONFIGURATION IS NOT SUPPORTED: validate setupvars script in install directory")
else()
ocv_path_join(OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG "${OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG}" "${__python_path}")
endif()
else()
ocv_path_join(OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG "${OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG}" "${OPENCV_PYTHON_INSTALL_PATH}")
if(DEFINED OPENCV_PYTHON3_INSTALL_PATH)
ocv_path_join(OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG "${OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG}" "${OPENCV_PYTHON3_INSTALL_PATH}")
else()
set(OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG "python_loader_is_not_installed")
endif()
endif()
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/${OPENCV_SETUPVARS_TEMPLATE}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/${OPENCV_SETUPVARS_FILENAME}" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/${OPENCV_SETUPVARS_FILENAME}"
+1 -1
View File
@@ -508,7 +508,7 @@ macro(ocv_warnings_disable)
foreach(var ${_flag_vars})
foreach(warning ${_gxx_warnings})
if(NOT warning MATCHES "^-Wno-")
string(REGEX REPLACE "${warning}(=[^ ]*)?" "" ${var} "${${var}}")
string(REGEX REPLACE "(^|[ ]+)${warning}(=[^ ]*)?([ ]+|$)" " " ${var} "${${var}}")
string(REPLACE "-W" "-Wno-" warning "${warning}")
endif()
ocv_check_flag_support(${var} "${warning}" _varname "")
@@ -8,6 +8,24 @@ if(DEFINED ANDROID_NDK_REVISION AND ANDROID_NDK_REVISION MATCHES "(1[56])([0-9]+
set(ANDROID_NDK_REVISION "${ANDROID_NDK_REVISION}" CACHE INTERNAL "Android NDK revision")
endif()
# fixup -g option: https://github.com/opencv/opencv/issues/8460#issuecomment-434249750
if((INSTALL_CREATE_DISTRIB OR CMAKE_BUILD_TYPE STREQUAL "Release")
AND NOT OPENCV_SKIP_ANDROID_G_OPTION_FIX
)
if(" ${CMAKE_CXX_FLAGS} " MATCHES " -g ")
message(STATUS "Android: fixup -g compiler option from Android toolchain")
endif()
string(REPLACE " -g " " " CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} ")
string(REPLACE " -g " " " CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} ")
string(REPLACE " -g " " " CMAKE_ASM_FLAGS " ${CMAKE_ASM_FLAGS} ")
if(NOT " ${CMAKE_CXX_FLAGS_DEBUG}" MATCHES " -g")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g")
endif()
if(NOT " ${CMAKE_C_FLAGS_DEBUG}" MATCHES " -g")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g")
endif()
endif()
# https://developer.android.com/studio/command-line/variables.html
ocv_check_environment_variables(ANDROID_SDK_ROOT ANDROID_HOME ANDROID_SDK)
+150 -4
View File
@@ -1,5 +1,151 @@
message(FATAL_ERROR "
Android gradle-based build/projects are not supported in this version of OpenCV.
You need to downgrade Android SDK Tools to version 25.2.5.
Details: https://github.com/opencv/opencv/issues/8460
# https://developer.android.com/studio/releases/gradle-plugin
set(ANDROID_GRADLE_PLUGIN_VERSION "3.2.1" CACHE STRING "Android Gradle Plugin version (3.0+)")
message(STATUS "Android Gradle Plugin version: ${ANDROID_GRADLE_PLUGIN_VERSION}")
set(ANDROID_COMPILE_SDK_VERSION "26" CACHE STRING "Android compileSdkVersion")
set(ANDROID_MIN_SDK_VERSION "21" CACHE STRING "Android minSdkVersion")
set(ANDROID_TARGET_SDK_VERSION "26" CACHE STRING "Android minSdkVersion")
set(ANDROID_BUILD_BASE_DIR "${OpenCV_BINARY_DIR}/opencv_android" CACHE INTERNAL "")
set(ANDROID_TMP_INSTALL_BASE_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/opencv_android")
set(ANDROID_INSTALL_SAMPLES_DIR "samples")
set(ANDROID_BUILD_ABI_FILTER "
reset()
include '${ANDROID_ABI}'
")
set(ANDROID_INSTALL_ABI_FILTER "
//reset()
//include 'armeabi-v7a'
//include 'arm64-v8a'
//include 'x86'
//include 'x86_64'
")
if(NOT INSTALL_CREATE_DISTRIB)
set(ANDROID_INSTALL_ABI_FILTER "${ANDROID_BUILD_ABI_FILTER}")
endif()
# BUG: Ninja generator generates broken targets with ANDROID_ABI_FILTER name (CMake 3.11.2)
#set(__spaces " ")
#string(REPLACE "\n" "\n${__spaces}" ANDROID_ABI_FILTER "${__spaces}${ANDROID_BUILD_ABI_FILTER}")
#string(REPLACE REGEX "[ ]+$" "" ANDROID_ABI_FILTER "${ANDROID_ABI_FILTER}")
set(ANDROID_ABI_FILTER "${ANDROID_BUILD_ABI_FILTER}")
configure_file("${OpenCV_SOURCE_DIR}/samples/android/build.gradle.in" "${ANDROID_BUILD_BASE_DIR}/build.gradle" @ONLY)
set(ANDROID_ABI_FILTER "${ANDROID_INSTALL_ABI_FILTER}")
configure_file("${OpenCV_SOURCE_DIR}/samples/android/build.gradle.in" "${ANDROID_TMP_INSTALL_BASE_DIR}/${ANDROID_INSTALL_SAMPLES_DIR}/build.gradle" @ONLY)
install(FILES "${ANDROID_TMP_INSTALL_BASE_DIR}/${ANDROID_INSTALL_SAMPLES_DIR}/build.gradle" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}" COMPONENT samples)
set(GRADLE_WRAPPER_FILES
"gradle/wrapper/gradle-wrapper.jar"
"gradle/wrapper/gradle-wrapper.properties"
"gradlew.bat"
"gradlew"
"gradle.properties"
)
foreach(fname ${GRADLE_WRAPPER_FILES})
get_filename_component(__dir "${fname}" DIRECTORY)
set(__permissions "")
set(__permissions_prefix "")
if(fname STREQUAL "gradlew")
set(__permissions FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif()
file(COPY "${OpenCV_SOURCE_DIR}/platforms/android/gradle-wrapper/${fname}" DESTINATION "${ANDROID_BUILD_BASE_DIR}/${__dir}" ${__permissions})
string(REPLACE "FILE_PERMISSIONS" "PERMISSIONS" __permissions "${__permissions}")
if("${__dir}" STREQUAL "")
set(__dir ".")
endif()
install(FILES "${OpenCV_SOURCE_DIR}/platforms/android/gradle-wrapper/${fname}" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples ${__permissions})
endforeach()
file(WRITE "${ANDROID_BUILD_BASE_DIR}/settings.gradle" "
include ':opencv'
")
file(WRITE "${ANDROID_TMP_INSTALL_BASE_DIR}/settings.gradle" "
rootProject.name = 'opencv_samples'
def opencvsdk='../'
//def opencvsdk='/<path to OpenCV-android-sdk>'
//println opencvsdk
include ':opencv'
project(':opencv').projectDir = new File(opencvsdk + '/sdk')
")
macro(add_android_project target path)
get_filename_component(__dir "${path}" NAME)
set(OPENCV_ANDROID_CMAKE_EXTRA_ARGS "")
if(DEFINED ANDROID_TOOLCHAIN)
set(OPENCV_ANDROID_CMAKE_EXTRA_ARGS "${OPENCV_ANDROID_CMAKE_EXTRA_ARGS},\n\"-DANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN}\"")
endif()
if(DEFINED ANDROID_STL)
set(OPENCV_ANDROID_CMAKE_EXTRA_ARGS "${OPENCV_ANDROID_CMAKE_EXTRA_ARGS},\n\"-DANDROID_STL=${ANDROID_STL}\"")
endif()
#
# Build
#
set(ANDROID_SAMPLE_JNI_PATH "${path}/jni")
set(ANDROID_SAMPLE_JAVA_PATH "${path}/src")
set(ANDROID_SAMPLE_RES_PATH "${path}/res")
set(ANDROID_SAMPLE_MANIFEST_PATH "${path}/gradle/AndroidManifest.xml")
set(ANDROID_ABI_FILTER "${ANDROID_BUILD_ABI_FILTER}")
set(ANDROID_PROJECT_JNI_PATH "../../")
string(REPLACE ";" "', '" ANDROID_SAMPLE_JAVA_PATH "['${ANDROID_SAMPLE_JAVA_PATH}']")
string(REPLACE ";" "', '" ANDROID_SAMPLE_RES_PATH "['${ANDROID_SAMPLE_RES_PATH}']")
configure_file("${path}/build.gradle.in" "${ANDROID_BUILD_BASE_DIR}/${__dir}/build.gradle" @ONLY)
file(APPEND "${ANDROID_BUILD_BASE_DIR}/settings.gradle" "
include ':${__dir}'
")
# build apk
set(APK_FILE "${ANDROID_BUILD_BASE_DIR}/${__dir}/build/outputs/apk/release/${__dir}-${ANDROID_ABI}-release-unsigned.apk")
ocv_update(OPENCV_GRADLE_VERBOSE_OPTIONS "-i")
add_custom_command(
OUTPUT "${APK_FILE}" "${OPENCV_DEPHELPER}/android_sample_${__dir}"
COMMAND ./gradlew ${OPENCV_GRADLE_VERBOSE_OPTIONS} "${__dir}:assemble"
COMMAND ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/android_sample_${__dir}"
WORKING_DIRECTORY "${ANDROID_BUILD_BASE_DIR}"
DEPENDS ${depends} opencv_java_android
COMMENT "Building OpenCV Android sample project: ${__dir}"
)
file(REMOVE "${OPENCV_DEPHELPER}/android_sample_${__dir}") # force rebuild after CMake run
add_custom_target(android_sample_${__dir} ALL DEPENDS "${OPENCV_DEPHELPER}/android_sample_${__dir}" SOURCES "${ANDROID_SAMPLE_MANIFEST_PATH}")
#
# Install
#
set(ANDROID_SAMPLE_JNI_PATH "jni")
set(ANDROID_SAMPLE_JAVA_PATH "src")
set(ANDROID_SAMPLE_RES_PATH "res")
set(ANDROID_SAMPLE_MANIFEST_PATH "AndroidManifest.xml")
install(DIRECTORY "${path}/res" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples OPTIONAL)
install(DIRECTORY "${path}/src" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples)
install(DIRECTORY "${path}/jni" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples OPTIONAL)
install(FILES "${path}/gradle/AndroidManifest.xml" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples)
set(ANDROID_ABI_FILTER "${ANDROID_INSTALL_ABI_FILTER}")
set(ANDROID_PROJECT_JNI_PATH "native/jni")
string(REPLACE ";" "', '" ANDROID_SAMPLE_JAVA_PATH "['${ANDROID_SAMPLE_JAVA_PATH}']")
string(REPLACE ";" "', '" ANDROID_SAMPLE_RES_PATH "['${ANDROID_SAMPLE_RES_PATH}']")
configure_file("${path}/build.gradle.in" "${ANDROID_TMP_INSTALL_BASE_DIR}/${__dir}/build.gradle" @ONLY)
install(FILES "${ANDROID_TMP_INSTALL_BASE_DIR}/${__dir}/build.gradle" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples)
file(APPEND "${ANDROID_TMP_INSTALL_BASE_DIR}/settings.gradle" "
include ':${__dir}'
")
endmacro()
install(FILES "${ANDROID_TMP_INSTALL_BASE_DIR}/settings.gradle" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}" COMPONENT samples)
@@ -12,7 +12,7 @@ Tutorial was written for the following versions of corresponding software:
- Download and install Android Studio from https://developer.android.com/studio.
- Get the latest pre-built OpenCV for Android release from https://github.com/opencv/opencv/releases and unpack it (for example, `opencv-3.4.4-android-sdk.zip`).
- Get the latest pre-built OpenCV for Android release from https://github.com/opencv/opencv/releases and unpack it (for example, `opencv-3.4.5-android-sdk.zip`).
- Download MobileNet object detection model from https://github.com/chuanqi305/MobileNet-SSD. We need a configuration file `MobileNetSSD_deploy.prototxt` and weights `MobileNetSSD_deploy.caffemodel`.
@@ -65,7 +65,7 @@ that should be used to find the match.
-# **Mask image (M):** The mask, a grayscale image that masks the template
- Only two matching methods currently accept a mask: CV_TM_SQDIFF and CV_TM_CCORR_NORMED (see
- Only two matching methods currently accept a mask: TM_SQDIFF and TM_CCORR_NORMED (see
below for explanation of all the matching methods available in opencv).
@@ -86,23 +86,23 @@ that should be used to find the match.
Good question. OpenCV implements Template matching in the function **matchTemplate()**. The
available methods are 6:
-# **method=CV_TM_SQDIFF**
-# **method=TM_SQDIFF**
\f[R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2\f]
-# **method=CV_TM_SQDIFF_NORMED**
-# **method=TM_SQDIFF_NORMED**
\f[R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
-# **method=CV_TM_CCORR**
-# **method=TM_CCORR**
\f[R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y'))\f]
-# **method=CV_TM_CCORR_NORMED**
-# **method=TM_CCORR_NORMED**
\f[R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
-# **method=CV_TM_CCOEFF**
-# **method=TM_CCOEFF**
\f[R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y'))\f]
@@ -110,7 +110,7 @@ available methods are 6:
\f[\begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}\f]
-# **method=CV_TM_CCOEFF_NORMED**
-# **method=TM_CCOEFF_NORMED**
\f[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }\f]
@@ -36,14 +36,14 @@ Open your Doxyfile using your favorite text editor and search for the key
`TAGFILES`. Change it as follows:
@code
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.0.0
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.0.1
@endcode
If you had other definitions already, you can append the line using a `\`:
@code
TAGFILES = ./docs/doxygen-tags/libstdc++.tag=https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen \
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.0.0
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.0.1
@endcode
Doxygen can now use the information from the tag file to link to the OpenCV
@@ -92,13 +92,51 @@ namespace cv { namespace cuda { namespace device
return vec.w;
}
//constants for conversion from/to RGB and Gray, YUV, YCrCb according to BT.601
const float B2YF = 0.114f;
const float G2YF = 0.587f;
const float R2YF = 0.299f;
//to YCbCr
const float YCBF = 0.564f; // == 1/2/(1-B2YF)
const float YCRF = 0.713f; // == 1/2/(1-R2YF)
const int YCBI = 9241; // == YCBF*16384
const int YCRI = 11682; // == YCRF*16384
//to YUV
const float B2UF = 0.492f;
const float R2VF = 0.877f;
const int B2UI = 8061; // == B2UF*16384
const int R2VI = 14369; // == R2VF*16384
//from YUV
const float U2BF = 2.032f;
const float U2GF = -0.395f;
const float V2GF = -0.581f;
const float V2RF = 1.140f;
const int U2BI = 33292;
const int U2GI = -6472;
const int V2GI = -9519;
const int V2RI = 18678;
//from YCrCb
const float CB2BF = 1.773f;
const float CB2GF = -0.344f;
const float CR2GF = -0.714f;
const float CR2RF = 1.403f;
const int CB2BI = 29049;
const int CB2GI = -5636;
const int CR2GI = -11698;
const int CR2RI = 22987;
enum
{
yuv_shift = 14,
xyz_shift = 12,
gray_shift = 15,
R2Y = 4899,
G2Y = 9617,
B2Y = 1868,
RY15 = 9798, // == R2YF*32768 + 0.5
GY15 = 19235, // == G2YF*32768 + 0.5
BY15 = 3735, // == B2YF*32768 + 0.5
BLOCK_SIZE = 256
};
}
@@ -406,7 +444,7 @@ namespace cv { namespace cuda { namespace device
{
static __device__ __forceinline__ uchar cvt(uint t)
{
return (uchar)CV_DESCALE(((t << 3) & 0xf8) * B2Y + ((t >> 3) & 0xfc) * G2Y + ((t >> 8) & 0xf8) * R2Y, yuv_shift);
return (uchar)CV_DESCALE(((t << 3) & 0xf8) * BY15 + ((t >> 3) & 0xfc) * GY15 + ((t >> 8) & 0xf8) * RY15, gray_shift);
}
};
@@ -414,7 +452,7 @@ namespace cv { namespace cuda { namespace device
{
static __device__ __forceinline__ uchar cvt(uint t)
{
return (uchar)CV_DESCALE(((t << 3) & 0xf8) * B2Y + ((t >> 2) & 0xf8) * G2Y + ((t >> 7) & 0xf8) * R2Y, yuv_shift);
return (uchar)CV_DESCALE(((t << 3) & 0xf8) * BY15 + ((t >> 2) & 0xf8) * GY15 + ((t >> 7) & 0xf8) * RY15, gray_shift);
}
};
@@ -443,7 +481,7 @@ namespace cv { namespace cuda { namespace device
{
template <int bidx, typename T> static __device__ __forceinline__ T RGB2GrayConvert(const T* src)
{
return (T)CV_DESCALE((unsigned)(src[bidx] * B2Y + src[1] * G2Y + src[bidx^2] * R2Y), yuv_shift);
return (T)CV_DESCALE((unsigned)(src[bidx] * BY15 + src[1] * GY15 + src[bidx^2] * RY15), gray_shift);
}
template <int bidx> static __device__ __forceinline__ uchar RGB2GrayConvert(uint src)
@@ -451,12 +489,12 @@ namespace cv { namespace cuda { namespace device
uint b = 0xffu & (src >> (bidx * 8));
uint g = 0xffu & (src >> 8);
uint r = 0xffu & (src >> ((bidx ^ 2) * 8));
return CV_DESCALE((uint)(b * B2Y + g * G2Y + r * R2Y), yuv_shift);
return CV_DESCALE((uint)(b * BY15 + g * GY15 + r * RY15), gray_shift);
}
template <int bidx> static __device__ __forceinline__ float RGB2GrayConvert(const float* src)
{
return src[bidx] * 0.114f + src[1] * 0.587f + src[bidx^2] * 0.299f;
return src[bidx] * B2YF + src[1] * G2YF + src[bidx^2] * R2YF;
}
template <typename T, int scn, int bidx> struct RGB2Gray : unary_function<typename TypeVec<T, scn>::vec_type, T>
@@ -494,8 +532,8 @@ namespace cv { namespace cuda { namespace device
namespace color_detail
{
__constant__ float c_RGB2YUVCoeffs_f[5] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f };
__constant__ int c_RGB2YUVCoeffs_i[5] = { B2Y, G2Y, R2Y, 8061, 14369 };
__constant__ float c_RGB2YUVCoeffs_f[5] = { B2YF, G2YF, R2YF, B2UF, R2VF };
__constant__ int c_RGB2YUVCoeffs_i[5] = { B2Y, G2Y, R2Y, B2UI, R2VI };
template <int bidx, typename T, typename D> static __device__ void RGB2YUVConvert(const T* src, D& dst)
{
@@ -543,8 +581,8 @@ namespace cv { namespace cuda { namespace device
namespace color_detail
{
__constant__ float c_YUV2RGBCoeffs_f[5] = { 2.032f, -0.395f, -0.581f, 1.140f };
__constant__ int c_YUV2RGBCoeffs_i[5] = { 33292, -6472, -9519, 18678 };
__constant__ float c_YUV2RGBCoeffs_f[5] = { U2BF, U2GF, V2GF, V2RF };
__constant__ int c_YUV2RGBCoeffs_i[5] = { U2BI, U2GI, V2GI, V2RI };
template <int bidx, typename T, typename D> static __device__ void YUV2RGBConvert(const T& src, D* dst)
{
@@ -633,8 +671,8 @@ namespace cv { namespace cuda { namespace device
namespace color_detail
{
__constant__ float c_RGB2YCrCbCoeffs_f[5] = {0.299f, 0.587f, 0.114f, 0.713f, 0.564f};
__constant__ int c_RGB2YCrCbCoeffs_i[5] = {R2Y, G2Y, B2Y, 11682, 9241};
__constant__ float c_RGB2YCrCbCoeffs_f[5] = {R2YF, G2YF, B2YF, YCRF, YCBF};
__constant__ int c_RGB2YCrCbCoeffs_i[5] = {R2Y, G2Y, B2Y, YCRI, YCBI};
template <int bidx, typename T, typename D> static __device__ void RGB2YCrCbConvert(const T* src, D& dst)
{
@@ -710,8 +748,8 @@ namespace cv { namespace cuda { namespace device
namespace color_detail
{
__constant__ float c_YCrCb2RGBCoeffs_f[5] = {1.403f, -0.714f, -0.344f, 1.773f};
__constant__ int c_YCrCb2RGBCoeffs_i[5] = {22987, -11698, -5636, 29049};
__constant__ float c_YCrCb2RGBCoeffs_f[5] = {CR2RF, CR2GF, CB2GF, CB2BF};
__constant__ int c_YCrCb2RGBCoeffs_i[5] = {CR2RI, CR2GI, CB2GI, CB2BI};
template <int bidx, typename T, typename D> static __device__ void YCrCb2RGBConvert(const T& src, D* dst)
{
+1 -1
View File
@@ -60,7 +60,7 @@ namespace cv
//! @{
template<typename _Tp, int _rows, int _cols, int _options, int _maxRows, int _maxCols> static inline
void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, Mat& dst )
void eigen2cv( const Eigen::Matrix<_Tp, _rows, _cols, _options, _maxRows, _maxCols>& src, OutputArray dst )
{
if( !(src.Flags & Eigen::RowMajorBit) )
{
@@ -1125,6 +1125,12 @@ inline float v_reduce_sum(const v_float32x8& a)
return _mm_cvtss_f32(s1);
}
inline double v_reduce_sum(const v_float64x4& a)
{
__m256d s0 = _mm256_hadd_pd(a.val, a.val);
return _mm_cvtsd_f64(_mm_add_pd(_v256_extract_low(s0), _v256_extract_high(s0)));
}
inline v_float32x8 v_reduce_sum4(const v_float32x8& a, const v_float32x8& b,
const v_float32x8& c, const v_float32x8& d)
{
@@ -1272,6 +1278,16 @@ OPENCV_HAL_IMPL_AVX_CHECK_FLT(v_float64x4, 15)
OPENCV_HAL_IMPL_AVX_MULADD(v_float32x8, ps)
OPENCV_HAL_IMPL_AVX_MULADD(v_float64x4, pd)
inline v_int32x8 v_fma(const v_int32x8& a, const v_int32x8& b, const v_int32x8& c)
{
return a * b + c;
}
inline v_int32x8 v_muladd(const v_int32x8& a, const v_int32x8& b, const v_int32x8& c)
{
return v_fma(a, b, c);
}
inline v_float32x8 v_invsqrt(const v_float32x8& x)
{
v_float32x8 half = x * v256_setall_f32(0.5);
@@ -984,6 +984,13 @@ OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, sum, add, f32)
OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, max, max, f32)
OPENCV_HAL_IMPL_NEON_REDUCE_OP_4(v_float32x4, float32x2, float, min, min, f32)
#if CV_SIMD128_64F
inline double v_reduce_sum(const v_float64x2& a)
{
return vgetq_lane_f64(a.val, 0) + vgetq_lane_f64(a.val, 1);
}
#endif
inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b,
const v_float32x4& c, const v_float32x4& d)
{
@@ -1456,6 +1456,13 @@ OPENCV_HAL_IMPL_SSE_REDUCE_OP_4_SUM(v_uint32x4, unsigned, __m128i, epi32, OPENCV
OPENCV_HAL_IMPL_SSE_REDUCE_OP_4_SUM(v_int32x4, int, __m128i, epi32, OPENCV_HAL_NOP, OPENCV_HAL_NOP, si128_si32)
OPENCV_HAL_IMPL_SSE_REDUCE_OP_4_SUM(v_float32x4, float, __m128, ps, _mm_castps_si128, _mm_castsi128_ps, ss_f32)
inline double v_reduce_sum(const v_float64x2& a)
{
double CV_DECL_ALIGNED(32) idx[2];
v_store_aligned(idx, a);
return idx[0] + idx[1];
}
inline v_float32x4 v_reduce_sum4(const v_float32x4& a, const v_float32x4& b,
const v_float32x4& c, const v_float32x4& d)
{
@@ -716,6 +716,11 @@ OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_float32x4, vec_float4, float, sum, vec_add)
OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_float32x4, vec_float4, float, max, vec_max)
OPENCV_HAL_IMPL_VSX_REDUCE_OP_4(v_float32x4, vec_float4, float, min, vec_min)
inline double v_reduce_sum(const v_float64x2& a)
{
return vec_extract(vec_add(a.val, vec_permi(a.val, a.val, 3)), 0);
}
#define OPENCV_HAL_IMPL_VSX_REDUCE_OP_8(_Tpvec, _Tpvec2, scalartype, suffix, func) \
inline scalartype v_reduce_##suffix(const _Tpvec& a) \
{ \
@@ -8,7 +8,7 @@
#define CV_VERSION_MAJOR 4
#define CV_VERSION_MINOR 0
#define CV_VERSION_REVISION 1
#define CV_VERSION_STATUS "-openvino"
#define CV_VERSION_STATUS ""
#define CVAUX_STR_EXP(__A) #__A
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
+8
View File
@@ -1257,6 +1257,14 @@ struct Device::Impl
else
vendorID_ = UNKNOWN_VENDOR;
const size_t CV_OPENCL_DEVICE_MAX_WORK_GROUP_SIZE = utils::getConfigurationParameterSizeT("OPENCV_OPENCL_DEVICE_MAX_WORK_GROUP_SIZE", 0);
if (CV_OPENCL_DEVICE_MAX_WORK_GROUP_SIZE > 0)
{
const size_t new_maxWorkGroupSize = std::min(maxWorkGroupSize_, CV_OPENCL_DEVICE_MAX_WORK_GROUP_SIZE);
if (new_maxWorkGroupSize != maxWorkGroupSize_)
CV_LOG_WARNING(NULL, "OpenCL: using workgroup size: " << new_maxWorkGroupSize << " (was " << maxWorkGroupSize_ << ")");
maxWorkGroupSize_ = new_maxWorkGroupSize;
}
#if 0
if (isExtensionSupported("cl_khr_spir"))
{
+24
View File
@@ -3,6 +3,12 @@
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#ifdef HAVE_EIGEN
#include <Eigen/Core>
#include <Eigen/Dense>
#include "opencv2/core/eigen.hpp"
#endif
namespace opencv_test { namespace {
class Core_ReduceTest : public cvtest::BaseTest
@@ -1962,4 +1968,22 @@ TEST(Core_Vectors, issue_13078_workaround)
ASSERT_EQ(7, ints[3]);
}
#ifdef HAVE_EIGEN
TEST(Core_Eigen, eigen2cv_check_Mat_type)
{
Mat A(4, 4, CV_32FC1, Scalar::all(0));
Eigen::MatrixXf eigen_A;
cv2eigen(A, eigen_A);
Mat_<float> f_mat;
EXPECT_NO_THROW(eigen2cv(eigen_A, f_mat));
EXPECT_EQ(CV_32FC1, f_mat.type());
Mat_<double> d_mat;
EXPECT_ANY_THROW(eigen2cv(eigen_A, d_mat));
//EXPECT_EQ(CV_64FC1, d_mat.type());
}
#endif // HAVE_EIGEN
}} // namespace
+2 -1
View File
@@ -750,6 +750,7 @@ CV__DNN_INLINE_NS_BEGIN
* @brief Reads a network model stored in <a href="http://torch.ch">Torch7</a> framework's format.
* @param model path to the file, dumped from Torch by using torch.save() function.
* @param isBinary specifies whether the network was serialized in ascii mode or binary.
* @param evaluate specifies testing phase of network. If true, it's similar to evaluate() method in Torch.
* @returns Net object.
*
* @note Ascii mode of Torch serializer is more preferable, because binary mode extensively use `long` type of C language,
@@ -771,7 +772,7 @@ CV__DNN_INLINE_NS_BEGIN
*
* Also some equivalents of these classes from cunn, cudnn, and fbcunn may be successfully imported.
*/
CV_EXPORTS_W Net readNetFromTorch(const String &model, bool isBinary = true);
CV_EXPORTS_W Net readNetFromTorch(const String &model, bool isBinary = true, bool evaluate = true);
/**
* @brief Read deep learning network represented in one of the supported formats.
+1 -1
View File
@@ -6,7 +6,7 @@
#define OPENCV_DNN_VERSION_HPP
/// Use with major OpenCV version only.
#define OPENCV_DNN_API_VERSION 20181205
#define OPENCV_DNN_API_VERSION 20181221
#if !defined CV_DOXYGEN && !defined CV_DNN_DONT_ADD_INLINE_NS
#define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION)
+6
View File
@@ -116,9 +116,15 @@ public:
virtual bool supportBackend(int backendId) CV_OVERRIDE
{
#ifdef HAVE_INF_ENGINE
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R5)
return !zeroDev && eps <= 1e-7f;
#else
return !zeroDev && (preferableTarget == DNN_TARGET_CPU || eps <= 1e-7f);
#endif
else
#endif // HAVE_INF_ENGINE
return backendId == DNN_BACKEND_OPENCV;
}
+129 -8
View File
@@ -6,6 +6,7 @@
// Third party copyrights are property of their respective owners.
#include "../precomp.hpp"
#include <opencv2/dnn/shape_utils.hpp>
#ifdef HAVE_PROTOBUF
@@ -134,9 +135,38 @@ Mat getMatFromTensor(opencv_onnx::TensorProto& tensor_proto)
else
CV_Error(Error::StsUnsupportedFormat, "Unsupported data type: " +
opencv_onnx::TensorProto_DataType_Name(datatype));
if (tensor_proto.dims_size() == 0)
blob.dims = 1; // To force 1-dimensional cv::Mat for scalars.
return blob;
}
void runLayer(Ptr<Layer> layer, const std::vector<Mat>& inputs,
std::vector<Mat>& outputs)
{
std::vector<MatShape> inpShapes(inputs.size());
int ddepth = CV_32F;
for (size_t i = 0; i < inputs.size(); ++i)
{
inpShapes[i] = shape(inputs[i]);
if (i > 0 && ddepth != inputs[i].depth())
CV_Error(Error::StsNotImplemented, "Mixed input data types.");
ddepth = inputs[i].depth();
}
std::vector<MatShape> outShapes, internalShapes;
layer->getMemoryShapes(inpShapes, 0, outShapes, internalShapes);
std::vector<Mat> internals(internalShapes.size());
outputs.resize(outShapes.size());
for (size_t i = 0; i < outShapes.size(); ++i)
outputs[i].create(outShapes[i], ddepth);
for (size_t i = 0; i < internalShapes.size(); ++i)
internals[i].create(internalShapes[i], ddepth);
layer->finalize(inputs, outputs);
layer->forward(inputs, outputs, internals);
}
std::map<std::string, Mat> ONNXImporter::getGraphTensors(
const opencv_onnx::GraphProto& graph_proto)
{
@@ -292,6 +322,26 @@ void ONNXImporter::populateNet(Net dstNet)
CV_Assert(model_proto.has_graph());
opencv_onnx::GraphProto graph_proto = model_proto.graph();
std::map<std::string, Mat> constBlobs = getGraphTensors(graph_proto);
// List of internal blobs shapes.
std::map<std::string, MatShape> outShapes;
// Add all the inputs shapes. It includes as constant blobs as network's inputs shapes.
for (int i = 0; i < graph_proto.input_size(); ++i)
{
opencv_onnx::ValueInfoProto valueInfoProto = graph_proto.input(i);
CV_Assert(valueInfoProto.has_type());
opencv_onnx::TypeProto typeProto = valueInfoProto.type();
CV_Assert(typeProto.has_tensor_type());
opencv_onnx::TypeProto::Tensor tensor = typeProto.tensor_type();
CV_Assert(tensor.has_shape());
opencv_onnx::TensorShapeProto tensorShape = tensor.shape();
MatShape inpShape(tensorShape.dim_size());
for (int j = 0; j < inpShape.size(); ++j)
{
inpShape[j] = tensorShape.dim(j).dim_value();
}
outShapes[valueInfoProto.name()] = inpShape;
}
std::string framework_name;
if (model_proto.has_producer_name()) {
@@ -301,6 +351,7 @@ void ONNXImporter::populateNet(Net dstNet)
// create map with network inputs (without const blobs)
std::map<std::string, LayerInfo> layer_id;
std::map<std::string, LayerInfo>::iterator layerId;
std::map<std::string, MatShape>::iterator shapeIt;
// fill map: push layer name, layer id and output id
std::vector<String> netInputs;
for (int j = 0; j < graph_proto.input_size(); j++)
@@ -317,9 +368,9 @@ void ONNXImporter::populateNet(Net dstNet)
LayerParams layerParams;
opencv_onnx::NodeProto node_proto;
for(int i = 0; i < layersSize; i++)
for(int li = 0; li < layersSize; li++)
{
node_proto = graph_proto.node(i);
node_proto = graph_proto.node(li);
layerParams = getLayerParams(node_proto);
CV_Assert(node_proto.output_size() >= 1);
layerParams.name = node_proto.output(0);
@@ -369,31 +420,30 @@ void ONNXImporter::populateNet(Net dstNet)
}
else if (layer_type == "Sub")
{
Mat blob = (-1.0f) * getBlob(node_proto, constBlobs, 1);
blob = blob.reshape(1, 1);
Mat blob = getBlob(node_proto, constBlobs, 1);
if (blob.total() == 1) {
layerParams.type = "Power";
layerParams.set("shift", blob.at<float>(0));
layerParams.set("shift", -blob.at<float>(0));
}
else {
layerParams.type = "Scale";
layerParams.set("has_bias", true);
layerParams.blobs.push_back(blob);
layerParams.blobs.push_back(-1.0f * blob.reshape(1, 1));
}
}
else if (layer_type == "Div")
{
Mat blob = getBlob(node_proto, constBlobs, 1);
CV_Assert_N(blob.type() == CV_32F, blob.total());
divide(1.0, blob, blob);
if (blob.total() == 1)
{
layerParams.set("scale", blob.at<float>(0));
layerParams.set("scale", 1.0f / blob.at<float>(0));
layerParams.type = "Power";
}
else
{
layerParams.type = "Scale";
divide(1.0, blob, blob);
layerParams.blobs.push_back(blob);
layerParams.set("bias_term", false);
}
@@ -598,6 +648,65 @@ void ONNXImporter::populateNet(Net dstNet)
{
layerParams.type = "Padding";
}
else if (layer_type == "Shape")
{
CV_Assert(node_proto.input_size() == 1);
shapeIt = outShapes.find(node_proto.input(0));
CV_Assert(shapeIt != outShapes.end());
MatShape inpShape = shapeIt->second;
Mat shapeMat(inpShape.size(), 1, CV_32S);
for (int j = 0; j < inpShape.size(); ++j)
shapeMat.at<int>(j) = inpShape[j];
shapeMat.dims = 1;
constBlobs.insert(std::make_pair(layerParams.name, shapeMat));
continue;
}
else if (layer_type == "Gather")
{
CV_Assert(node_proto.input_size() == 2);
CV_Assert(layerParams.has("axis"));
Mat input = getBlob(node_proto, constBlobs, 0);
Mat indexMat = getBlob(node_proto, constBlobs, 1);
CV_Assert_N(indexMat.type() == CV_32S, indexMat.total() == 1);
int index = indexMat.at<int>(0);
int axis = layerParams.get<int>("axis");
std::vector<cv::Range> ranges(input.dims, Range::all());
ranges[axis] = Range(index, index + 1);
Mat out = input(ranges);
constBlobs.insert(std::make_pair(layerParams.name, out));
continue;
}
else if (layer_type == "Concat")
{
bool hasVariableInps = false;
for (int i = 0; i < node_proto.input_size(); ++i)
{
if (layer_id.find(node_proto.input(i)) != layer_id.end())
{
hasVariableInps = true;
break;
}
}
if (!hasVariableInps)
{
std::vector<Mat> inputs(node_proto.input_size()), concatenated;
for (size_t i = 0; i < inputs.size(); ++i)
{
inputs[i] = getBlob(node_proto, constBlobs, i);
}
Ptr<Layer> concat = ConcatLayer::create(layerParams);
runLayer(concat, inputs, concatenated);
CV_Assert(concatenated.size() == 1);
constBlobs.insert(std::make_pair(layerParams.name, concatenated[0]));
continue;
}
}
else
{
for (int j = 0; j < node_proto.input_size(); j++) {
@@ -609,12 +718,24 @@ void ONNXImporter::populateNet(Net dstNet)
int id = dstNet.addLayer(layerParams.name, layerParams.type, layerParams);
layer_id.insert(std::make_pair(layerParams.name, LayerInfo(id, 0)));
std::vector<MatShape> layerInpShapes, layerOutShapes, layerInternalShapes;
for (int j = 0; j < node_proto.input_size(); j++) {
layerId = layer_id.find(node_proto.input(j));
if (layerId != layer_id.end()) {
dstNet.connect(layerId->second.layerId, layerId->second.outputId, id, j);
// Collect input shapes.
shapeIt = outShapes.find(node_proto.input(j));
CV_Assert(shapeIt != outShapes.end());
layerInpShapes.push_back(shapeIt->second);
}
}
// Compute shape of output blob for this layer.
Ptr<Layer> layer = dstNet.getLayer(id);
layer->getMemoryShapes(layerInpShapes, 0, layerOutShapes, layerInternalShapes);
CV_Assert(!layerOutShapes.empty());
outShapes[layerParams.name] = layerOutShapes[0];
}
}
+4 -2
View File
@@ -152,6 +152,7 @@ InfEngineBackendNet::InfEngineBackendNet()
{
targetDevice = InferenceEngine::TargetDevice::eCPU;
precision = InferenceEngine::Precision::FP32;
hasNetOwner = false;
}
InfEngineBackendNet::InfEngineBackendNet(InferenceEngine::CNNNetwork& net)
@@ -162,6 +163,7 @@ InfEngineBackendNet::InfEngineBackendNet(InferenceEngine::CNNNetwork& net)
outputs = net.getOutputsInfo();
layers.resize(net.layerCount()); // A hack to execute InfEngineBackendNet::layerCount correctly.
netOwner = net;
hasNetOwner = true;
}
void InfEngineBackendNet::Release() CV_NOEXCEPT
@@ -178,12 +180,12 @@ void InfEngineBackendNet::setPrecision(InferenceEngine::Precision p) CV_NOEXCEPT
InferenceEngine::Precision InfEngineBackendNet::getPrecision() CV_NOEXCEPT
{
return precision;
return hasNetOwner ? netOwner.getPrecision() : precision;
}
InferenceEngine::Precision InfEngineBackendNet::getPrecision() const CV_NOEXCEPT
{
return precision;
return hasNetOwner ? netOwner.getPrecision() : precision;
}
// Assume that outputs of network is unconnected blobs.
+6 -2
View File
@@ -26,10 +26,11 @@
#define INF_ENGINE_RELEASE_2018R2 2018020000
#define INF_ENGINE_RELEASE_2018R3 2018030000
#define INF_ENGINE_RELEASE_2018R4 2018040000
#define INF_ENGINE_RELEASE_2018R5 2018050000
#ifndef INF_ENGINE_RELEASE
#warning("IE version have not been provided via command-line. Using 2018R4 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2018R4
#warning("IE version have not been provided via command-line. Using 2018R5 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2018R5
#endif
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
@@ -136,6 +137,9 @@ private:
InferenceEngine::InferRequest infRequest;
// In case of models from Model Optimizer we need to manage their lifetime.
InferenceEngine::CNNNetwork netOwner;
// There is no way to check if netOwner is initialized or not so we use
// a separate flag to determine if the model has been loaded from IR.
bool hasNetOwner;
std::string name;
+8 -5
View File
@@ -129,13 +129,15 @@ struct TorchImporter
Module *rootModule;
Module *curModule;
int moduleCounter;
bool testPhase;
TorchImporter(String filename, bool isBinary)
TorchImporter(String filename, bool isBinary, bool evaluate)
{
CV_TRACE_FUNCTION();
rootModule = curModule = NULL;
moduleCounter = 0;
testPhase = evaluate;
file = cv::Ptr<THFile>(THDiskFile_new(filename, "r", 0), THFile_free);
CV_Assert(file && THFile_isOpened(file));
@@ -680,7 +682,8 @@ struct TorchImporter
layerParams.blobs.push_back(tensorParams["bias"].second);
}
if (nnName == "InstanceNormalization")
bool trainPhase = scalarParams.get<bool>("train", false);
if (nnName == "InstanceNormalization" || (trainPhase && !testPhase))
{
cv::Ptr<Module> mvnModule(new Module(nnName));
mvnModule->apiType = "MVN";
@@ -1243,18 +1246,18 @@ struct TorchImporter
Mat readTorchBlob(const String &filename, bool isBinary)
{
TorchImporter importer(filename, isBinary);
TorchImporter importer(filename, isBinary, true);
importer.readObject();
CV_Assert(importer.tensors.size() == 1);
return importer.tensors.begin()->second;
}
Net readNetFromTorch(const String &model, bool isBinary)
Net readNetFromTorch(const String &model, bool isBinary, bool evaluate)
{
CV_TRACE_FUNCTION();
TorchImporter importer(model, isBinary);
TorchImporter importer(model, isBinary, evaluate);
Net net;
importer.populateNet(net);
return net;
+1 -1
View File
@@ -59,7 +59,7 @@ private:
int avg_pool_padded_area_;
int need_mask_;
PaddingMode padding_mode_;
int activation_;
//int activation_;
PoolShaderConfig config_;
};
+7 -3
View File
@@ -281,10 +281,14 @@ Context::~Context()
if (enableValidationLayers) {
auto func = (PFN_vkDestroyDebugReportCallbackEXT)
vkGetInstanceProcAddr(kInstance, "vkDestroyDebugReportCallbackEXT");
if (func == nullptr) {
throw std::runtime_error("Could not load vkDestroyDebugReportCallbackEXT");
if (func == nullptr)
{
CV_LOG_FATAL(NULL, "Could not load vkDestroyDebugReportCallbackEXT");
}
else
{
func(kInstance, kDebugReportCallback, NULL);
}
func(kInstance, kDebugReportCallback, NULL);
}
kShaders.clear();
vkDestroyInstance(kInstance, NULL);
+2 -1
View File
@@ -12,8 +12,9 @@ namespace cv { namespace dnn { namespace vkcom {
#ifdef HAVE_VULKAN
struct Context
class Context
{
public:
Context();
~Context();
};
+4 -2
View File
@@ -45,7 +45,9 @@ void OpBase::initVulkanThing(int buffer_num)
void OpBase::createDescriptorSetLayout(int buffer_num)
{
VkDescriptorSetLayoutBinding bindings[buffer_num] = {};
if (buffer_num <= 0)
return;
std::vector<VkDescriptorSetLayoutBinding> bindings(buffer_num);
for (int i = 0; i < buffer_num; i++)
{
bindings[i].binding = i;
@@ -56,7 +58,7 @@ void OpBase::createDescriptorSetLayout(int buffer_num)
VkDescriptorSetLayoutCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
info.bindingCount = buffer_num;
info.pBindings = bindings;
info.pBindings = &bindings[0];
VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device_, &info, NULL, &descriptor_set_layout_));
}
+2 -2
View File
@@ -226,9 +226,9 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
TEST_P(DNNTestNetwork, OpenFace)
{
#if defined(INF_ENGINE_RELEASE)
#if INF_ENGINE_RELEASE < 2018030000
#if (INF_ENGINE_RELEASE < 2018030000 || INF_ENGINE_RELEASE == 2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is enabled starts from OpenVINO 2018R3");
throw SkipTestException("");
#elif INF_ENGINE_RELEASE < 2018040000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
throw SkipTestException("Test is enabled starts from OpenVINO 2018R4");
+1
View File
@@ -471,6 +471,7 @@ TEST(Test_Caffe, shared_weights)
net.setInput(blob_1, "input_1");
net.setInput(blob_2, "input_2");
net.setPreferableBackend(DNN_BACKEND_OPENCV);
Mat sum = net.forward();
+1 -1
View File
@@ -306,7 +306,7 @@ TEST_P(Test_Darknet_nets, TinyYoloVoc)
// batch size 1
testDarknetModel(config_file, weights_file, ref.rowRange(0, 2), scoreDiff, iouDiff);
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018040000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018040000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_MYRIAD)
#endif
// batch size 2
+1 -1
View File
@@ -166,7 +166,7 @@ TEST_P(Deconvolution, Accuracy)
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU &&
dilation.width == 2 && dilation.height == 2)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018040000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018040000
if (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU &&
hasBias && group != 1)
throw SkipTestException("Test is disabled for OpenVINO 2018R4");
+8
View File
@@ -190,6 +190,14 @@ TEST_P(DNNTestOpenVINO, models)
modelName == "landmarks-regression-retail-0009" ||
modelName == "semantic-segmentation-adas-0001")))
throw SkipTestException("");
#elif INF_ENGINE_RELEASE == 2018050000
if (modelName == "single-image-super-resolution-0063" ||
modelName == "single-image-super-resolution-1011" ||
modelName == "single-image-super-resolution-1021" ||
(target == DNN_TARGET_OPENCL_FP16 && modelName == "face-reidentification-retail-0095") ||
(target == DNN_TARGET_MYRIAD && (modelName == "license-plate-recognition-barrier-0001" ||
modelName == "semantic-segmentation-adas-0001")))
throw SkipTestException("");
#endif
#endif
+75 -23
View File
@@ -137,7 +137,7 @@ TEST_P(Test_Caffe_layers, Convolution)
TEST_P(Test_Caffe_layers, DeConvolution)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018040000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018040000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_CPU)
throw SkipTestException("Test is disabled for OpenVINO 2018R4");
#endif
@@ -295,6 +295,10 @@ TEST_P(Test_Caffe_layers, Eltwise)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL)
throw SkipTestException("Test is disabled for OpenVINO 2018R5");
#endif
testLayerUsingCaffeModels("layer_eltwise");
}
@@ -918,8 +922,11 @@ INSTANTIATE_TEST_CASE_P(/**/, Layer_Test_DWconv_Prelu, Combine(Values(3, 6), Val
// Using Intel's Model Optimizer generate .xml and .bin files:
// ./ModelOptimizer -w /path/to/caffemodel -d /path/to/prototxt \
// -p FP32 -i -b ${batch_size} -o /path/to/output/folder
TEST(Layer_Test_Convolution_DLDT, Accuracy)
typedef testing::TestWithParam<Target> Layer_Test_Convolution_DLDT;
TEST_P(Layer_Test_Convolution_DLDT, Accuracy)
{
Target targetId = GetParam();
Net netDefault = readNet(_tf("layer_convolution.caffemodel"), _tf("layer_convolution.prototxt"));
Net net = readNet(_tf("layer_convolution.xml"), _tf("layer_convolution.bin"));
@@ -930,17 +937,29 @@ TEST(Layer_Test_Convolution_DLDT, Accuracy)
Mat outDefault = netDefault.forward();
net.setInput(inp);
Mat out = net.forward();
net.setPreferableTarget(targetId);
normAssert(outDefault, out);
if (targetId != DNN_TARGET_MYRIAD)
{
Mat out = net.forward();
std::vector<int> outLayers = net.getUnconnectedOutLayers();
ASSERT_EQ(net.getLayer(outLayers[0])->name, "output_merge");
ASSERT_EQ(net.getLayer(outLayers[0])->type, "Concat");
normAssert(outDefault, out);
std::vector<int> outLayers = net.getUnconnectedOutLayers();
ASSERT_EQ(net.getLayer(outLayers[0])->name, "output_merge");
ASSERT_EQ(net.getLayer(outLayers[0])->type, "Concat");
}
else
{
// An assertion is expected because the model is in FP32 format but
// Myriad plugin supports only FP16 models.
ASSERT_ANY_THROW(net.forward());
}
}
TEST(Layer_Test_Convolution_DLDT, setInput_uint8)
TEST_P(Layer_Test_Convolution_DLDT, setInput_uint8)
{
Target targetId = GetParam();
Mat inp = blobFromNPY(_tf("blob.npy"));
Mat inputs[] = {Mat(inp.dims, inp.size, CV_8U), Mat()};
@@ -951,12 +970,25 @@ TEST(Layer_Test_Convolution_DLDT, setInput_uint8)
for (int i = 0; i < 2; ++i)
{
Net net = readNet(_tf("layer_convolution.xml"), _tf("layer_convolution.bin"));
net.setPreferableTarget(targetId);
net.setInput(inputs[i]);
outs[i] = net.forward();
ASSERT_EQ(outs[i].type(), CV_32F);
if (targetId != DNN_TARGET_MYRIAD)
{
outs[i] = net.forward();
ASSERT_EQ(outs[i].type(), CV_32F);
}
else
{
// An assertion is expected because the model is in FP32 format but
// Myriad plugin supports only FP16 models.
ASSERT_ANY_THROW(net.forward());
}
}
normAssert(outs[0], outs[1]);
if (targetId != DNN_TARGET_MYRIAD)
normAssert(outs[0], outs[1]);
}
INSTANTIATE_TEST_CASE_P(/**/, Layer_Test_Convolution_DLDT,
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE)));
// 1. Create a .prototxt file with the following network:
// layer {
@@ -980,14 +1012,17 @@ TEST(Layer_Test_Convolution_DLDT, setInput_uint8)
// net.save('/path/to/caffemodel')
//
// 3. Convert using ModelOptimizer.
typedef testing::TestWithParam<tuple<int, int> > Test_DLDT_two_inputs;
typedef testing::TestWithParam<tuple<int, int, Target> > Test_DLDT_two_inputs;
TEST_P(Test_DLDT_two_inputs, as_IR)
{
int firstInpType = get<0>(GetParam());
int secondInpType = get<1>(GetParam());
// TODO: It looks like a bug in Inference Engine.
Target targetId = get<2>(GetParam());
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE < 2018040000
if (secondInpType == CV_8U)
throw SkipTestException("");
throw SkipTestException("Test is enabled starts from OpenVINO 2018R4");
#endif
Net net = readNet(_tf("net_two_inputs.xml"), _tf("net_two_inputs.bin"));
int inpSize[] = {1, 2, 3};
@@ -998,11 +1033,21 @@ TEST_P(Test_DLDT_two_inputs, as_IR)
net.setInput(firstInp, "data");
net.setInput(secondInp, "second_input");
Mat out = net.forward();
net.setPreferableTarget(targetId);
if (targetId != DNN_TARGET_MYRIAD)
{
Mat out = net.forward();
Mat ref;
cv::add(firstInp, secondInp, ref, Mat(), CV_32F);
normAssert(out, ref);
Mat ref;
cv::add(firstInp, secondInp, ref, Mat(), CV_32F);
normAssert(out, ref);
}
else
{
// An assertion is expected because the model is in FP32 format but
// Myriad plugin supports only FP16 models.
ASSERT_ANY_THROW(net.forward());
}
}
TEST_P(Test_DLDT_two_inputs, as_backend)
@@ -1010,6 +1055,8 @@ TEST_P(Test_DLDT_two_inputs, as_backend)
static const float kScale = 0.5f;
static const float kScaleInv = 1.0f / kScale;
Target targetId = get<2>(GetParam());
Net net;
LayerParams lp;
lp.type = "Eltwise";
@@ -1018,9 +1065,9 @@ TEST_P(Test_DLDT_two_inputs, as_backend)
int eltwiseId = net.addLayerToPrev(lp.name, lp.type, lp); // connect to a first input
net.connect(0, 1, eltwiseId, 1); // connect to a second input
int inpSize[] = {1, 2, 3};
Mat firstInp(3, &inpSize[0], get<0>(GetParam()));
Mat secondInp(3, &inpSize[0], get<1>(GetParam()));
int inpSize[] = {1, 2, 3, 4};
Mat firstInp(4, &inpSize[0], get<0>(GetParam()));
Mat secondInp(4, &inpSize[0], get<1>(GetParam()));
randu(firstInp, 0, 255);
randu(secondInp, 0, 255);
@@ -1028,15 +1075,20 @@ TEST_P(Test_DLDT_two_inputs, as_backend)
net.setInput(firstInp, "data", kScale);
net.setInput(secondInp, "second_input", kScaleInv);
net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
net.setPreferableTarget(targetId);
Mat out = net.forward();
Mat ref;
addWeighted(firstInp, kScale, secondInp, kScaleInv, 0, ref, CV_32F);
normAssert(out, ref);
// Output values are in range [0, 637.5].
double l1 = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 0.06 : 1e-6;
double lInf = (targetId == DNN_TARGET_OPENCL_FP16 || targetId == DNN_TARGET_MYRIAD) ? 0.3 : 1e-5;
normAssert(out, ref, "", l1, lInf);
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_DLDT_two_inputs, Combine(
Values(CV_8U, CV_32F), Values(CV_8U, CV_32F)
Values(CV_8U, CV_32F), Values(CV_8U, CV_32F),
testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE))
));
class UnsupportedLayer : public Layer
+26 -2
View File
@@ -162,6 +162,12 @@ TEST_P(Test_ONNX_layers, MultyInputs)
normAssert(ref, out, "", default_l1, default_lInf);
}
TEST_P(Test_ONNX_layers, DynamicReshape)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("");
testONNXModels("dynamic_reshape");
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_ONNX_layers, dnnBackendsAndTargets());
@@ -245,6 +251,10 @@ TEST_P(Test_ONNX_nets, VGG16)
else if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL) {
lInf = 1.2e-4;
}
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
l1 = 0.131;
#endif
testONNXModels("vgg16", pb, l1, lInf);
}
@@ -323,7 +333,7 @@ TEST_P(Test_ONNX_nets, CNN_MNIST)
TEST_P(Test_ONNX_nets, MobileNet_v2)
{
// output range: [-166; 317]
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.38 : 7e-5;
const double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.4 : 7e-5;
const double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 2.87 : 5e-4;
testONNXModels("mobilenetv2", pb, l1, lInf);
}
@@ -346,7 +356,17 @@ TEST_P(Test_ONNX_nets, LResNet100E_IR)
TEST_P(Test_ONNX_nets, Emotion_ferplus)
{
testONNXModels("emotion_ferplus", pb);
double l1 = default_l1;
double lInf = default_lInf;
// Output values are in range [-2.01109, 2.11111]
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
l1 = 0.007;
else if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
{
l1 = 0.021;
lInf = 0.034;
}
testONNXModels("emotion_ferplus", pb, l1, lInf);
}
TEST_P(Test_ONNX_nets, Inception_v2)
@@ -367,6 +387,10 @@ TEST_P(Test_ONNX_nets, DenseNet121)
TEST_P(Test_ONNX_nets, Inception_v1)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
#endif
testONNXModels("inception_v1", pb);
}
+12
View File
@@ -241,6 +241,10 @@ TEST_P(Test_TensorFlow_layers, unfused_flatten)
TEST_P(Test_TensorFlow_layers, leaky_relu)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL)
throw SkipTestException("");
#endif
runTensorFlowNet("leaky_relu_order1");
runTensorFlowNet("leaky_relu_order2");
runTensorFlowNet("leaky_relu_order3");
@@ -383,6 +387,10 @@ TEST_P(Test_TensorFlow_nets, Faster_RCNN)
TEST_P(Test_TensorFlow_nets, MobileNet_v1_SSD_PPN)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("Unstable test case");
#endif
checkBackend();
std::string proto = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pbtxt", false);
std::string model = findDataFile("dnn/ssd_mobilenet_v1_ppn_coco.pb", false);
@@ -560,6 +568,10 @@ TEST_P(Test_TensorFlow_layers, slice)
if (backend == DNN_BACKEND_INFERENCE_ENGINE &&
(target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
throw SkipTestException("");
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
#endif
runTensorFlowNet("slice_4d");
}
+15 -10
View File
@@ -73,7 +73,7 @@ class Test_Torch_layers : public DNNTestLayer
{
public:
void runTorchNet(const String& prefix, String outLayerName = "",
bool check2ndBlob = false, bool isBinary = false,
bool check2ndBlob = false, bool isBinary = false, bool evaluate = true,
double l1 = 0.0, double lInf = 0.0)
{
String suffix = (isBinary) ? ".dat" : ".txt";
@@ -84,7 +84,7 @@ public:
checkBackend(backend, target, &inp, &outRef);
Net net = readNetFromTorch(_tf(prefix + "_net" + suffix), isBinary);
Net net = readNetFromTorch(_tf(prefix + "_net" + suffix), isBinary, evaluate);
ASSERT_FALSE(net.empty());
net.setPreferableBackend(backend);
@@ -114,7 +114,7 @@ TEST_P(Test_Torch_layers, run_convolution)
// Output reference values are in range [23.4018, 72.0181]
double l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.08 : default_l1;
double lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.42 : default_lInf;
runTorchNet("net_conv", "", false, true, l1, lInf);
runTorchNet("net_conv", "", false, true, true, l1, lInf);
}
TEST_P(Test_Torch_layers, run_pool_max)
@@ -136,7 +136,7 @@ TEST_P(Test_Torch_layers, run_reshape_change_batch_size)
TEST_P(Test_Torch_layers, run_reshape)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018040000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018040000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is disabled for OpenVINO 2018R4");
#endif
@@ -147,7 +147,7 @@ TEST_P(Test_Torch_layers, run_reshape)
TEST_P(Test_Torch_layers, run_reshape_single_sample)
{
// Reference output values in range [14.4586, 18.4492].
runTorchNet("net_reshape_single_sample", "", false, false,
runTorchNet("net_reshape_single_sample", "", false, false, true,
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.0073 : default_l1,
(target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.025 : default_lInf);
}
@@ -166,13 +166,13 @@ TEST_P(Test_Torch_layers, run_concat)
TEST_P(Test_Torch_layers, run_depth_concat)
{
runTorchNet("net_depth_concat", "", false, true, 0.0,
runTorchNet("net_depth_concat", "", false, true, true, 0.0,
target == DNN_TARGET_OPENCL_FP16 ? 0.021 : 0.0);
}
TEST_P(Test_Torch_layers, run_deconv)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018040000
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE >= 2018040000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is disabled for OpenVINO 2018R4");
#endif
@@ -182,6 +182,7 @@ TEST_P(Test_Torch_layers, run_deconv)
TEST_P(Test_Torch_layers, run_batch_norm)
{
runTorchNet("net_batch_norm", "", false, true);
runTorchNet("net_batch_norm_train", "", false, true, false);
}
TEST_P(Test_Torch_layers, net_prelu)
@@ -216,7 +217,7 @@ TEST_P(Test_Torch_layers, net_conv_gemm_lrn)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
runTorchNet("net_conv_gemm_lrn", "", false, true,
runTorchNet("net_conv_gemm_lrn", "", false, true, true,
target == DNN_TARGET_OPENCL_FP16 ? 0.046 : 0.0,
target == DNN_TARGET_OPENCL_FP16 ? 0.023 : 0.0);
}
@@ -266,9 +267,9 @@ class Test_Torch_nets : public DNNTestLayer {};
TEST_P(Test_Torch_nets, OpenFace_accuracy)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE < 2018030000
#if defined(INF_ENGINE_RELEASE) && (INF_ENGINE_RELEASE < 2018030000 || INF_ENGINE_RELEASE == 2018050000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("Test is enabled starts from OpenVINO 2018R3");
throw SkipTestException("");
#endif
checkBackend();
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
@@ -389,6 +390,10 @@ TEST_P(Test_Torch_nets, ENet_accuracy)
// -model models/instance_norm/feathers.t7
TEST_P(Test_Torch_nets, FastNeuralStyle_accuracy)
{
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE == 2018050000
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
#endif
checkBackend();
std::string models[] = {"dnn/fast_neural_style_eccv16_starry_night.t7",
"dnn/fast_neural_style_instance_norm_feathers.t7"};
@@ -289,14 +289,14 @@ public:
/** @brief Set detection threshold.
@param threshold AGAST detection threshold score.
*/
CV_WRAP virtual void setThreshold(int threshold) { CV_UNUSED(threshold); return; };
CV_WRAP virtual int getThreshold() const { return -1; };
CV_WRAP virtual void setThreshold(int threshold) { CV_UNUSED(threshold); return; }
CV_WRAP virtual int getThreshold() const { return -1; }
/** @brief Set detection octaves.
@param octaves detection octaves. Use 0 to do single scale.
*/
CV_WRAP virtual void setOctaves(int octaves) { CV_UNUSED(octaves); return; };
CV_WRAP virtual int getOctaves() const { return -1; };
CV_WRAP virtual void setOctaves(int octaves) { CV_UNUSED(octaves); return; }
CV_WRAP virtual int getOctaves() const { return -1; }
};
/** @brief Class implementing the ORB (*oriented BRIEF*) keypoint detector and descriptor extractor
@@ -488,9 +488,9 @@ FastFeatureDetector::TYPE_5_8
Detects corners using the FAST algorithm by @cite Rosten06 .
@note In Python API, types are given as cv2.FAST_FEATURE_DETECTOR_TYPE_5_8,
cv2.FAST_FEATURE_DETECTOR_TYPE_7_12 and cv2.FAST_FEATURE_DETECTOR_TYPE_9_16. For corner
detection, use cv2.FAST.detect() method.
@note In Python API, types are given as cv.FAST_FEATURE_DETECTOR_TYPE_5_8,
cv.FAST_FEATURE_DETECTOR_TYPE_7_12 and cv.FAST_FEATURE_DETECTOR_TYPE_9_16. For corner
detection, use cv.FAST.detect() method.
*/
CV_EXPORTS void FAST( InputArray image, CV_OUT std::vector<KeyPoint>& keypoints,
int threshold, bool nonmaxSuppression, FastFeatureDetector::DetectorType type );
@@ -1224,9 +1224,9 @@ output image. See possible flags bit values below.
DrawMatchesFlags. See details above in drawMatches .
@note
For Python API, flags are modified as cv2.DRAW_MATCHES_FLAGS_DEFAULT,
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG,
cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
For Python API, flags are modified as cv.DRAW_MATCHES_FLAGS_DEFAULT,
cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS, cv.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG,
cv.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
*/
CV_EXPORTS_W void drawKeypoints( InputArray image, const std::vector<KeyPoint>& keypoints, InputOutputArray outImage,
const Scalar& color=Scalar::all(-1), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT );
@@ -7,11 +7,13 @@ import java.util.List;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfInt;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Range;
import org.opencv.core.Scalar;
import org.opencv.core.DMatch;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.features2d.Features2d;
@@ -141,4 +143,30 @@ public class Features2dTest extends OpenCVTestCase {
Imgcodecs.imwrite(outputPath, outimg);
// OpenCVTestRunner.Log("Output image is saved to: " + outputPath);
}
public void testDrawKeypoints()
{
Mat outImg = Mat.ones(11, 11, CvType.CV_8U);
MatOfKeyPoint kps = new MatOfKeyPoint(new KeyPoint(5, 5, 1)); // x, y, size
Features2d.drawKeypoints(new Mat(), kps, outImg, new Scalar(255),
Features2d.DrawMatchesFlags_DRAW_OVER_OUTIMG);
Mat ref = new MatOfInt(new int[] {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 15, 54, 15, 1, 1, 1, 1,
1, 1, 1, 76, 217, 217, 221, 81, 1, 1, 1,
1, 1, 100, 224, 111, 57, 115, 225, 101, 1, 1,
1, 44, 215, 100, 1, 1, 1, 101, 214, 44, 1,
1, 54, 212, 57, 1, 1, 1, 55, 212, 55, 1,
1, 40, 215, 104, 1, 1, 1, 105, 215, 40, 1,
1, 1, 102, 221, 111, 55, 115, 222, 103, 1, 1,
1, 1, 1, 76, 218, 217, 220, 81, 1, 1, 1,
1, 1, 1, 1, 15, 55, 15, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
}).reshape(1, 11);
ref.convertTo(ref, CvType.CV_8U);
assertMatEqual(ref, outImg);
}
}
+1 -1
View File
@@ -77,7 +77,7 @@ void KeyPointsFilter::retainBest(std::vector<KeyPoint>& keypoints, int n_points)
return;
}
//first use nth element to partition the keypoints into the best and worst.
std::nth_element(keypoints.begin(), keypoints.begin() + n_points, keypoints.end(), KeypointResponseGreater());
std::nth_element(keypoints.begin(), keypoints.begin() + n_points - 1, keypoints.end(), KeypointResponseGreater());
//this is the boundary response, and in the case of FAST may be ambiguous
float ambiguous_response = keypoints[n_points - 1].response;
//use std::partition to grab all of the keypoints with the boundary response.
+38
View File
@@ -0,0 +1,38 @@
// 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"
namespace opencv_test { namespace {
TEST(Features2D_KeypointUtils, retainBest_issue_12594)
{
const size_t N = 9;
// Construct 4-way tie for 3rd highest - correct answer for "3 best" is 6
const float no_problem[] = { 5.0f, 4.0f, 1.0f, 2.0f, 0.0f, 3.0f, 3.0f, 3.0f, 3.0f };
// Same set, different order that exposes partial sort property of std::nth_element
// Note: the problem case may depend on your particular implementation of STL
const float problem[] = { 3.0f, 3.0f, 3.0f, 3.0f, 4.0f, 5.0f, 0.0f, 1.0f, 2.0f };
const size_t NBEST = 3u;
const size_t ANSWER = 6u;
std::vector<cv::KeyPoint> sorted_cv(N);
std::vector<cv::KeyPoint> unsorted_cv(N);
for (size_t i = 0; i < N; ++i)
{
sorted_cv[i].response = no_problem[i];
unsorted_cv[i].response = problem[i];
}
cv::KeyPointsFilter::retainBest(sorted_cv, NBEST);
cv::KeyPointsFilter::retainBest(unsorted_cv, NBEST);
EXPECT_EQ(ANSWER, sorted_cv.size());
EXPECT_EQ(ANSWER, unsorted_cv.size());
}
}} // namespace
@@ -16,6 +16,4 @@ namespace util
} // namespace util
} // namespace cv
#define UNUSED(x) cv::util::suppress_unused_warning(x)
#endif /* OPENCV_GAPI_UTIL_COMPILER_HINTS_HPP */
@@ -340,7 +340,7 @@ static void run_arithm_s3(uchar out[], const uchar in[], int width, const uchar
v_store_interleave(&out[3*w], x, y, z);
}
#endif
UNUSED(v_op);
cv::util::suppress_unused_warning(v_op);
for (; w < width; w++)
{
out[3*w ] = saturate<uchar>( s_op(in[3*w ], scalar[0]) );
@@ -386,7 +386,7 @@ static void run_arithm_s1(uchar out[], const float in[], int width, const float
v_store(&out[w], uc);
}
#endif
UNUSED(v_op);
cv::util::suppress_unused_warning(v_op);
for (; w < width; w++)
{
out[w] = saturate<uchar>(s_op(in[w], scalar[0]), std::roundf);
@@ -10,7 +10,7 @@
#include <limits>
#include <type_traits>
#include <opencv2/gapi/util/compiler_hints.hpp> //UNUSED
#include <opencv2/gapi/util/compiler_hints.hpp> //suppress_unused_warning
#include <opencv2/gapi/own/saturate.hpp>
namespace cv {
@@ -102,7 +102,7 @@ cv::gimpl::GOCLExecutable::GOCLExecutable(const ade::Graph &g,
{
const auto mat_desc = util::get<cv::GMatDesc>(desc.meta);
const auto type = CV_MAKETYPE(mat_desc.depth, mat_desc.chan);
m_res.slot<cv::UMat>()[desc.rc].create(mat_desc.size.width, mat_desc.size.height, type);
m_res.slot<cv::UMat>()[desc.rc].create(mat_desc.size.height, mat_desc.size.width, type);
}
break;
}
+4 -2
View File
@@ -104,11 +104,13 @@ cv::gimpl::GCompiler::GCompiler(const cv::GComputation &c,
// Remove GCompoundBackend to avoid calling setupBackend() with it in the list
m_all_kernels.remove(cv::gapi::compound::backend());
m_e.addPass("init", "resolve_kernels", std::bind(passes::resolveKernels, _1,
m_e.addPassStage("kernels");
m_e.addPass("kernels", "resolve_kernels", std::bind(passes::resolveKernels, _1,
std::ref(m_all_kernels), // NB: and not copied here
lookup_order));
m_e.addPass("kernels", "check_islands_content", passes::checkIslandsContent);
m_e.addPass("init", "check_islands_content", passes::checkIslandsContent);
m_e.addPassStage("meta");
m_e.addPass("meta", "initialize", std::bind(passes::initMeta, _1, std::ref(m_metas)));
m_e.addPass("meta", "propagate", std::bind(passes::inferMeta, _1, false));
+1 -1
View File
@@ -26,7 +26,7 @@ ade::NodeHandle GModel::mkOpNode(GModel::Graph &g, const GKernel &k, const std::
ade::NodeHandle op_h = g.createNode();
g.metadata(op_h).set(NodeType{NodeType::OP});
//These extra empty {} are to please GCC (-Wmissing-field-initializers)
g.metadata(op_h).set(Op{k, args, {}, {}, {}});
g.metadata(op_h).set(Op{k, args, {}, {}});
if (!island.empty())
g.metadata(op_h).set(Island{island});
return op_h;
-1
View File
@@ -61,7 +61,6 @@ struct Op
std::vector<RcDesc> outs; // TODO: Introduce a new type for resource references
cv::gapi::GBackend backend;
util::any opaque;
};
struct Data
+25
View File
@@ -116,6 +116,31 @@ PERF_TEST_P(MatSize, equalizeHist,
}
#undef MatSize
typedef TestBaseWithParam< tuple<int, int> > Dim_Cmpmethod;
PERF_TEST_P(Dim_Cmpmethod, compareHist,
testing::Combine(testing::Values(1, 3),
testing::Values(HISTCMP_CORREL, HISTCMP_CHISQR, HISTCMP_INTERSECT, HISTCMP_BHATTACHARYYA, HISTCMP_CHISQR_ALT, HISTCMP_KL_DIV))
)
{
int dims = get<0>(GetParam());
int method = get<1>(GetParam());
int histSize[] = { 2048, 128, 64 };
Mat hist1(dims, histSize, CV_32FC1);
Mat hist2(dims, histSize, CV_32FC1);
randu(hist1, 0, 256);
randu(hist2, 0, 256);
declare.in(hist1.reshape(1, 256), hist2.reshape(1, 256));
TEST_CYCLE()
{
compareHist(hist1, hist2, method);
}
SANITY_CHECK_NOTHING();
}
typedef tuple<Size, double> Sz_ClipLimit_t;
typedef TestBaseWithParam<Sz_ClipLimit_t> Sz_ClipLimit;
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -441,7 +441,7 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
ocl_sepFilter3x3_8UC1(_src, _dst, ddepth, kx, ky, delta, borderType));
CV_OCL_RUN(ocl::isOpenCLActivated() && _dst.isUMat() && _src.dims() <= 2 && (size_t)_src.rows() > kx.total() && (size_t)_src.cols() > kx.total(),
ocl_sepFilter2D(_src, _dst, ddepth, kx, ky, Point(-1, -1), 0, borderType))
ocl_sepFilter2D(_src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType))
Mat src = _src.getMat();
Mat dst = _dst.getMat();
@@ -494,7 +494,7 @@ void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
CV_OCL_RUN(ocl::isOpenCLActivated() && _dst.isUMat() && _src.dims() <= 2 &&
(size_t)_src.rows() > kx.total() && (size_t)_src.cols() > kx.total(),
ocl_sepFilter2D(_src, _dst, ddepth, kx, ky, Point(-1, -1), 0, borderType))
ocl_sepFilter2D(_src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType))
Mat src = _src.getMat();
Mat dst = _dst.getMat();
File diff suppressed because it is too large Load Diff
+105 -94
View File
@@ -41,6 +41,7 @@
#include "precomp.hpp"
#include "opencl_kernels_imgproc.hpp"
#include "opencv2/core/hal/intrin.hpp"
#include "opencv2/core/openvx/ovx_defs.hpp"
@@ -1938,10 +1939,6 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
CV_Assert( it.planes[0].isContinuous() && it.planes[1].isContinuous() );
#if CV_SSE2
bool haveSIMD = checkHardwareSupport(CV_CPU_SSE2);
#endif
for( size_t i = 0; i < it.nplanes; i++, ++it )
{
const float* h1 = it.planes[0].ptr<float>();
@@ -1961,50 +1958,63 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
}
else if( method == CV_COMP_CORREL )
{
#if CV_SSE2
if (haveSIMD)
#if CV_SIMD_64F
v_float64 v_s1 = vx_setzero_f64();
v_float64 v_s2 = vx_setzero_f64();
v_float64 v_s11 = vx_setzero_f64();
v_float64 v_s12 = vx_setzero_f64();
v_float64 v_s22 = vx_setzero_f64();
for ( ; j <= len - v_float32::nlanes; j += v_float32::nlanes)
{
__m128d v_s1 = _mm_setzero_pd(), v_s2 = v_s1;
__m128d v_s11 = v_s1, v_s22 = v_s1, v_s12 = v_s1;
v_float32 v_a = vx_load(h1 + j);
v_float32 v_b = vx_load(h2 + j);
for ( ; j <= len - 4; j += 4)
{
__m128 v_a = _mm_loadu_ps(h1 + j);
__m128 v_b = _mm_loadu_ps(h2 + j);
// 0-1
v_float64 v_ad = v_cvt_f64(v_a);
v_float64 v_bd = v_cvt_f64(v_b);
v_s12 = v_muladd(v_ad, v_bd, v_s12);
v_s11 = v_muladd(v_ad, v_ad, v_s11);
v_s22 = v_muladd(v_bd, v_bd, v_s22);
v_s1 += v_ad;
v_s2 += v_bd;
// 0-1
__m128d v_ad = _mm_cvtps_pd(v_a);
__m128d v_bd = _mm_cvtps_pd(v_b);
v_s12 = _mm_add_pd(v_s12, _mm_mul_pd(v_ad, v_bd));
v_s11 = _mm_add_pd(v_s11, _mm_mul_pd(v_ad, v_ad));
v_s22 = _mm_add_pd(v_s22, _mm_mul_pd(v_bd, v_bd));
v_s1 = _mm_add_pd(v_s1, v_ad);
v_s2 = _mm_add_pd(v_s2, v_bd);
// 2-3
v_ad = _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_a), 8)));
v_bd = _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_b), 8)));
v_s12 = _mm_add_pd(v_s12, _mm_mul_pd(v_ad, v_bd));
v_s11 = _mm_add_pd(v_s11, _mm_mul_pd(v_ad, v_ad));
v_s22 = _mm_add_pd(v_s22, _mm_mul_pd(v_bd, v_bd));
v_s1 = _mm_add_pd(v_s1, v_ad);
v_s2 = _mm_add_pd(v_s2, v_bd);
}
double CV_DECL_ALIGNED(16) ar[10];
_mm_store_pd(ar, v_s12);
_mm_store_pd(ar + 2, v_s11);
_mm_store_pd(ar + 4, v_s22);
_mm_store_pd(ar + 6, v_s1);
_mm_store_pd(ar + 8, v_s2);
s12 += ar[0] + ar[1];
s11 += ar[2] + ar[3];
s22 += ar[4] + ar[5];
s1 += ar[6] + ar[7];
s2 += ar[8] + ar[9];
// 2-3
v_ad = v_cvt_f64_high(v_a);
v_bd = v_cvt_f64_high(v_b);
v_s12 = v_muladd(v_ad, v_bd, v_s12);
v_s11 = v_muladd(v_ad, v_ad, v_s11);
v_s22 = v_muladd(v_bd, v_bd, v_s22);
v_s1 += v_ad;
v_s2 += v_bd;
}
#endif
s12 += v_reduce_sum(v_s12);
s11 += v_reduce_sum(v_s11);
s22 += v_reduce_sum(v_s22);
s1 += v_reduce_sum(v_s1);
s2 += v_reduce_sum(v_s2);
#elif CV_SIMD && 0 //Disable vectorization for CV_COMP_CORREL if f64 is unsupported due to low precision
v_float32 v_s1 = vx_setzero_f32();
v_float32 v_s2 = vx_setzero_f32();
v_float32 v_s11 = vx_setzero_f32();
v_float32 v_s12 = vx_setzero_f32();
v_float32 v_s22 = vx_setzero_f32();
for (; j <= len - v_float32::nlanes; j += v_float32::nlanes)
{
v_float32 v_a = vx_load(h1 + j);
v_float32 v_b = vx_load(h2 + j);
v_s12 = v_muladd(v_a, v_b, v_s12);
v_s11 = v_muladd(v_a, v_a, v_s11);
v_s22 = v_muladd(v_b, v_b, v_s22);
v_s1 += v_a;
v_s2 += v_b;
}
s12 += v_reduce_sum(v_s12);
s11 += v_reduce_sum(v_s11);
s22 += v_reduce_sum(v_s22);
s1 += v_reduce_sum(v_s1);
s2 += v_reduce_sum(v_s2);
#endif
for( ; j < len; j++ )
{
double a = h1[j];
@@ -2019,67 +2029,68 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
}
else if( method == CV_COMP_INTERSECT )
{
#if CV_NEON
float32x4_t v_result = vdupq_n_f32(0.0f);
for( ; j <= len - 4; j += 4 )
v_result = vaddq_f32(v_result, vminq_f32(vld1q_f32(h1 + j), vld1q_f32(h2 + j)));
float CV_DECL_ALIGNED(16) ar[4];
vst1q_f32(ar, v_result);
result += ar[0] + ar[1] + ar[2] + ar[3];
#elif CV_SSE2
if (haveSIMD)
#if CV_SIMD_64F
v_float64 v_result = vx_setzero_f64();
for ( ; j <= len - v_float32::nlanes; j += v_float32::nlanes)
{
__m128d v_result = _mm_setzero_pd();
for ( ; j <= len - 4; j += 4)
{
__m128 v_src = _mm_min_ps(_mm_loadu_ps(h1 + j),
_mm_loadu_ps(h2 + j));
v_result = _mm_add_pd(v_result, _mm_cvtps_pd(v_src));
v_src = _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_src), 8));
v_result = _mm_add_pd(v_result, _mm_cvtps_pd(v_src));
}
double CV_DECL_ALIGNED(16) ar[2];
_mm_store_pd(ar, v_result);
result += ar[0] + ar[1];
v_float32 v_src = v_min(vx_load(h1 + j), vx_load(h2 + j));
v_result += v_cvt_f64(v_src) + v_cvt_f64_high(v_src);
}
#endif
result += v_reduce_sum(v_result);
#elif CV_SIMD
v_float32 v_result = vx_setzero_f32();
for (; j <= len - v_float32::nlanes; j += v_float32::nlanes)
{
v_float32 v_src = v_min(vx_load(h1 + j), vx_load(h2 + j));
v_result += v_src;
}
result += v_reduce_sum(v_result);
#endif
for( ; j < len; j++ )
result += std::min(h1[j], h2[j]);
}
else if( method == CV_COMP_BHATTACHARYYA )
{
#if CV_SSE2
if (haveSIMD)
#if CV_SIMD_64F
v_float64 v_s1 = vx_setzero_f64();
v_float64 v_s2 = vx_setzero_f64();
v_float64 v_result = vx_setzero_f64();
for ( ; j <= len - v_float32::nlanes; j += v_float32::nlanes)
{
__m128d v_s1 = _mm_setzero_pd(), v_s2 = v_s1, v_result = v_s1;
for ( ; j <= len - 4; j += 4)
{
__m128 v_a = _mm_loadu_ps(h1 + j);
__m128 v_b = _mm_loadu_ps(h2 + j);
v_float32 v_a = vx_load(h1 + j);
v_float32 v_b = vx_load(h2 + j);
__m128d v_ad = _mm_cvtps_pd(v_a);
__m128d v_bd = _mm_cvtps_pd(v_b);
v_s1 = _mm_add_pd(v_s1, v_ad);
v_s2 = _mm_add_pd(v_s2, v_bd);
v_result = _mm_add_pd(v_result, _mm_sqrt_pd(_mm_mul_pd(v_ad, v_bd)));
v_float64 v_ad = v_cvt_f64(v_a);
v_float64 v_bd = v_cvt_f64(v_b);
v_s1 += v_ad;
v_s2 += v_bd;
v_result += v_sqrt(v_ad * v_bd);
v_ad = _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_a), 8)));
v_bd = _mm_cvtps_pd(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(v_b), 8)));
v_s1 = _mm_add_pd(v_s1, v_ad);
v_s2 = _mm_add_pd(v_s2, v_bd);
v_result = _mm_add_pd(v_result, _mm_sqrt_pd(_mm_mul_pd(v_ad, v_bd)));
}
double CV_DECL_ALIGNED(16) ar[6];
_mm_store_pd(ar, v_s1);
_mm_store_pd(ar + 2, v_s2);
_mm_store_pd(ar + 4, v_result);
s1 += ar[0] + ar[1];
s2 += ar[2] + ar[3];
result += ar[4] + ar[5];
v_ad = v_cvt_f64_high(v_a);
v_bd = v_cvt_f64_high(v_b);
v_s1 += v_ad;
v_s2 += v_bd;
v_result += v_sqrt(v_ad * v_bd);
}
#endif
s1 += v_reduce_sum(v_s1);
s2 += v_reduce_sum(v_s2);
result += v_reduce_sum(v_result);
#elif CV_SIMD && 0 //Disable vectorization for CV_COMP_BHATTACHARYYA if f64 is unsupported due to low precision
v_float32 v_s1 = vx_setzero_f32();
v_float32 v_s2 = vx_setzero_f32();
v_float32 v_result = vx_setzero_f32();
for (; j <= len - v_float32::nlanes; j += v_float32::nlanes)
{
v_float32 v_a = vx_load(h1 + j);
v_float32 v_b = vx_load(h2 + j);
v_s1 += v_a;
v_s2 += v_b;
v_result += v_sqrt(v_a * v_b);
}
s1 += v_reduce_sum(v_s1);
s2 += v_reduce_sum(v_s2);
result += v_reduce_sum(v_result);
#endif
for( ; j < len; j++ )
{
double a = h1[j];
+6 -6
View File
@@ -282,10 +282,10 @@ medianBlur_8u_O1( const Mat& _src, Mat& _dst, int ksize )
for ( ; luc[c][k] < j+r+1; ++luc[c][k] )
{
#if CV_SIMD256
v_fine += v256_load(px + 16 * MIN(luc[c][k], n - 1)) - v256_load(px + 16 * MAX(luc[c][k] - 2 * r - 1, 0));
v_fine = v_fine + v256_load(px + 16 * MIN(luc[c][k], n - 1)) - v256_load(px + 16 * MAX(luc[c][k] - 2 * r - 1, 0));
#elif CV_SIMD128
v_finel += v_load(px + 16 * MIN(luc[c][k], n - 1) ) - v_load(px + 16 * MAX(luc[c][k] - 2 * r - 1, 0));
v_fineh += v_load(px + 16 * MIN(luc[c][k], n - 1) + 8) - v_load(px + 16 * MAX(luc[c][k] - 2 * r - 1, 0) + 8);
v_finel = v_finel + v_load(px + 16 * MIN(luc[c][k], n - 1) ) - v_load(px + 16 * MAX(luc[c][k] - 2 * r - 1, 0));
v_fineh = v_fineh + v_load(px + 16 * MIN(luc[c][k], n - 1) + 8) - v_load(px + 16 * MAX(luc[c][k] - 2 * r - 1, 0) + 8);
#else
for (int ind = 0; ind < 16; ++ind)
H[c].fine[k][ind] += px[16 * MIN(luc[c][k], n - 1) + ind] - px[16 * MAX(luc[c][k] - 2 * r - 1, 0) + ind];
@@ -321,10 +321,10 @@ medianBlur_8u_O1( const Mat& _src, Mat& _dst, int ksize )
CV_Assert( b < 16 );
}
}
#if CV_SIMD
vx_cleanup();
#endif
}
#if CV_SIMD
vx_cleanup();
#endif
}
#undef HOP
+7 -12
View File
@@ -76,10 +76,6 @@
enum
{
gray_shift = 15,
yuv_shift = 14,
R2Y = 4899,
G2Y = 9617,
B2Y = 1868,
RY15 = 9798, // == R2YF*32768 + 0.5
GY15 = 19235, // == G2YF*32768 + 0.5
BY15 = 3735 // == B2YF*32768 + 0.5
@@ -133,10 +129,8 @@ __kernel void RGB2Gray(__global const uchar * srcptr, int src_step, int src_offs
DATA_TYPE_3 src_pix = vload3(0, src);
#ifdef DEPTH_5
dst[0] = fma(src_pix.B_COMP, B2YF, fma(src_pix.G_COMP, G2YF, src_pix.R_COMP * R2YF));
#elif defined(DEPTH_0)
dst[0] = (DATA_TYPE)CV_DESCALE(mad24(src_pix.B_COMP, BY15, mad24(src_pix.G_COMP, GY15, mul24(src_pix.R_COMP, RY15))), gray_shift);
#else
dst[0] = (DATA_TYPE)CV_DESCALE(mad24(src_pix.B_COMP, B2Y, mad24(src_pix.G_COMP, G2Y, mul24(src_pix.R_COMP, R2Y))), yuv_shift);
dst[0] = (DATA_TYPE)CV_DESCALE(mad24(src_pix.B_COMP, BY15, mad24(src_pix.G_COMP, GY15, mul24(src_pix.R_COMP, RY15))), gray_shift);
#endif
++y;
src_index += src_step;
@@ -340,9 +334,9 @@ __kernel void BGR5x52Gray(__global const uchar* src, int src_step, int src_offse
int t = *((__global const ushort*)(src + src_index));
#if greenbits == 6
dst[dst_index] = (uchar)CV_DESCALE(mad24((t << 3) & 0xf8, B2Y, mad24((t >> 3) & 0xfc, G2Y, ((t >> 8) & 0xf8) * R2Y)), yuv_shift);
dst[dst_index] = (uchar)CV_DESCALE(mad24((t << 3) & 0xf8, BY15, mad24((t >> 3) & 0xfc, GY15, ((t >> 8) & 0xf8) * RY15)), gray_shift);
#else
dst[dst_index] = (uchar)CV_DESCALE(mad24((t << 3) & 0xf8, B2Y, mad24((t >> 2) & 0xf8, G2Y, ((t >> 7) & 0xf8) * R2Y)), yuv_shift);
dst[dst_index] = (uchar)CV_DESCALE(mad24((t << 3) & 0xf8, BY15, mad24((t >> 2) & 0xf8, GY15, ((t >> 7) & 0xf8) * RY15)), gray_shift);
#endif
++y;
dst_index += dst_step;
@@ -445,9 +439,10 @@ __kernel void mRGBA2RGBA(__global const uchar* src, int src_step, int src_offset
*(__global uchar4 *)(dst + dst_index) = (uchar4)(0, 0, 0, 0);
else
*(__global uchar4 *)(dst + dst_index) =
(uchar4)(mad24(src_pix.x, MAX_NUM, v3_half) / v3,
mad24(src_pix.y, MAX_NUM, v3_half) / v3,
mad24(src_pix.z, MAX_NUM, v3_half) / v3, v3);
(uchar4)(SAT_CAST(mad24(src_pix.x, MAX_NUM, v3_half) / v3),
SAT_CAST(mad24(src_pix.y, MAX_NUM, v3_half) / v3),
SAT_CAST(mad24(src_pix.z, MAX_NUM, v3_half) / v3),
SAT_CAST(v3));
++y;
dst_index += dst_step;
+11
View File
@@ -2200,4 +2200,15 @@ TEST(Imgproc_Filter2D, dftFilter2d_regression_10683)
EXPECT_LE(cvtest::norm(dst, expected, NORM_INF), 2);
}
TEST(Imgproc_MedianBlur, hires_regression_13409)
{
Mat src(2048, 2048, CV_8UC1), dst_hires, dst_ref;
randu(src, 0, 256);
medianBlur(src, dst_hires, 9);
medianBlur(src(Rect(512, 512, 1024, 1024)), dst_ref, 9);
ASSERT_EQ(0.0, cvtest::norm(dst_hires(Rect(516, 516, 1016, 1016)), dst_ref(Rect(4, 4, 1016, 1016)), NORM_INF));
}
}} // namespace
+3 -3
View File
@@ -3,8 +3,8 @@ if(OPENCV_INITIAL_PASS)
add_subdirectory(generator)
endif()
if(APPLE_FRAMEWORK OR WINRT OR NOT PYTHON_DEFAULT_AVAILABLE OR NOT ANT_EXECUTABLE
OR NOT (JNI_FOUND OR (ANDROID AND ANDROID_NATIVE_API_LEVEL GREATER 7))
if(APPLE_FRAMEWORK OR WINRT OR NOT PYTHON_DEFAULT_AVAILABLE OR NOT (ANT_EXECUTABLE OR ANDROID_PROJECTS_BUILD_TYPE STREQUAL "GRADLE")
OR NOT (JNI_FOUND OR (ANDROID AND (NOT DEFINED ANDROID_NATIVE_API_LEVEL OR ANDROID_NATIVE_API_LEVEL GREATER 7)))
OR BUILD_opencv_world
)
ocv_module_disable(java)
@@ -55,7 +55,7 @@ macro(copy_common_tests _src_location _dst_location _deps)
endmacro()
add_subdirectory(jni) # generates ${the_module} target (${the_module}_jni doesn't work properly with Android samples)
add_subdirectory(jni) # generates ${the_module} target (${the_module}_jni doesn't work properly with Android non-gradle samples)
if(ANDROID)
add_subdirectory(android_sdk) # generates ${the_module}_android target
else()
+62 -6
View File
@@ -1,12 +1,11 @@
if(NOT ANDROID_EXECUTABLE)
message(WARNING "'android' tool required to build Android SDK")
return()
endif()
ocv_assert(ANDROID_TOOLS_Pkg_Revision GREATER 13)
project(${the_module}_android)
set(OPENCV_JAVA_DIR "${OpenCV_BINARY_DIR}/android_sdk" CACHE INTERNAL "")
if(ANDROID_EXECUTABLE)
set(OPENCV_JAVA_DIR "${OpenCV_BINARY_DIR}/android_sdk" CACHE INTERNAL "")
else() # gradle
set(OPENCV_JAVA_DIR "${ANDROID_BUILD_BASE_DIR}/opencv" CACHE INTERNAL "")
endif()
set(OPENCV_ANDROID_LIB_DIR "${OPENCV_JAVA_DIR}" CACHE INTERNAL "") # for OpenCV samples
file(REMOVE_RECURSE "${OPENCV_JAVA_DIR}")
@@ -15,6 +14,11 @@ set(java_src_dir "${OPENCV_JAVA_DIR}/src")
file(MAKE_DIRECTORY "${java_src_dir}")
ocv_copyfiles_append_dir(JAVA_SRC_COPY "${OPENCV_JAVA_BINDINGS_DIR}/gen/java" "${java_src_dir}")
if(ANDROID_EXECUTABLE)
ocv_assert(ANDROID_TOOLS_Pkg_Revision GREATER 13)
ocv_copyfiles_append_dir(JAVA_SRC_COPY "${OPENCV_JAVA_BINDINGS_DIR}/gen/android/java" "${java_src_dir}")
# calc default SDK Target
@@ -90,5 +94,57 @@ FILE(MAKE_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${JAVA_INSTALL_ROOT
FILE(MAKE_DIRECTORY \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${JAVA_INSTALL_ROOT}/res\")
" COMPONENT java)
ocv_update(ANDROID_COMPILE_SDK_VERSION "27")
ocv_update(ANDROID_MIN_SDK_VERSION "14")
ocv_update(ANDROID_TARGET_SDK_VERSION "21")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build.gradle.in" "${CMAKE_CURRENT_BINARY_DIR}/build.gradle" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/build.gradle" DESTINATION ${JAVA_INSTALL_ROOT}/.. COMPONENT java)
else() # gradle build
#
# Android Gradle-based project
#
#TODO: INSTALL ONLY
ocv_copyfiles_append_dir(JAVA_SRC_COPY "${OPENCV_JAVA_BINDINGS_DIR}/gen/android/java" "${java_src_dir}")
ocv_copyfiles_append_dir(JAVA_SRC_COPY "${OPENCV_JAVA_BINDINGS_DIR}/gen/android-21/java" "${java_src_dir}")
# copy boilerplate
set(__base_dir "${CMAKE_CURRENT_SOURCE_DIR}/android_gradle_lib/")
file(GLOB_RECURSE seed_project_files_rel RELATIVE "${__base_dir}/" "${__base_dir}/*")
list(REMOVE_ITEM seed_project_files_rel "${ANDROID_MANIFEST_FILE}")
foreach(file ${seed_project_files_rel})
configure_file("${__base_dir}/${file}" "${OPENCV_JAVA_DIR}/${file}" @ONLY)
list(APPEND depends "${__base_dir}/${file}")
get_filename_component(install_subdir "${file}" PATH)
install(FILES "${OPENCV_JAVA_DIR}/${file}" DESTINATION "${JAVA_INSTALL_ROOT}/${install_subdir}" COMPONENT java)
endforeach()
list(APPEND depends gen_opencv_java_source "${OPENCV_DEPHELPER}/gen_opencv_java_source")
ocv_copyfiles_add_target(${the_module}_android_source_copy JAVA_SRC_COPY "Copy Java(Andoid SDK) source files" ${depends})
file(REMOVE "${OPENCV_DEPHELPER}/${the_module}_android_source_copy") # force rebuild after CMake run
set(depends ${the_module}_android_source_copy "${OPENCV_DEPHELPER}/${the_module}_android_source_copy")
# build jar
set(AAR_FILE "${OPENCV_JAVA_DIR}/build/outputs/aar/opencv-release.aar")
ocv_update(OPENCV_GRADLE_VERBOSE_OPTIONS "-i")
add_custom_command(
OUTPUT "${AAR_FILE}" "${OPENCV_DEPHELPER}/${the_module}_android"
COMMAND ./gradlew ${OPENCV_GRADLE_VERBOSE_OPTIONS} "opencv:assemble"
COMMAND ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/${the_module}_android"
WORKING_DIRECTORY "${ANDROID_BUILD_BASE_DIR}"
DEPENDS ${depends} ${the_module}
COMMENT "Building OpenCV Android library project"
)
file(REMOVE "${OPENCV_DEPHELPER}/${the_module}_android") # force rebuild after CMake run
add_custom_target(${the_module}_android ALL DEPENDS "${OPENCV_DEPHELPER}/${the_module}_android" SOURCES "${__base_dir}/${ANDROID_MANIFEST_FILE}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build.gradle.in" "${ANDROID_TMP_INSTALL_BASE_DIR}/opencv/build.gradle" @ONLY)
install(FILES "${ANDROID_TMP_INSTALL_BASE_DIR}/opencv/build.gradle" DESTINATION ${JAVA_INSTALL_ROOT}/.. COMPONENT java)
install(DIRECTORY "${java_src_dir}" DESTINATION "${JAVA_INSTALL_ROOT}" COMPONENT java)
endif() # gradle build
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.opencv"
android:versionCode="@OPENCV_VERSION_MAJOR@@OPENCV_VERSION_MINOR@@OPENCV_VERSION_PATCH@0"
android:versionName="@OPENCV_VERSION@">
</manifest>
@@ -0,0 +1,35 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
//buildToolsVersion "x.y.z" // not needed since com.android.tools.build:gradle:3.0.0
defaultConfig {
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
}
sourceSets {
main {
jniLibs.srcDirs = ['../../jni']
java.srcDirs = ['src'] // TODO Use original files instead of copied into build directory
aidl.srcDirs = ['src']
res.srcDirs = ['@OpenCV_SOURCE_DIR@/modules/java/android_sdk/android_gradle_lib/res']
manifest.srcFile 'AndroidManifest.xml'
}
}
}
dependencies {
}
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name = "CameraBridgeViewBase" >
<attr name="show_fps" format="boolean"/>
<attr name="camera_id" format="integer" >
<enum name="any" value="-1" />
<enum name="back" value="99" />
<enum name="front" value="98" />
</attr>
</declare-styleable>
</resources>
+5 -5
View File
@@ -81,9 +81,9 @@
// splits {
// abi {
// enable true
// universalApk false
// reset()
// include 'armeabi-v7a' // , 'x86', 'x86_64', 'arm64-v8a'
// universalApk false
// }
// }
//
@@ -93,12 +93,12 @@ apply plugin: 'com.android.library'
println "OpenCV: " + project.buildscript.sourceFile
android {
compileSdkVersion 27
//buildToolsVersion "27.0.3" // not needed since com.android.tools.build:gradle:3.0.0
compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@
//buildToolsVersion "x.y.z" // not needed since com.android.tools.build:gradle:3.0.0
defaultConfig {
minSdkVersion 14
targetSdkVersion 21
minSdkVersion @ANDROID_MIN_SDK_VERSION@
targetSdkVersion @ANDROID_TARGET_SDK_VERSION@
}
buildTypes {
+5 -2
View File
@@ -427,9 +427,12 @@ class JavaWrapperGenerator(object):
constinfo = ConstInfo(decl, namespaces=self.namespaces, enumType=enumType)
if constinfo.isIgnored():
logging.info('ignored: %s', constinfo)
elif not self.isWrapped(constinfo.classname):
logging.info('class not found: %s', constinfo)
else:
if not self.isWrapped(constinfo.classname):
logging.info('class not found: %s', constinfo)
constinfo.name = constinfo.classname + '_' + constinfo.name
constinfo.classname = ''
ci = self.getClass(constinfo.classname)
duplicate = ci.getConst(constinfo.name)
if duplicate:
+7
View File
@@ -18,6 +18,13 @@ set(depends gen_opencv_java_source "${OPENCV_DEPHELPER}/gen_opencv_java_source")
ocv_copyfiles_add_target(${the_module}_jar_source_copy JAVA_SRC_COPY "Copy Java(JAR) source files" ${depends})
set(depends ${the_module}_jar_source_copy "${OPENCV_DEPHELPER}/${the_module}_jar_source_copy")
if(OPENCV_JAVA_SOURCE_VERSION)
set(OPENCV_ANT_JAVAC_EXTRA_ATTRS "${OPENCV_ANT_JAVAC_EXTRA_ATTRS} source=\"${OPENCV_JAVA_SOURCE_VERSION}\"")
endif()
if(OPENCV_JAVA_TARGET_VERSION)
set(OPENCV_ANT_JAVAC_EXTRA_ATTRS "${OPENCV_ANT_JAVAC_EXTRA_ATTRS} target=\"${OPENCV_JAVA_TARGET_VERSION}\"")
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/build.xml.in" "${OPENCV_JAVA_DIR}/build.xml" @ONLY)
list(APPEND depends "${OPENCV_JAVA_DIR}/build.xml")
+1 -1
View File
@@ -11,7 +11,7 @@
<!-- This is to make a jar with a source attachment, for e.g. easy -->
<!-- navigation in Eclipse. See this question: -->
<!-- http://stackoverflow.com/questions/3584968/ant-how-to-compile-jar-that-includes-source-attachment -->
<javac sourcepath="" srcdir="java" destdir="build/classes" debug="on" includeantruntime="false" >
<javac sourcepath="" srcdir="java" destdir="build/classes" debug="on" includeantruntime="false" @OPENCV_ANT_JAVAC_EXTRA_ATTRS@ >
<include name="**/*.java"/>
<compilerarg line="-encoding utf-8"/>
</javac>
+7 -1
View File
@@ -13,6 +13,12 @@ foreach(m ${OPENCV_MODULES_BUILD})
endif()
endforeach()
if(ANDROID)
ocv_update(JNI_OUTPUT_PATH "${OpenCV_BINARY_DIR}/jni/${ANDROID_NDK_ABI_NAME}")
else()
ocv_update(JNI_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH}")
endif()
set(__type MODULE)
if(BUILD_FAT_JAVA_LIB)
set(__type SHARED) # samples link to libopencv_java
@@ -60,7 +66,7 @@ endif()
set_target_properties(${the_module} PROPERTIES
OUTPUT_NAME "${the_module}${OPENCV_JAVA_LIB_NAME_SUFFIX}"
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
LIBRARY_OUTPUT_DIRECTORY ${JNI_OUTPUT_PATH}
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
DEFINE_SYMBOL CVAPI_EXPORTS
)
+7
View File
@@ -782,6 +782,9 @@ bool QRCodeDetector::detect(InputArray in, OutputArray points) const
Mat inarr = in.getMat();
CV_Assert(!inarr.empty());
CV_Assert(inarr.depth() == CV_8U);
if (inarr.cols <= 20 || inarr.rows <= 20)
return false; // image data is not enough for providing reliable results
int incn = inarr.channels();
if( incn == 3 || incn == 4 )
{
@@ -1054,6 +1057,8 @@ std::string QRCodeDetector::decode(InputArray in, InputArray points,
Mat inarr = in.getMat();
CV_Assert(!inarr.empty());
CV_Assert(inarr.depth() == CV_8U);
if (inarr.cols <= 20 || inarr.rows <= 20)
return cv::String(); // image data is not enough for providing reliable results
int incn = inarr.channels();
if( incn == 3 || incn == 4 )
@@ -1092,6 +1097,8 @@ std::string QRCodeDetector::detectAndDecode(InputArray in,
Mat inarr = in.getMat();
CV_Assert(!inarr.empty());
CV_Assert(inarr.depth() == CV_8U);
if (inarr.cols <= 20 || inarr.rows <= 20)
return cv::String(); // image data is not enough for providing reliable results
int incn = inarr.channels();
if( incn == 3 || incn == 4 )
+1
View File
@@ -20,6 +20,7 @@ add_subdirectory(bindings)
if(NOT OPENCV_SKIP_PYTHON_LOADER)
include("./python_loader.cmake")
message(STATUS "OpenCV Python: during development append to PYTHONPATH: ${CMAKE_BINARY_DIR}/python_loader")
endif()
if(__disable_python2)
+15
View File
@@ -120,6 +120,21 @@ if(NOT OPENCV_SKIP_PYTHON_LOADER)
set(__python_loader_subdir "cv2/")
endif()
if(NOT " ${PYTHON}" STREQUAL " PYTHON"
AND NOT DEFINED OPENCV_PYTHON_INSTALL_PATH
)
if(DEFINED OPENCV_${PYTHON}_INSTALL_PATH)
set(OPENCV_PYTHON_INSTALL_PATH "${OPENCV_${PYTHON}_INSTALL_PATH}")
elseif(NOT OPENCV_SKIP_PYTHON_LOADER)
set(OPENCV_PYTHON_INSTALL_PATH "${${PYTHON}_PACKAGES_PATH}")
endif()
endif()
if(NOT OPENCV_SKIP_PYTHON_LOADER AND DEFINED OPENCV_PYTHON_INSTALL_PATH)
include("${CMAKE_CURRENT_LIST_DIR}/python_loader.cmake")
set(OPENCV_PYTHON_INSTALL_PATH_SETUPVARS "${OPENCV_PYTHON_INSTALL_PATH}" CACHE INTERNAL "")
endif()
if(NOT " ${PYTHON}" STREQUAL " PYTHON" AND DEFINED OPENCV_${PYTHON}_INSTALL_PATH)
set(__python_binary_install_path "${OPENCV_${PYTHON}_INSTALL_PATH}")
elseif(OPENCV_SKIP_PYTHON_LOADER AND DEFINED ${PYTHON}_PACKAGES_PATH)
+1 -1
View File
@@ -9,7 +9,7 @@ def main():
os.chdir(SCRIPT_DIR)
package_name = 'opencv'
package_version = os.environ.get('OPENCV_VERSION', '4.0.0') # TODO
package_version = os.environ.get('OPENCV_VERSION', '4.0.1') # TODO
long_description = 'Open Source Computer Vision Library Python bindings' # TODO
+27 -16
View File
@@ -2,20 +2,24 @@ ocv_assert(NOT OPENCV_SKIP_PYTHON_LOADER)
set(PYTHON_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}")
ocv_assert(DEFINED OPENCV_PYTHON_INSTALL_PATH)
if(OpenCV_FOUND)
set(__loader_path "${OpenCV_BINARY_DIR}/python_loader")
message(STATUS "OpenCV Python: during development append to PYTHONPATH: ${__loader_path}")
else()
set(__loader_path "${CMAKE_BINARY_DIR}/python_loader")
endif()
set(__python_loader_install_tmp_path "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/python_loader/")
if(IS_ABSOLUTE "${OPENCV_PYTHON_INSTALL_PATH}")
set(OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/")
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "'${CMAKE_INSTALL_PREFIX}'")
if(DEFINED OPENCV_PYTHON_INSTALL_PATH)
if(IS_ABSOLUTE "${OPENCV_PYTHON_INSTALL_PATH}")
set(OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/")
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "'${CMAKE_INSTALL_PREFIX}'")
else()
file(RELATIVE_PATH OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/${OPENCV_PYTHON_INSTALL_PATH}/cv2" ${CMAKE_INSTALL_PREFIX})
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "os.path.join(LOADER_DIR, '${OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE}')")
endif()
else()
file(RELATIVE_PATH OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/${OPENCV_PYTHON_INSTALL_PATH}/cv2" ${CMAKE_INSTALL_PREFIX})
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "os.path.join(LOADER_DIR, '${OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE}')")
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "os.path.join(LOADER_DIR, 'not_installed')")
endif()
set(PYTHON_LOADER_FILES
@@ -25,7 +29,13 @@ set(PYTHON_LOADER_FILES
foreach(fname ${PYTHON_LOADER_FILES})
get_filename_component(__dir "${fname}" DIRECTORY)
file(COPY "${PYTHON_SOURCE_DIR}/package/${fname}" DESTINATION "${__loader_path}/${__dir}")
install(FILES "${PYTHON_SOURCE_DIR}/package/${fname}" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/${__dir}" COMPONENT python)
if(fname STREQUAL "setup.py")
if(OPENCV_PYTHON_SETUP_PY_INSTALL_PATH)
install(FILES "${PYTHON_SOURCE_DIR}/package/${fname}" DESTINATION "${OPENCV_PYTHON_SETUP_PY_INSTALL_PATH}" COMPONENT python)
endif()
elseif(DEFINED OPENCV_PYTHON_INSTALL_PATH)
install(FILES "${PYTHON_SOURCE_DIR}/package/${fname}" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/${__dir}" COMPONENT python)
endif()
endforeach()
if(NOT OpenCV_FOUND) # Ignore "standalone" builds of Python bindings
@@ -41,14 +51,15 @@ if(NOT OpenCV_FOUND) # Ignore "standalone" builds of Python bindings
string(REPLACE ";" ",\n " CMAKE_PYTHON_BINARIES_PATH "${CMAKE_PYTHON_BINARIES_PATH}")
configure_file("${PYTHON_SOURCE_DIR}/package/template/config.py.in" "${__loader_path}/cv2/config.py" @ONLY)
if(WIN32)
list(APPEND CMAKE_PYTHON_BINARIES_INSTALL_PATH "os.path.join(${CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE}, '${OPENCV_BIN_INSTALL_PATH}')")
else()
list(APPEND CMAKE_PYTHON_BINARIES_INSTALL_PATH "os.path.join(${CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE}, '${OPENCV_LIB_INSTALL_PATH}')")
# install
if(DEFINED OPENCV_PYTHON_INSTALL_PATH)
if(WIN32)
list(APPEND CMAKE_PYTHON_BINARIES_INSTALL_PATH "os.path.join(${CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE}, '${OPENCV_BIN_INSTALL_PATH}')")
else()
list(APPEND CMAKE_PYTHON_BINARIES_INSTALL_PATH "os.path.join(${CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE}, '${OPENCV_LIB_INSTALL_PATH}')")
endif()
string(REPLACE ";" ",\n " CMAKE_PYTHON_BINARIES_PATH "${CMAKE_PYTHON_BINARIES_INSTALL_PATH}")
configure_file("${PYTHON_SOURCE_DIR}/package/template/config.py.in" "${__python_loader_install_tmp_path}/cv2/config.py" @ONLY)
install(FILES "${__python_loader_install_tmp_path}/cv2/config.py" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/cv2/" COMPONENT python)
endif()
string(REPLACE ";" ",\n " CMAKE_PYTHON_BINARIES_PATH "${CMAKE_PYTHON_BINARIES_INSTALL_PATH}")
configure_file("${PYTHON_SOURCE_DIR}/package/template/config.py.in" "${__python_loader_install_tmp_path}/cv2/config.py" @ONLY)
install(FILES "${__python_loader_install_tmp_path}/cv2/config.py" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/cv2/" COMPONENT python)
message(STATUS "OpenCV Python: during development append to PYTHONPATH: ${__loader_path}")
endif()
+14
View File
@@ -197,6 +197,7 @@ typedef std::vector<size_t> vector_size_t;
typedef std::vector<Point> vector_Point;
typedef std::vector<Point2f> vector_Point2f;
typedef std::vector<Point3f> vector_Point3f;
typedef std::vector<Size> vector_Size;
typedef std::vector<Vec2f> vector_Vec2f;
typedef std::vector<Vec3f> vector_Vec3f;
typedef std::vector<Vec4f> vector_Vec4f;
@@ -1338,6 +1339,19 @@ template<> struct pyopencvVecConverter<Mat>
}
};
template<> struct pyopencvVecConverter<UMat>
{
static bool to(PyObject* obj, std::vector<UMat>& value, const ArgInfo info)
{
return pyopencv_to_generic_vec(obj, value, info);
}
static PyObject* from(const std::vector<UMat>& value)
{
return pyopencv_from_generic_vec(value);
}
};
template<> struct pyopencvVecConverter<KeyPoint>
{
static bool to(PyObject* obj, std::vector<KeyPoint>& value, const ArgInfo info)
+11 -3
View File
@@ -634,6 +634,8 @@ class CppHeaderParser(object):
block_type, block_name = b[self.BLOCK_TYPE], b[self.BLOCK_NAME]
if block_type in ["file", "enum"]:
continue
if block_type in ["enum struct", "enum class"] and block_name == name:
continue
if block_type not in ["struct", "class", "namespace", "enum struct", "enum class"]:
print("Error at %d: there are non-valid entries in the current block stack %s" % (self.lineno, self.block_stack))
sys.exit(-1)
@@ -831,7 +833,7 @@ class CppHeaderParser(object):
l = l[pos+2:]
state = SCAN
if l.startswith('CV__'): # just ignore this lines
if l.startswith('CV__') or l.startswith('__CV_'): # just ignore these lines
#print('IGNORE: ' + l)
state = SCAN
continue
@@ -845,11 +847,17 @@ class CppHeaderParser(object):
if not token:
block_head += " " + l
break
block_head = block_head.strip()
if len(block_head) > 0 and block_head[-1] == ')' and block_head.startswith('CV_ENUM_FLAGS('):
l = ''
token = ';'
else:
break
if token == "//":
block_head += " " + l[:pos]
break
l = ''
continue
if token == "/*":
block_head += " " + l[:pos]
+7 -1
View File
@@ -3,7 +3,13 @@ if(NOT DEFINED OpenCV_BINARY_DIR)
endif()
include("${OpenCV_BINARY_DIR}/opencv_python_config.cmake")
if(NOT DEFINED OpenCV_SOURCE_DIR)
message(FATAL_ERROR "Missing define of OpenCV_SOURCE_DIR")
message(FATAL_ERROR "Missing OpenCV_SOURCE_DIR")
endif()
if(NOT OPENCV_PYTHON_INSTALL_PATH)
if(NOT DEFINED OPENCV_PYTHON_STANDALONE_INSTALL_PATH)
message(FATAL_ERROR "Missing OPENCV_PYTHON_STANDALONE_INSTALL_PATH / OPENCV_PYTHON_INSTALL_PATH")
endif()
set(OPENCV_PYTHON_INSTALL_PATH "${OPENCV_PYTHON_STANDALONE_INSTALL_PATH}")
endif()
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVUtils.cmake")
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class Features2D_Tests(NewOpenCVTests):
def test_issue_13406(self):
self.assertEqual(True, hasattr(cv, 'drawKeypoints'))
self.assertEqual(True, hasattr(cv, 'DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS'))
self.assertEqual(True, hasattr(cv, 'DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS'))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
+63
View File
@@ -19,5 +19,68 @@ class stitching_test(NewOpenCVTests):
self.assertAlmostEqual(pano.shape[0], 685, delta=100, msg="rows: %r" % list(pano.shape))
self.assertAlmostEqual(pano.shape[1], 1025, delta=100, msg="cols: %r" % list(pano.shape))
class stitching_detail_test(NewOpenCVTests):
def test_simple(self):
img = self.get_sample('stitching/a1.png')
finder= cv.ORB.create()
imgFea = cv.detail.computeImageFeatures2(finder,img)
self.assertIsNotNone(imgFea)
matcher = cv.detail_BestOf2NearestMatcher(False, 0.3)
self.assertIsNotNone(matcher)
matcher = cv.detail_AffineBestOf2NearestMatcher(False, False, 0.3)
self.assertIsNotNone(matcher)
matcher = cv.detail_BestOf2NearestRangeMatcher(2, False, 0.3)
self.assertIsNotNone(matcher)
estimator = cv.detail_AffineBasedEstimator()
self.assertIsNotNone(estimator)
estimator = cv.detail_HomographyBasedEstimator()
self.assertIsNotNone(estimator)
adjuster = cv.detail_BundleAdjusterReproj()
self.assertIsNotNone(adjuster)
adjuster = cv.detail_BundleAdjusterRay()
self.assertIsNotNone(adjuster)
adjuster = cv.detail_BundleAdjusterAffinePartial()
self.assertIsNotNone(adjuster)
adjuster = cv.detail_NoBundleAdjuster()
self.assertIsNotNone(adjuster)
compensator=cv.detail.ExposureCompensator_createDefault(cv.detail.ExposureCompensator_NO)
self.assertIsNotNone(compensator)
compensator=cv.detail.ExposureCompensator_createDefault(cv.detail.ExposureCompensator_GAIN)
self.assertIsNotNone(compensator)
compensator=cv.detail.ExposureCompensator_createDefault(cv.detail.ExposureCompensator_GAIN_BLOCKS)
self.assertIsNotNone(compensator)
seam_finder = cv.detail.SeamFinder_createDefault(cv.detail.SeamFinder_NO)
self.assertIsNotNone(seam_finder)
seam_finder = cv.detail.SeamFinder_createDefault(cv.detail.SeamFinder_NO)
self.assertIsNotNone(seam_finder)
seam_finder = cv.detail.SeamFinder_createDefault(cv.detail.SeamFinder_VORONOI_SEAM)
self.assertIsNotNone(seam_finder)
seam_finder = cv.detail_GraphCutSeamFinder("COST_COLOR")
self.assertIsNotNone(seam_finder)
seam_finder = cv.detail_GraphCutSeamFinder("COST_COLOR_GRAD")
self.assertIsNotNone(seam_finder)
seam_finder = cv.detail_DpSeamFinder("COLOR")
self.assertIsNotNone(seam_finder)
seam_finder = cv.detail_DpSeamFinder("COLOR_GRAD")
self.assertIsNotNone(seam_finder)
blender = cv.detail.Blender_createDefault(cv.detail.Blender_NO)
self.assertIsNotNone(blender)
blender = cv.detail.Blender_createDefault(cv.detail.Blender_FEATHER)
self.assertIsNotNone(blender)
blender = cv.detail.Blender_createDefault(cv.detail.Blender_MULTI_BAND)
self.assertIsNotNone(blender)
timelapser = cv.detail.Timelapser_createDefault(cv.detail.Timelapser_AS_IS);
self.assertIsNotNone(timelapser)
timelapser = cv.detail.Timelapser_createDefault(cv.detail.Timelapser_CROP);
self.assertIsNotNone(timelapser)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
@@ -193,6 +193,9 @@ public:
CV_WRAP bool waveCorrection() const { return do_wave_correct_; }
CV_WRAP void setWaveCorrection(bool flag) { do_wave_correct_ = flag; }
CV_WRAP InterpolationFlags interpolationFlags() const { return interp_flags_; }
CV_WRAP void setInterpolationFlags(InterpolationFlags interp_flags) { interp_flags_ = interp_flags; }
detail::WaveCorrectKind waveCorrectKind() const { return wave_correct_kind_; }
void setWaveCorrectKind(detail::WaveCorrectKind kind) { wave_correct_kind_ = kind; }
@@ -289,6 +292,7 @@ private:
double seam_est_resol_;
double compose_resol_;
double conf_thresh_;
InterpolationFlags interp_flags_;
Ptr<Feature2D> features_finder_;
Ptr<detail::FeaturesMatcher> features_matcher_;
cv::UMat matching_mask_;
@@ -64,7 +64,7 @@ undergoes rotations around its centre only.
See "Construction of Panoramic Image Mosaics with Global and Local Alignment"
by Heung-Yeung Shum and Richard Szeliski.
*/
void CV_EXPORTS focalsFromHomography(const Mat &H, double &f0, double &f1, bool &f0_ok, bool &f1_ok);
void CV_EXPORTS_W focalsFromHomography(const Mat &H, double &f0, double &f1, bool &f0_ok, bool &f1_ok);
/** @brief Estimates focal lengths for each given camera.
@@ -76,7 +76,7 @@ void CV_EXPORTS estimateFocal(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<double> &focals);
bool CV_EXPORTS calibrateRotatingCamera(const std::vector<Mat> &Hs, Mat &K);
bool CV_EXPORTS_W calibrateRotatingCamera(const std::vector<Mat> &Hs,CV_OUT Mat &K);
//! @} stitching_autocalib
@@ -60,35 +60,35 @@ namespace detail {
Simple blender which puts one image over another
*/
class CV_EXPORTS Blender
class CV_EXPORTS_W Blender
{
public:
virtual ~Blender() {}
enum { NO, FEATHER, MULTI_BAND };
static Ptr<Blender> createDefault(int type, bool try_gpu = false);
CV_WRAP static Ptr<Blender> createDefault(int type, bool try_gpu = false);
/** @brief Prepares the blender for blending.
@param corners Source images top-left corners
@param sizes Source image sizes
*/
void prepare(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_WRAP void prepare(const std::vector<Point> &corners, const std::vector<Size> &sizes);
/** @overload */
virtual void prepare(Rect dst_roi);
CV_WRAP virtual void prepare(Rect dst_roi);
/** @brief Processes the image.
@param img Source image
@param mask Source image mask
@param tl Source image top-left corners
*/
virtual void feed(InputArray img, InputArray mask, Point tl);
CV_WRAP virtual void feed(InputArray img, InputArray mask, Point tl);
/** @brief Blends and returns the final pano.
@param dst Final pano
@param dst_mask Final pano mask
*/
virtual void blend(InputOutputArray dst, InputOutputArray dst_mask);
CV_WRAP virtual void blend(CV_IN_OUT InputOutputArray dst,CV_IN_OUT InputOutputArray dst_mask);
protected:
UMat dst_, dst_mask_;
@@ -97,22 +97,22 @@ protected:
/** @brief Simple blender which mixes images at its borders.
*/
class CV_EXPORTS FeatherBlender : public Blender
class CV_EXPORTS_W FeatherBlender : public Blender
{
public:
FeatherBlender(float sharpness = 0.02f);
CV_WRAP FeatherBlender(float sharpness = 0.02f);
float sharpness() const { return sharpness_; }
void setSharpness(float val) { sharpness_ = val; }
CV_WRAP float sharpness() const { return sharpness_; }
CV_WRAP void setSharpness(float val) { sharpness_ = val; }
void prepare(Rect dst_roi) CV_OVERRIDE;
void feed(InputArray img, InputArray mask, Point tl) CV_OVERRIDE;
void blend(InputOutputArray dst, InputOutputArray dst_mask) CV_OVERRIDE;
CV_WRAP void prepare(Rect dst_roi) CV_OVERRIDE;
CV_WRAP void feed(InputArray img, InputArray mask, Point tl) CV_OVERRIDE;
CV_WRAP void blend(InputOutputArray dst, InputOutputArray dst_mask) CV_OVERRIDE;
//! Creates weight maps for fixed set of source images by their masks and top-left corners.
//! Final image can be obtained by simple weighting of the source images.
Rect createWeightMaps(const std::vector<UMat> &masks, const std::vector<Point> &corners,
std::vector<UMat> &weight_maps);
CV_WRAP Rect createWeightMaps(const std::vector<UMat> &masks, const std::vector<Point> &corners,
CV_IN_OUT std::vector<UMat> &weight_maps);
private:
float sharpness_;
@@ -124,17 +124,17 @@ inline FeatherBlender::FeatherBlender(float _sharpness) { setSharpness(_sharpnes
/** @brief Blender which uses multi-band blending algorithm (see @cite BA83).
*/
class CV_EXPORTS MultiBandBlender : public Blender
class CV_EXPORTS_W MultiBandBlender : public Blender
{
public:
MultiBandBlender(int try_gpu = false, int num_bands = 5, int weight_type = CV_32F);
CV_WRAP MultiBandBlender(int try_gpu = false, int num_bands = 5, int weight_type = CV_32F);
int numBands() const { return actual_num_bands_; }
void setNumBands(int val) { actual_num_bands_ = val; }
CV_WRAP int numBands() const { return actual_num_bands_; }
CV_WRAP void setNumBands(int val) { actual_num_bands_ = val; }
void prepare(Rect dst_roi) CV_OVERRIDE;
void feed(InputArray img, InputArray mask, Point tl) CV_OVERRIDE;
void blend(InputOutputArray dst, InputOutputArray dst_mask) CV_OVERRIDE;
CV_WRAP void prepare(Rect dst_roi) CV_OVERRIDE;
CV_WRAP void feed(InputArray img, InputArray mask, Point tl) CV_OVERRIDE;
CV_WRAP void blend(CV_IN_OUT InputOutputArray dst, CV_IN_OUT InputOutputArray dst_mask) CV_OVERRIDE;
private:
int actual_num_bands_, num_bands_;
@@ -165,16 +165,16 @@ private:
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
void CV_EXPORTS normalizeUsingWeightMap(InputArray weight, InputOutputArray src);
void CV_EXPORTS_W normalizeUsingWeightMap(InputArray weight, CV_IN_OUT InputOutputArray src);
void CV_EXPORTS createWeightMap(InputArray mask, float sharpness, InputOutputArray weight);
void CV_EXPORTS_W createWeightMap(InputArray mask, float sharpness, CV_IN_OUT InputOutputArray weight);
void CV_EXPORTS createLaplacePyr(InputArray img, int num_levels, std::vector<UMat>& pyr);
void CV_EXPORTS createLaplacePyrGpu(InputArray img, int num_levels, std::vector<UMat>& pyr);
void CV_EXPORTS_W createLaplacePyr(InputArray img, int num_levels, CV_IN_OUT std::vector<UMat>& pyr);
void CV_EXPORTS_W createLaplacePyrGpu(InputArray img, int num_levels, CV_IN_OUT std::vector<UMat>& pyr);
// Restores source image
void CV_EXPORTS restoreImageFromLaplacePyr(std::vector<UMat>& pyr);
void CV_EXPORTS restoreImageFromLaplacePyrGpu(std::vector<UMat>& pyr);
void CV_EXPORTS_W restoreImageFromLaplacePyr(CV_IN_OUT std::vector<UMat>& pyr);
void CV_EXPORTS_W restoreImageFromLaplacePyrGpu(CV_IN_OUT std::vector<UMat>& pyr);
//! @}
@@ -55,19 +55,19 @@ namespace detail {
@note Translation is assumed to be zero during the whole stitching pipeline. :
*/
struct CV_EXPORTS CameraParams
struct CV_EXPORTS_W_SIMPLE CameraParams
{
CameraParams();
CameraParams(const CameraParams& other);
CameraParams& operator =(const CameraParams& other);
Mat K() const;
CV_WRAP Mat K() const;
double focal; // Focal length
double aspect; // Aspect ratio
double ppx; // Principal point X
double ppy; // Principal point Y
Mat R; // Rotation
Mat t; // Translation
CV_PROP_RW double focal; // Focal length
CV_PROP_RW double aspect; // Aspect ratio
CV_PROP_RW double ppx; // Principal point X
CV_PROP_RW double ppy; // Principal point Y
CV_PROP_RW Mat R; // Rotation
CV_PROP_RW Mat t; // Translation
};
//! @}
@@ -57,54 +57,64 @@ namespace detail {
/** @brief Base class for all exposure compensators.
*/
class CV_EXPORTS ExposureCompensator
class CV_EXPORTS_W ExposureCompensator
{
public:
virtual ~ExposureCompensator() {}
enum { NO, GAIN, GAIN_BLOCKS };
static Ptr<ExposureCompensator> createDefault(int type);
CV_WRAP static Ptr<ExposureCompensator> createDefault(int type);
/**
@param corners Source image top-left corners
@param images Source images
@param masks Image masks to update (second value in pair specifies the value which should be used
to detect where image is)
*/
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<UMat> &masks);
*/
CV_WRAP void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<UMat> &masks);
/** @overload */
virtual void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks) = 0;
const std::vector<std::pair<UMat, uchar> > &masks) = 0;
/** @brief Compensate exposure in the specified image.
@param index Image index
@param corner Image top-left corner
@param image Image to process
@param mask Image mask
*/
virtual void apply(int index, Point corner, InputOutputArray image, InputArray mask) = 0;
*/
CV_WRAP virtual void apply(int index, Point corner, InputOutputArray image, InputArray mask) = 0;
CV_WRAP virtual void getMatGains(CV_OUT std::vector<Mat>& ) {CV_Error(Error::StsInternal, "");};
CV_WRAP virtual void setMatGains(std::vector<Mat>& ) { CV_Error(Error::StsInternal, ""); };
CV_WRAP void setUpdateGain(bool b) { updateGain = b; };
CV_WRAP bool getUpdateGain() { return updateGain; };
protected :
bool updateGain;
};
/** @brief Stub exposure compensator which does nothing.
*/
class CV_EXPORTS NoExposureCompensator : public ExposureCompensator
class CV_EXPORTS_W NoExposureCompensator : public ExposureCompensator
{
public:
void feed(const std::vector<Point> &/*corners*/, const std::vector<UMat> &/*images*/,
const std::vector<std::pair<UMat,uchar> > &/*masks*/) CV_OVERRIDE { }
void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) CV_OVERRIDE { }
CV_WRAP void apply(int /*index*/, Point /*corner*/, InputOutputArray /*image*/, InputArray /*mask*/) CV_OVERRIDE { }
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE { umv.clear(); return; };
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE { umv.clear(); return; };
};
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image
intensities, see @cite BL07 and @cite WJ10 for details.
*/
class CV_EXPORTS GainCompensator : public ExposureCompensator
class CV_EXPORTS_W GainCompensator : public ExposureCompensator
{
public:
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks) CV_OVERRIDE;
void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE ;
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE ;
std::vector<double> gains() const;
private:
@@ -114,14 +124,16 @@ private:
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block
intensities, see @cite UES01 for details.
*/
class CV_EXPORTS BlocksGainCompensator : public ExposureCompensator
class CV_EXPORTS_W BlocksGainCompensator : public ExposureCompensator
{
public:
BlocksGainCompensator(int bl_width = 32, int bl_height = 32)
: bl_width_(bl_width), bl_height_(bl_height) {}
CV_WRAP BlocksGainCompensator(int bl_width = 32, int bl_height = 32)
: bl_width_(bl_width), bl_height_(bl_height) {setUpdateGain(true);}
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks) CV_OVERRIDE;
void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE;
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE;
private:
int bl_width_, bl_height_;
@@ -55,24 +55,38 @@ namespace detail {
//! @{
/** @brief Structure containing image keypoints and descriptors. */
struct CV_EXPORTS ImageFeatures
struct CV_EXPORTS_W_SIMPLE ImageFeatures
{
int img_idx;
Size img_size;
CV_PROP_RW int img_idx;
CV_PROP_RW Size img_size;
std::vector<KeyPoint> keypoints;
UMat descriptors;
CV_PROP_RW UMat descriptors;
CV_WRAP std::vector<KeyPoint> getKeypoints() { return keypoints; };
};
/** @brief
CV_EXPORTS void computeImageFeatures(
@param featuresFinder
@param images
@param features
@param masks
*/
CV_EXPORTS_W void computeImageFeatures(
const Ptr<Feature2D> &featuresFinder,
InputArrayOfArrays images,
std::vector<ImageFeatures> &features,
CV_OUT std::vector<ImageFeatures> &features,
InputArrayOfArrays masks = noArray());
CV_EXPORTS void computeImageFeatures(
/** @brief
@param featuresFinder
@param image
@param features
@param mask
*/
CV_EXPORTS_AS(computeImageFeatures2) void computeImageFeatures(
const Ptr<Feature2D> &featuresFinder,
InputArray image,
ImageFeatures &features,
CV_OUT ImageFeatures &features,
InputArray mask = noArray());
/** @brief Structure containing information about matches between two images.
@@ -82,33 +96,36 @@ homography or affine transformation based on selected matcher.
@sa detail::FeaturesMatcher
*/
struct CV_EXPORTS MatchesInfo
struct CV_EXPORTS_W_SIMPLE MatchesInfo
{
MatchesInfo();
MatchesInfo(const MatchesInfo &other);
MatchesInfo& operator =(const MatchesInfo &other);
int src_img_idx, dst_img_idx; //!< Images indices (optional)
CV_PROP_RW int src_img_idx;
CV_PROP_RW int dst_img_idx; //!< Images indices (optional)
std::vector<DMatch> matches;
std::vector<uchar> inliers_mask; //!< Geometrically consistent matches mask
int num_inliers; //!< Number of geometrically consistent matches
Mat H; //!< Estimated transformation
double confidence; //!< Confidence two images are from the same panorama
CV_PROP_RW int num_inliers; //!< Number of geometrically consistent matches
CV_PROP_RW Mat H; //!< Estimated transformation
CV_PROP_RW double confidence; //!< Confidence two images are from the same panorama
CV_WRAP std::vector<DMatch> getMatches() { return matches; };
CV_WRAP std::vector<uchar> getInliers() { return inliers_mask; };
};
/** @brief Feature matchers base class. */
class CV_EXPORTS FeaturesMatcher
class CV_EXPORTS_W FeaturesMatcher
{
public:
virtual ~FeaturesMatcher() {}
CV_WRAP virtual ~FeaturesMatcher() {}
/** @overload
@param features1 First image features
@param features2 Second image features
@param matches_info Found matches
*/
void operator ()(const ImageFeatures &features1, const ImageFeatures &features2,
MatchesInfo& matches_info) { match(features1, features2, matches_info); }
CV_WRAP_AS(apply) void operator ()(const ImageFeatures &features1, const ImageFeatures &features2,
CV_OUT MatchesInfo& matches_info) { match(features1, features2, matches_info); }
/** @brief Performs images matching.
@@ -120,16 +137,16 @@ public:
@sa detail::MatchesInfo
*/
void operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
CV_WRAP_AS(apply2) void operator ()(const std::vector<ImageFeatures> &features, CV_OUT std::vector<MatchesInfo> &pairwise_matches,
const cv::UMat &mask = cv::UMat());
/** @return True, if it's possible to use the same matcher instance in parallel, false otherwise
*/
bool isThreadSafe() const { return is_thread_safe_; }
CV_WRAP bool isThreadSafe() const { return is_thread_safe_; }
/** @brief Frees unused memory allocated before if there is any.
*/
virtual void collectGarbage() {}
CV_WRAP virtual void collectGarbage() {}
protected:
FeaturesMatcher(bool is_thread_safe = false) : is_thread_safe_(is_thread_safe) {}
@@ -152,7 +169,7 @@ ratio between descriptor distances is greater than the threshold match_conf
@sa detail::FeaturesMatcher
*/
class CV_EXPORTS BestOf2NearestMatcher : public FeaturesMatcher
class CV_EXPORTS_W BestOf2NearestMatcher : public FeaturesMatcher
{
public:
/** @brief Constructs a "best of 2 nearest" matcher.
@@ -164,23 +181,25 @@ public:
@param num_matches_thresh2 Minimum number of matches required for the 2D projective transform
re-estimation on inliers
*/
BestOf2NearestMatcher(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6,
CV_WRAP BestOf2NearestMatcher(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6,
int num_matches_thresh2 = 6);
void collectGarbage() CV_OVERRIDE;
CV_WRAP void collectGarbage() CV_OVERRIDE;
CV_WRAP static Ptr<BestOf2NearestMatcher> create(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6,
int num_matches_thresh2 = 6);
protected:
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info) CV_OVERRIDE;
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info) CV_OVERRIDE;
int num_matches_thresh1_;
int num_matches_thresh2_;
Ptr<FeaturesMatcher> impl_;
};
class CV_EXPORTS BestOf2NearestRangeMatcher : public BestOf2NearestMatcher
class CV_EXPORTS_W BestOf2NearestRangeMatcher : public BestOf2NearestMatcher
{
public:
BestOf2NearestRangeMatcher(int range_width = 5, bool try_use_gpu = false, float match_conf = 0.3f,
CV_WRAP BestOf2NearestRangeMatcher(int range_width = 5, bool try_use_gpu = false, float match_conf = 0.3f,
int num_matches_thresh1 = 6, int num_matches_thresh2 = 6);
void operator ()(const std::vector<ImageFeatures> &features, std::vector<MatchesInfo> &pairwise_matches,
@@ -200,7 +219,7 @@ transformation (affine trasformation estimate will be placed in matches_info).
@sa cv::detail::FeaturesMatcher cv::detail::BestOf2NearestMatcher
*/
class CV_EXPORTS AffineBestOf2NearestMatcher : public BestOf2NearestMatcher
class CV_EXPORTS_W AffineBestOf2NearestMatcher : public BestOf2NearestMatcher
{
public:
/** @brief Constructs a "best of 2 nearest" matcher that expects affine trasformation
@@ -215,7 +234,7 @@ public:
@sa cv::estimateAffine2D cv::estimateAffinePartial2D
*/
AffineBestOf2NearestMatcher(bool full_affine = false, bool try_use_gpu = false,
CV_WRAP AffineBestOf2NearestMatcher(bool full_affine = false, bool try_use_gpu = false,
float match_conf = 0.3f, int num_matches_thresh1 = 6) :
BestOf2NearestMatcher(try_use_gpu, match_conf, num_matches_thresh1, num_matches_thresh1),
full_affine_(full_affine) {}
@@ -62,7 +62,7 @@ cameras.
@note The coordinate system origin is implementation-dependent, but you can always normalize the
rotations in respect to the first camera, for instance. :
*/
class CV_EXPORTS Estimator
class CV_EXPORTS_W Estimator
{
public:
virtual ~Estimator() {}
@@ -74,10 +74,12 @@ public:
@param cameras Estimated camera parameters
@return True in case of success, false otherwise
*/
bool operator ()(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras)
{ return estimate(features, pairwise_matches, cameras); }
CV_WRAP_AS(apply) bool operator ()(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
CV_OUT CV_IN_OUT std::vector<CameraParams> &cameras)
{
return estimate(features, pairwise_matches, cameras);
}
protected:
/** @brief This method must implement camera parameters estimation logic in order to make the wrapper
@@ -90,15 +92,15 @@ protected:
*/
virtual bool estimate(const std::vector<ImageFeatures> &features,
const std::vector<MatchesInfo> &pairwise_matches,
std::vector<CameraParams> &cameras) = 0;
CV_OUT std::vector<CameraParams> &cameras) = 0;
};
/** @brief Homography based rotation estimator.
*/
class CV_EXPORTS HomographyBasedEstimator : public Estimator
class CV_EXPORTS_W HomographyBasedEstimator : public Estimator
{
public:
HomographyBasedEstimator(bool is_focals_estimated = false)
CV_WRAP HomographyBasedEstimator(bool is_focals_estimated = false)
: is_focals_estimated_(is_focals_estimated) {}
private:
@@ -116,7 +118,7 @@ final transformation for each camera.
@sa cv::detail::HomographyBasedEstimator
*/
class CV_EXPORTS AffineBasedEstimator : public Estimator
class CV_EXPORTS_W AffineBasedEstimator : public Estimator
{
private:
virtual bool estimate(const std::vector<ImageFeatures> &features,
@@ -126,21 +128,21 @@ private:
/** @brief Base class for all camera parameters refinement methods.
*/
class CV_EXPORTS BundleAdjusterBase : public Estimator
class CV_EXPORTS_W BundleAdjusterBase : public Estimator
{
public:
const Mat refinementMask() const { return refinement_mask_.clone(); }
void setRefinementMask(const Mat &mask)
CV_WRAP const Mat refinementMask() const { return refinement_mask_.clone(); }
CV_WRAP void setRefinementMask(const Mat &mask)
{
CV_Assert(mask.type() == CV_8U && mask.size() == Size(3, 3));
refinement_mask_ = mask.clone();
}
double confThresh() const { return conf_thresh_; }
void setConfThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
CV_WRAP double confThresh() const { return conf_thresh_; }
CV_WRAP void setConfThresh(double conf_thresh) { conf_thresh_ = conf_thresh; }
TermCriteria termCriteria() { return term_criteria_; }
void setTermCriteria(const TermCriteria& term_criteria) { term_criteria_ = term_criteria; }
CV_WRAP TermCriteria termCriteria() { return term_criteria_; }
CV_WRAP void setTermCriteria(const TermCriteria& term_criteria) { term_criteria_ = term_criteria; }
protected:
/** @brief Construct a bundle adjuster base instance.
@@ -214,10 +216,10 @@ protected:
/** @brief Stub bundle adjuster that does nothing.
*/
class CV_EXPORTS NoBundleAdjuster : public BundleAdjusterBase
class CV_EXPORTS_W NoBundleAdjuster : public BundleAdjusterBase
{
public:
NoBundleAdjuster() : BundleAdjusterBase(0, 0) {}
CV_WRAP NoBundleAdjuster() : BundleAdjusterBase(0, 0) {}
private:
bool estimate(const std::vector<ImageFeatures> &, const std::vector<MatchesInfo> &,
@@ -238,10 +240,10 @@ error squares
It can estimate focal length, aspect ratio, principal point.
You can affect only on them via the refinement mask.
*/
class CV_EXPORTS BundleAdjusterReproj : public BundleAdjusterBase
class CV_EXPORTS_W BundleAdjusterReproj : public BundleAdjusterBase
{
public:
BundleAdjusterReproj() : BundleAdjusterBase(7, 2) {}
CV_WRAP BundleAdjusterReproj() : BundleAdjusterBase(7, 2) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) CV_OVERRIDE;
@@ -258,10 +260,10 @@ between the rays passing through the camera center and a feature. :
It can estimate focal length. It ignores the refinement mask for now.
*/
class CV_EXPORTS BundleAdjusterRay : public BundleAdjusterBase
class CV_EXPORTS_W BundleAdjusterRay : public BundleAdjusterBase
{
public:
BundleAdjusterRay() : BundleAdjusterBase(4, 3) {}
CV_WRAP BundleAdjusterRay() : BundleAdjusterBase(4, 3) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) CV_OVERRIDE;
@@ -282,10 +284,10 @@ It estimates all transformation parameters. Refinement mask is ignored.
@sa AffineBasedEstimator AffineBestOf2NearestMatcher BundleAdjusterAffinePartial
*/
class CV_EXPORTS BundleAdjusterAffine : public BundleAdjusterBase
class CV_EXPORTS_W BundleAdjusterAffine : public BundleAdjusterBase
{
public:
BundleAdjusterAffine() : BundleAdjusterBase(6, 2) {}
CV_WRAP BundleAdjusterAffine() : BundleAdjusterBase(6, 2) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) CV_OVERRIDE;
@@ -306,10 +308,10 @@ It estimates all transformation parameters. Refinement mask is ignored.
@sa AffineBasedEstimator AffineBestOf2NearestMatcher BundleAdjusterAffine
*/
class CV_EXPORTS BundleAdjusterAffinePartial : public BundleAdjusterBase
class CV_EXPORTS_W BundleAdjusterAffinePartial : public BundleAdjusterBase
{
public:
BundleAdjusterAffinePartial() : BundleAdjusterBase(4, 2) {}
CV_WRAP BundleAdjusterAffinePartial() : BundleAdjusterBase(4, 2) {}
private:
void setUpInitialCameraParams(const std::vector<CameraParams> &cameras) CV_OVERRIDE;
@@ -332,17 +334,17 @@ enum WaveCorrectKind
@param rmats Camera rotation matrices.
@param kind Correction kind, see detail::WaveCorrectKind.
*/
void CV_EXPORTS waveCorrect(std::vector<Mat> &rmats, WaveCorrectKind kind);
void CV_EXPORTS_W waveCorrect(CV_IN_OUT std::vector<Mat> &rmats, WaveCorrectKind kind);
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
// Returns matches graph representation in DOT language
String CV_EXPORTS matchesGraphAsString(std::vector<String> &pathes, std::vector<MatchesInfo> &pairwise_matches,
String CV_EXPORTS_W matchesGraphAsString(std::vector<String> &pathes, std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
std::vector<int> CV_EXPORTS leaveBiggestComponent(
CV_EXPORTS_W std::vector<int> leaveBiggestComponent(
std::vector<ImageFeatures> &features,
std::vector<MatchesInfo> &pairwise_matches,
float conf_threshold);
@@ -55,35 +55,37 @@ namespace detail {
/** @brief Base class for a seam estimator.
*/
class CV_EXPORTS SeamFinder
class CV_EXPORTS_W SeamFinder
{
public:
virtual ~SeamFinder() {}
CV_WRAP virtual ~SeamFinder() {}
enum { NO, VORONOI_SEAM, DP_SEAM };
/** @brief Estimates seams.
@param src Source images
@param corners Source image top-left corners
@param masks Source image masks to update
*/
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks) = 0;
CV_WRAP virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
CV_IN_OUT std::vector<UMat> &masks) = 0;
CV_WRAP static Ptr<SeamFinder> createDefault(int type);
};
/** @brief Stub seam estimator which does nothing.
*/
class CV_EXPORTS NoSeamFinder : public SeamFinder
class CV_EXPORTS_W NoSeamFinder : public SeamFinder
{
public:
void find(const std::vector<UMat>&, const std::vector<Point>&, std::vector<UMat>&) CV_OVERRIDE {}
CV_WRAP void find(const std::vector<UMat>&, const std::vector<Point>&, CV_IN_OUT std::vector<UMat>&) CV_OVERRIDE {}
};
/** @brief Base class for all pairwise seam estimators.
*/
class CV_EXPORTS PairwiseSeamFinder : public SeamFinder
class CV_EXPORTS_W PairwiseSeamFinder : public SeamFinder
{
public:
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks) CV_OVERRIDE;
CV_WRAP virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
CV_IN_OUT std::vector<UMat> &masks) CV_OVERRIDE;
protected:
void run();
@@ -103,11 +105,11 @@ protected:
/** @brief Voronoi diagram-based seam estimator.
*/
class CV_EXPORTS VoronoiSeamFinder : public PairwiseSeamFinder
class CV_EXPORTS_W VoronoiSeamFinder : public PairwiseSeamFinder
{
public:
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks) CV_OVERRIDE;
CV_WRAP virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
CV_IN_OUT std::vector<UMat> &masks) CV_OVERRIDE;
virtual void find(const std::vector<Size> &size, const std::vector<Point> &corners,
std::vector<UMat> &masks);
private:
@@ -115,15 +117,17 @@ private:
};
class CV_EXPORTS DpSeamFinder : public SeamFinder
class CV_EXPORTS_W DpSeamFinder : public SeamFinder
{
public:
enum CostFunction { COLOR, COLOR_GRAD };
DpSeamFinder(CostFunction costFunc = COLOR);
CV_WRAP DpSeamFinder(String costFunc );
CostFunction costFunction() const { return costFunc_; }
void setCostFunction(CostFunction val) { costFunc_ = val; }
CV_WRAP void setCostFunction(String val);
virtual void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks) CV_OVERRIDE;
@@ -233,15 +237,17 @@ public:
/** @brief Minimum graph cut-based seam estimator. See details in @cite V03 .
*/
class CV_EXPORTS GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder
class CV_EXPORTS_W GraphCutSeamFinder : public GraphCutSeamFinderBase, public SeamFinder
{
public:
GraphCutSeamFinder(int cost_type = COST_COLOR_GRAD, float terminal_cost = 10000.f,
float bad_region_penalty = 1000.f);
CV_WRAP GraphCutSeamFinder(String cost_type,float terminal_cost = 10000.f,
float bad_region_penalty = 1000.f);
~GraphCutSeamFinder();
void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
CV_WRAP void find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks) CV_OVERRIDE;
private:
@@ -54,7 +54,7 @@ namespace detail {
// Base Timelapser class, takes a sequence of images, applies appropriate shift, stores result in dst_.
class CV_EXPORTS Timelapser
class CV_EXPORTS_W Timelapser
{
public:
@@ -62,11 +62,11 @@ public:
virtual ~Timelapser() {}
static Ptr<Timelapser> createDefault(int type);
CV_WRAP static Ptr<Timelapser> createDefault(int type);
virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes);
virtual void process(InputArray img, InputArray mask, Point tl);
virtual const UMat& getDst() {return dst_;}
CV_WRAP virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_WRAP virtual void process(InputArray img, InputArray mask, Point tl);
CV_WRAP virtual const UMat& getDst() {return dst_;}
protected:
@@ -77,7 +77,7 @@ protected:
};
class CV_EXPORTS TimelapserCrop : public Timelapser
class CV_EXPORTS_W TimelapserCrop : public Timelapser
{
public:
virtual void initialize(const std::vector<Point> &corners, const std::vector<Size> &sizes) CV_OVERRIDE;
@@ -100,16 +100,16 @@ private:
//////////////////////////////////////////////////////////////////////////////
// Auxiliary functions
CV_EXPORTS bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi);
CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<UMat> &images);
CV_EXPORTS Rect resultRoi(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_EXPORTS Rect resultRoiIntersection(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_EXPORTS Point resultTl(const std::vector<Point> &corners);
CV_EXPORTS_W bool overlapRoi(Point tl1, Point tl2, Size sz1, Size sz2, Rect &roi);
CV_EXPORTS_W Rect resultRoi(const std::vector<Point> &corners, const std::vector<UMat> &images);
CV_EXPORTS_W Rect resultRoi(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_EXPORTS_W Rect resultRoiIntersection(const std::vector<Point> &corners, const std::vector<Size> &sizes);
CV_EXPORTS_W Point resultTl(const std::vector<Point> &corners);
// Returns random 'count' element subset of the {0,1,...,size-1} set
CV_EXPORTS void selectRandomSubset(int count, int size, std::vector<int> &subset);
CV_EXPORTS_W void selectRandomSubset(int count, int size, std::vector<int> &subset);
CV_EXPORTS int& stitchingLogLevel();
CV_EXPORTS_W int& stitchingLogLevel();
//! @}
@@ -92,7 +92,7 @@ public:
@return Project image top-left corner
*/
virtual Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
OutputArray dst) = 0;
CV_OUT OutputArray dst) = 0;
/** @brief Projects the image backward.
@@ -105,7 +105,7 @@ public:
@param dst Backward-projected image
*/
virtual void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
Size dst_size, OutputArray dst) = 0;
Size dst_size, CV_OUT OutputArray dst) = 0;
/**
@param src_size Source image bounding box
@@ -121,7 +121,7 @@ public:
/** @brief Base class for warping logic implementation.
*/
struct CV_EXPORTS ProjectorBase
struct CV_EXPORTS_W_SIMPLE ProjectorBase
{
void setCameraParams(InputArray K = Mat::eye(3, 3, CV_32F),
InputArray R = Mat::eye(3, 3, CV_32F),
@@ -189,13 +189,13 @@ public:
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE;
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R, InputArray T);
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, OutputArray xmap, OutputArray ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE;
virtual Rect buildMaps(Size src_size, InputArray K, InputArray R, InputArray T, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap);
Rect buildMaps(Size src_size, InputArray K, InputArray R, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap) CV_OVERRIDE;
Point warp(InputArray src, InputArray K, InputArray R,
int interp_mode, int border_mode, OutputArray dst) CV_OVERRIDE;
int interp_mode, int border_mode, CV_OUT OutputArray dst) CV_OVERRIDE;
virtual Point warp(InputArray src, InputArray K, InputArray R, InputArray T, int interp_mode, int border_mode,
OutputArray dst);
CV_OUT OutputArray dst);
Rect warpRoi(Size src_size, InputArray K, InputArray R) CV_OVERRIDE;
Rect warpRoi(Size src_size, InputArray K, InputArray R, InputArray T);
@@ -220,9 +220,9 @@ public:
AffineWarper(float scale = 1.f) : PlaneWarper(scale) {}
Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R) CV_OVERRIDE;
Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap) CV_OVERRIDE;
Rect buildMaps(Size src_size, InputArray K, InputArray R, CV_OUT OutputArray xmap, CV_OUT OutputArray ymap) CV_OVERRIDE;
Point warp(InputArray src, InputArray K, InputArray R,
int interp_mode, int border_mode, OutputArray dst) CV_OVERRIDE;
int interp_mode, int border_mode, CV_OUT OutputArray dst) CV_OVERRIDE;
Rect warpRoi(Size src_size, InputArray K, InputArray R) CV_OVERRIDE;
protected:
@@ -233,10 +233,10 @@ protected:
};
struct CV_EXPORTS SphericalProjector : ProjectorBase
struct CV_EXPORTS_W_SIMPLE SphericalProjector : ProjectorBase
{
void mapForward(float x, float y, float &u, float &v);
void mapBackward(float u, float v, float &x, float &y);
CV_WRAP void mapForward(float x, float y, float &u, float &v);
CV_WRAP void mapBackward(float u, float v, float &x, float &y);
};
@@ -44,25 +44,94 @@
#define OPENCV_STITCHING_WARPER_CREATORS_HPP
#include "opencv2/stitching/detail/warpers.hpp"
#include <string>
namespace cv {
class CV_EXPORTS_W PyRotationWarper
{
Ptr<detail::RotationWarper> rw;
public:
CV_WRAP PyRotationWarper(String type, float scale);
CV_WRAP PyRotationWarper() {};
~PyRotationWarper() {}
/** @brief Projects the image point.
@param pt Source point
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Projected point
*/
CV_WRAP Point2f warpPoint(const Point2f &pt, InputArray K, InputArray R);
/** @brief Builds the projection maps according to the given camera data.
@param src_size Source image size
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@param xmap Projection map for the x axis
@param ymap Projection map for the y axis
@return Projected image minimum bounding box
*/
CV_WRAP Rect buildMaps(Size src_size, InputArray K, InputArray R, OutputArray xmap, OutputArray ymap);
/** @brief Projects the image.
@param src Source image
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@param interp_mode Interpolation mode
@param border_mode Border extrapolation mode
@param dst Projected image
@return Project image top-left corner
*/
CV_WRAP Point warp(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
CV_OUT OutputArray dst);
/** @brief Projects the image backward.
@param src Projected image
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@param interp_mode Interpolation mode
@param border_mode Border extrapolation mode
@param dst_size Backward-projected image size
@param dst Backward-projected image
*/
CV_WRAP void warpBackward(InputArray src, InputArray K, InputArray R, int interp_mode, int border_mode,
Size dst_size, CV_OUT OutputArray dst);
/**
@param src_size Source image bounding box
@param K Camera intrinsic parameters
@param R Camera rotation matrix
@return Projected image minimum bounding box
*/
CV_WRAP Rect warpRoi(Size src_size, InputArray K, InputArray R);
CV_WRAP float getScale() const { return 1.f; }
CV_WRAP void setScale(float) {}
};
//! @addtogroup stitching_warp
//! @{
/** @brief Image warper factories base class.
*/
class WarperCreator
class CV_EXPORTS_W WarperCreator
{
public:
virtual ~WarperCreator() {}
CV_WRAP virtual ~WarperCreator() {}
virtual Ptr<detail::RotationWarper> create(float scale) const = 0;
};
/** @brief Plane warper factory class.
@sa detail::PlaneWarper
*/
class PlaneWarper : public WarperCreator
class CV_EXPORTS PlaneWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::PlaneWarper>(scale); }
@@ -71,7 +140,7 @@ public:
/** @brief Affine warper factory class.
@sa detail::AffineWarper
*/
class AffineWarper : public WarperCreator
class CV_EXPORTS AffineWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::AffineWarper>(scale); }
@@ -80,32 +149,32 @@ public:
/** @brief Cylindrical warper factory class.
@sa detail::CylindricalWarper
*/
class CylindricalWarper: public WarperCreator
class CV_EXPORTS CylindricalWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::CylindricalWarper>(scale); }
};
/** @brief Spherical warper factory class */
class SphericalWarper: public WarperCreator
class CV_EXPORTS SphericalWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::SphericalWarper>(scale); }
};
class FisheyeWarper : public WarperCreator
class CV_EXPORTS FisheyeWarper : public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::FisheyeWarper>(scale); }
};
class StereographicWarper: public WarperCreator
class CV_EXPORTS StereographicWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::StereographicWarper>(scale); }
};
class CompressedRectilinearWarper: public WarperCreator
class CV_EXPORTS CompressedRectilinearWarper: public WarperCreator
{
float a, b;
public:
@@ -116,7 +185,7 @@ public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::CompressedRectilinearWarper>(scale, a, b); }
};
class CompressedRectilinearPortraitWarper: public WarperCreator
class CV_EXPORTS CompressedRectilinearPortraitWarper: public WarperCreator
{
float a, b;
public:
@@ -127,7 +196,7 @@ public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::CompressedRectilinearPortraitWarper>(scale, a, b); }
};
class PaniniWarper: public WarperCreator
class CV_EXPORTS PaniniWarper: public WarperCreator
{
float a, b;
public:
@@ -138,7 +207,7 @@ public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::PaniniWarper>(scale, a, b); }
};
class PaniniPortraitWarper: public WarperCreator
class CV_EXPORTS PaniniPortraitWarper: public WarperCreator
{
float a, b;
public:
@@ -149,13 +218,13 @@ public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::PaniniPortraitWarper>(scale, a, b); }
};
class MercatorWarper: public WarperCreator
class CV_EXPORTS MercatorWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::MercatorWarper>(scale); }
};
class TransverseMercatorWarper: public WarperCreator
class CV_EXPORTS TransverseMercatorWarper: public WarperCreator
{
public:
Ptr<detail::RotationWarper> create(float scale) const CV_OVERRIDE { return makePtr<detail::TransverseMercatorWarper>(scale); }
@@ -3,4 +3,47 @@
typedef Stitcher::Status Status;
typedef Stitcher::Mode Mode;
typedef std::vector<detail::ImageFeatures> vector_ImageFeatures;
typedef std::vector<detail::MatchesInfo> vector_MatchesInfo;
typedef std::vector<detail::CameraParams> vector_CameraParams;
template<> struct pyopencvVecConverter<detail::ImageFeatures>
{
static bool to(PyObject* obj, std::vector<detail::ImageFeatures>& value, const ArgInfo info)
{
return pyopencv_to_generic_vec(obj, value, info);
}
static PyObject* from(const std::vector<detail::ImageFeatures>& value)
{
return pyopencv_from_generic_vec(value);
}
};
template<> struct pyopencvVecConverter<detail::MatchesInfo>
{
static bool to(PyObject* obj, std::vector<detail::MatchesInfo>& value, const ArgInfo info)
{
return pyopencv_to_generic_vec(obj, value, info);
}
static PyObject* from(const std::vector<detail::MatchesInfo>& value)
{
return pyopencv_from_generic_vec(value);
}
};
template<> struct pyopencvVecConverter<detail::CameraParams>
{
static bool to(PyObject* obj, std::vector<detail::CameraParams>& value, const ArgInfo info)
{
return pyopencv_to_generic_vec(obj, value, info);
}
static PyObject* from(const std::vector<detail::CameraParams>& value)
{
return pyopencv_from_generic_vec(value);
}
};
#endif
+34
View File
@@ -13,6 +13,7 @@ using namespace perf;
#define WORK_MEGAPIX 0.6
typedef TestBaseWithParam<string> stitch;
typedef TestBaseWithParam<int> stitchExposureCompensation;
typedef TestBaseWithParam<tuple<string, string> > stitchDatasets;
#ifdef HAVE_OPENCV_XFEATURES2D
@@ -20,6 +21,7 @@ typedef TestBaseWithParam<tuple<string, string> > stitchDatasets;
#else
#define TEST_DETECTORS testing::Values("orb", "akaze")
#endif
#define TEST_EXP_COMP_BS testing::Values(32, 16, 12, 10, 8)
#define AFFINE_DATASETS testing::Values("s", "budapest", "newspaper", "prague")
PERF_TEST_P(stitch, a123, TEST_DETECTORS)
@@ -58,6 +60,38 @@ PERF_TEST_P(stitch, a123, TEST_DETECTORS)
SANITY_CHECK_NOTHING();
}
PERF_TEST_P(stitchExposureCompensation, a123, TEST_EXP_COMP_BS)
{
Mat pano;
vector<Mat> imgs;
imgs.push_back( imread( getDataPath("stitching/a1.png") ) );
imgs.push_back( imread( getDataPath("stitching/a2.png") ) );
imgs.push_back( imread( getDataPath("stitching/a3.png") ) );
int bs = GetParam();
declare.time(30 * 10).iterations(10);
while(next())
{
Ptr<Stitcher> stitcher = Stitcher::create();
stitcher->setWarper(makePtr<SphericalWarper>());
stitcher->setRegistrationResol(WORK_MEGAPIX);
stitcher->setExposureCompensator(
makePtr<detail::BlocksGainCompensator>(bs, bs));
startTimer();
stitcher->stitch(imgs, pano);
stopTimer();
}
EXPECT_NEAR(pano.size().width, 1182, 50);
EXPECT_NEAR(pano.size().height, 682, 30);
SANITY_CHECK_NOTHING();
}
PERF_TEST_P(stitch, b12, TEST_DETECTORS)
{
Mat pano;
+1 -1
View File
@@ -70,7 +70,7 @@ Ptr<Blender> Blender::createDefault(int type, bool try_gpu)
if (type == NO)
return makePtr<Blender>();
if (type == FEATHER)
return makePtr<FeatherBlender>();
return makePtr<FeatherBlender>(try_gpu);
if (type == MULTI_BAND)
return makePtr<MultiBandBlender>(try_gpu);
CV_Error(Error::StsBadArg, "unsupported blending method");
+146 -39
View File
@@ -41,18 +41,28 @@
//M*/
#include "precomp.hpp"
#ifdef HAVE_EIGEN
#include <Eigen/Core>
#include <Eigen/Dense>
#endif
namespace cv {
namespace detail {
Ptr<ExposureCompensator> ExposureCompensator::createDefault(int type)
{
Ptr<ExposureCompensator> e;
if (type == NO)
return makePtr<NoExposureCompensator>();
if (type == GAIN)
return makePtr<GainCompensator>();
e = makePtr<NoExposureCompensator>();
else if (type == GAIN)
e = makePtr<GainCompensator>();
if (type == GAIN_BLOCKS)
return makePtr<BlocksGainCompensator>();
e = makePtr<BlocksGainCompensator>();
if (e.get() != nullptr)
{
e->setUpdateGain(true);
return e;
}
CV_Error(Error::StsBadArg, "unsupported exposure compensation method");
}
@@ -80,6 +90,7 @@ void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<
const int num_images = static_cast<int>(images.size());
Mat_<int> N(num_images, num_images); N.setTo(0);
Mat_<double> I(num_images, num_images); I.setTo(0);
Mat_<bool> skip(num_images, 1); skip.setTo(true);
//Rect dst_roi = resultRoi(corners, images);
Mat subimg1, subimg2;
@@ -99,7 +110,19 @@ void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<
submask2 = masks[j].first(Rect(roi.tl() - corners[j], roi.br() - corners[j])).getMat(ACCESS_READ);
intersect = (submask1 == masks[i].second) & (submask2 == masks[j].second);
N(i, j) = N(j, i) = std::max(1, countNonZero(intersect));
int intersect_count = countNonZero(intersect);
N(i, j) = N(j, i) = std::max(1, intersect_count);
// Don't compute Isums if subimages do not intersect anyway
if (intersect_count == 0)
continue;
// Don't skip images that intersect with at least one other image
if (i != j)
{
skip(i, 0) = false;
skip(j, 0) = false;
}
double Isum1 = 0, Isum2 = 0;
for (int y = 0; y < roi.height; ++y)
@@ -120,26 +143,68 @@ void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<
}
}
}
double alpha = 0.01;
double beta = 100;
Mat_<double> A(num_images, num_images); A.setTo(0);
Mat_<double> b(num_images, 1); b.setTo(0);
for (int i = 0; i < num_images; ++i)
if (getUpdateGain() || gains_.rows != num_images)
{
for (int j = 0; j < num_images; ++j)
double alpha = 0.01;
double beta = 100;
int num_eq = num_images - countNonZero(skip);
Mat_<double> A(num_eq, num_eq); A.setTo(0);
Mat_<double> b(num_eq, 1); b.setTo(0);
for (int i = 0, ki = 0; i < num_images; ++i)
{
b(i, 0) += beta * N(i, j);
A(i, i) += beta * N(i, j);
if (j == i) continue;
A(i, i) += 2 * alpha * I(i, j) * I(i, j) * N(i, j);
A(i, j) -= 2 * alpha * I(i, j) * I(j, i) * N(i, j);
if (skip(i, 0))
continue;
for (int j = 0, kj = 0; j < num_images; ++j)
{
if (skip(j, 0))
continue;
b(ki, 0) += beta * N(i, j);
A(ki, ki) += beta * N(i, j);
if (j != i)
{
A(ki, ki) += 2 * alpha * I(i, j) * I(i, j) * N(i, j);
A(ki, kj) -= 2 * alpha * I(i, j) * I(j, i) * N(i, j);
}
++kj;
}
++ki;
}
Mat_<double> l_gains;
#ifdef HAVE_EIGEN
Eigen::MatrixXf eigen_A, eigen_b, eigen_x;
cv2eigen(A, eigen_A);
cv2eigen(b, eigen_b);
Eigen::LLT<Eigen::MatrixXf> solver(eigen_A);
#if ENABLE_LOG
if (solver.info() != Eigen::ComputationInfo::Success)
LOGLN("Failed to solve exposure compensation system");
#endif
eigen_x = solver.solve(eigen_b);
Mat_<float> l_gains_float;
eigen2cv(eigen_x, l_gains_float);
l_gains_float.convertTo(l_gains, CV_64FC1);
#else
solve(A, b, l_gains);
#endif
CV_CheckTypeEQ(l_gains.type(), CV_64FC1, "");
gains_.create(num_images, 1);
for (int i = 0, j = 0; i < num_images; ++i)
{
if (skip(i, 0))
gains_.at<double>(i, 0) = 1;
else
gains_.at<double>(i, 0) = l_gains(j++, 0);
}
}
solve(A, b, gains_);
LOGLN("Exposure compensation, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
}
@@ -160,6 +225,24 @@ std::vector<double> GainCompensator::gains() const
return gains_vec;
}
void GainCompensator::getMatGains(std::vector<Mat>& umv)
{
umv.clear();
for (int i = 0; i < gains_.rows; ++i)
umv.push_back(Mat(1,1,CV_64FC1,Scalar(gains_(i, 0))));
}
void GainCompensator::setMatGains(std::vector<Mat>& umv)
{
gains_=Mat_<double>(static_cast<int>(umv.size()),1);
for (int i = 0; i < static_cast<int>(umv.size()); i++)
{
int type = umv[i].type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
CV_CheckType(type, depth == CV_64F && cn == 1, "Only double images are supported for gain");
CV_Assert(umv[i].rows == 1 && umv[i].cols == 1);
gains_(i, 0) = umv[i].at<double>(0, 0);
}
}
void BlocksGainCompensator::feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
const std::vector<std::pair<UMat,uchar> > &masks)
@@ -197,29 +280,32 @@ void BlocksGainCompensator::feed(const std::vector<Point> &corners, const std::v
}
}
GainCompensator compensator;
compensator.feed(block_corners, block_images, block_masks);
std::vector<double> gains = compensator.gains();
gain_maps_.resize(num_images);
Mat_<float> ker(1, 3);
ker(0,0) = 0.25; ker(0,1) = 0.5; ker(0,2) = 0.25;
int bl_idx = 0;
for (int img_idx = 0; img_idx < num_images; ++img_idx)
if (getUpdateGain())
{
Size bl_per_img = bl_per_imgs[img_idx];
gain_maps_[img_idx].create(bl_per_img, CV_32F);
GainCompensator compensator;
compensator.feed(block_corners, block_images, block_masks);
std::vector<double> gains = compensator.gains();
gain_maps_.resize(num_images);
Mat_<float> ker(1, 3);
ker(0, 0) = 0.25; ker(0, 1) = 0.5; ker(0, 2) = 0.25;
int bl_idx = 0;
for (int img_idx = 0; img_idx < num_images; ++img_idx)
{
Mat_<float> gain_map = gain_maps_[img_idx].getMat(ACCESS_WRITE);
for (int by = 0; by < bl_per_img.height; ++by)
for (int bx = 0; bx < bl_per_img.width; ++bx, ++bl_idx)
gain_map(by, bx) = static_cast<float>(gains[bl_idx]);
}
Size bl_per_img = bl_per_imgs[img_idx];
gain_maps_[img_idx].create(bl_per_img, CV_32F);
sepFilter2D(gain_maps_[img_idx], gain_maps_[img_idx], CV_32F, ker, ker);
sepFilter2D(gain_maps_[img_idx], gain_maps_[img_idx], CV_32F, ker, ker);
{
Mat_<float> gain_map = gain_maps_[img_idx].getMat(ACCESS_WRITE);
for (int by = 0; by < bl_per_img.height; ++by)
for (int bx = 0; bx < bl_per_img.width; ++bx, ++bl_idx)
gain_map(by, bx) = static_cast<float>(gains[bl_idx]);
}
sepFilter2D(gain_maps_[img_idx], gain_maps_[img_idx], CV_32F, ker, ker);
sepFilter2D(gain_maps_[img_idx], gain_maps_[img_idx], CV_32F, ker, ker);
}
}
}
@@ -251,5 +337,26 @@ void BlocksGainCompensator::apply(int index, Point /*corner*/, InputOutputArray
}
}
void BlocksGainCompensator::getMatGains(std::vector<Mat>& umv)
{
umv.clear();
for (int i = 0; i < static_cast<int>(gain_maps_.size()); ++i)
{
Mat m;
gain_maps_[i].copyTo(m);
umv.push_back(m);
}
}
void BlocksGainCompensator::setMatGains(std::vector<Mat>& umv)
{
for (int i = 0; i < static_cast<int>(umv.size()); i++)
{
UMat m;
umv[i].copyTo(m);
gain_maps_.push_back(m);
}
}
} // namespace detail
} // namespace cv
+6
View File
@@ -384,6 +384,12 @@ BestOf2NearestMatcher::BestOf2NearestMatcher(bool try_use_gpu, float match_conf,
num_matches_thresh2_ = num_matches_thresh2;
}
Ptr<BestOf2NearestMatcher> BestOf2NearestMatcher::create(bool try_use_gpu, float match_conf, int num_matches_thresh1, int num_matches_thresh2)
{
return makePtr<BestOf2NearestMatcher>(try_use_gpu, match_conf, num_matches_thresh1, num_matches_thresh2);
}
void BestOf2NearestMatcher::match(const ImageFeatures &features1, const ImageFeatures &features2,
MatchesInfo &matches_info)
+45
View File
@@ -47,6 +47,18 @@
namespace cv {
namespace detail {
Ptr<SeamFinder> SeamFinder::createDefault(int type)
{
if (type == NO)
return makePtr<NoSeamFinder>();
if (type == VORONOI_SEAM)
return makePtr<VoronoiSeamFinder>();
if (type == DP_SEAM)
return makePtr<DpSeamFinder>();
CV_Error(Error::StsBadArg, "unsupported exposure compensation method");
}
void PairwiseSeamFinder::find(const std::vector<UMat> &src, const std::vector<Point> &corners,
std::vector<UMat> &masks)
{
@@ -165,6 +177,26 @@ void VoronoiSeamFinder::findInPair(size_t first, size_t second, Rect roi)
DpSeamFinder::DpSeamFinder(CostFunction costFunc) : costFunc_(costFunc), ncomps_(0) {}
DpSeamFinder::DpSeamFinder(String costFunc)
{
ncomps_ = 0;
if (costFunc == "COLOR")
costFunc_ = COLOR;
else if (costFunc == "COLOR_GRAD")
costFunc_ = COLOR_GRAD;
else
CV_Error(-1, "Unknown cost function");
}
void DpSeamFinder::setCostFunction(String costFunc)
{
if (costFunc == "COLOR")
costFunc_ = COLOR;
else if (costFunc == "COLOR_GRAD")
costFunc_ = COLOR_GRAD;
else
CV_Error(-1, "Unknown cost function");
}
void DpSeamFinder::find(const std::vector<UMat> &src, const std::vector<Point> &corners, std::vector<UMat> &masks)
{
@@ -1324,6 +1356,19 @@ void GraphCutSeamFinder::Impl::findInPair(size_t first, size_t second, Rect roi)
}
}
GraphCutSeamFinder::GraphCutSeamFinder(String cost_type, float terminal_cost, float bad_region_penalty)
{
CostType t;
if (cost_type == "COST_COLOR")
t = COST_COLOR;
else if (cost_type == "COST_COLOR_GRAD")
t = COST_COLOR_GRAD;
else
CV_Error(Error::StsBadFunc, "Unknown cost type function");
impl_ = new Impl(t, terminal_cost, bad_region_penalty);
}
GraphCutSeamFinder::GraphCutSeamFinder(int cost_type, float terminal_cost, float bad_region_penalty)
: impl_(new Impl(cost_type, terminal_cost, bad_region_penalty)) {}

Some files were not shown because too many files have changed in this diff Show More