mirror of
https://github.com/opencv/opencv.git
synced 2026-07-25 21:33:04 +04:00
Compare commits
91 Commits
4.0.1-openvino
...
4.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
| c9ad5779f2 | |||
| 26c5b0c71f | |||
| 1dee705074 | |||
| c0e11bb50e | |||
| f35e043cf9 | |||
| 8f1356c3c5 | |||
| 14633bc857 | |||
| 578ea4bae9 | |||
| 2bba0f297b | |||
| 6c1638b132 | |||
| 1a6c2b37ea | |||
| 840c892abd | |||
| 09d8bbb138 | |||
| 832217907f | |||
| 26c5b846e6 | |||
| 59ce1d80a5 | |||
| 2f3e06ac1f | |||
| 37a63ca02b | |||
| 0d63bd575c | |||
| 257f60582a | |||
| bbdc987fc6 | |||
| 124011c321 | |||
| 8456d096d2 | |||
| 32c975b533 | |||
| a3a3670027 | |||
| b6a72826dd | |||
| 6bcf0b5519 | |||
| 3d5cebb3ac | |||
| e82d03ef61 | |||
| 131c09cf76 | |||
| 06f32e3b3e | |||
| eedd7bfd50 | |||
| cbf80117af | |||
| 2b35c1708b | |||
| e093a19c70 | |||
| 6fbcb283b9 | |||
| 7fb70e1701 | |||
| 2fb409b286 | |||
| b0a08cced9 | |||
| 82b7803a7a | |||
| 50ef9830e2 | |||
| d5f430cc11 | |||
| 8ed4fb9405 | |||
| de82d9da9e | |||
| fd27d5ea00 | |||
| 715f8fcce0 | |||
| 3f3c8823ac | |||
| d9d9b05912 | |||
| 55171b25f8 | |||
| 3eb2c940de | |||
| 493611ace5 | |||
| bb8c19aad3 | |||
| b571f03016 | |||
| f605898bae | |||
| 5736bf5dd5 | |||
| 4f9c1da806 | |||
| eb1f3733ee | |||
| d993b9c1df | |||
| 4e16ae9a1f | |||
| ab86f15ba0 | |||
| e058febaad | |||
| 0a801354b1 | |||
| d7f60f69f1 | |||
| d99a4af229 | |||
| 4b33910449 | |||
| c1e9a7ee4b | |||
| 82a02d8585 | |||
| 8d907d2e32 | |||
| 0c16d8f6c3 | |||
| b7bb79c7c8 | |||
| 5340073770 | |||
| 3903174f7c | |||
| a9771078df | |||
| eb1f7797e4 | |||
| aa666dfa9c | |||
| 3e710d8eec | |||
| 384ac63490 | |||
| 954098d1cb | |||
| e71758cfdf | |||
| cea3289bd4 | |||
| 00285a5e88 | |||
| d38676085a | |||
| d8583b2c7a | |||
| 82227b5ace | |||
| 6fa23f330f | |||
| c8f934b5b1 | |||
| 857fba0878 | |||
| a4111fab39 | |||
| 54de51ef3c | |||
| 0915df5b18 | |||
| 53f6198f27 |
Vendored
+2
@@ -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)
|
||||
|
||||
Vendored
+1
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
|
||||
+6
-2
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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}"
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"))
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
int avg_pool_padded_area_;
|
||||
int need_mask_;
|
||||
PaddingMode padding_mode_;
|
||||
int activation_;
|
||||
//int activation_;
|
||||
PoolShaderConfig config_;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -12,8 +12,9 @@ namespace cv { namespace dnn { namespace vkcom {
|
||||
|
||||
#ifdef HAVE_VULKAN
|
||||
|
||||
struct Context
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
Context();
|
||||
~Context();
|
||||
};
|
||||
|
||||
@@ -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_));
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+706
-798
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
|
||||
+775
-1835
File diff suppressed because it is too large
Load Diff
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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()
|
||||
|
||||
@@ -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>
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user