mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
commit
22dbcf98c5
@ -295,8 +295,8 @@ OCV_OPTION(BUILD_ANDROID_EXAMPLES "Build examples for Android platform"
|
||||
OCV_OPTION(BUILD_DOCS "Create build rules for OpenCV Documentation" OFF IF (NOT WINRT AND NOT APPLE_FRAMEWORK))
|
||||
OCV_OPTION(BUILD_EXAMPLES "Build all examples" OFF )
|
||||
OCV_OPTION(BUILD_PACKAGE "Enables 'make package_source' command" ON IF NOT WINRT)
|
||||
OCV_OPTION(BUILD_PERF_TESTS "Build performance tests" ON IF (NOT APPLE_FRAMEWORK) )
|
||||
OCV_OPTION(BUILD_TESTS "Build accuracy & regression tests" ON IF (NOT APPLE_FRAMEWORK) )
|
||||
OCV_OPTION(BUILD_PERF_TESTS "Build performance tests" NOT INSTALL_CREATE_DISTRIB IF (NOT APPLE_FRAMEWORK) )
|
||||
OCV_OPTION(BUILD_TESTS "Build accuracy & regression tests" NOT INSTALL_CREATE_DISTRIB IF (NOT APPLE_FRAMEWORK) )
|
||||
OCV_OPTION(BUILD_WITH_DEBUG_INFO "Include debug info into release binaries ('OFF' means default settings)" OFF )
|
||||
OCV_OPTION(BUILD_WITH_STATIC_CRT "Enables use of statically linked CRT for statically linked OpenCV" ON IF MSVC )
|
||||
OCV_OPTION(BUILD_WITH_DYNAMIC_IPP "Enables dynamic linking of IPP (only for standalone IPP)" OFF )
|
||||
@ -461,6 +461,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")
|
||||
endif()
|
||||
|
||||
ocv_update(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_LIB_INSTALL_PATH}")
|
||||
|
@ -78,9 +78,9 @@ endif()
|
||||
|
||||
if(INF_ENGINE_TARGET)
|
||||
if(NOT INF_ENGINE_RELEASE)
|
||||
message(WARNING "InferenceEngine version have not been set, 2018R3 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
message(WARNING "InferenceEngine version have not been set, 2018R4 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
endif()
|
||||
set(INF_ENGINE_RELEASE "2018030000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
|
||||
set(INF_ENGINE_RELEASE "2018040000" 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}"
|
||||
)
|
||||
|
@ -43,7 +43,12 @@ else()
|
||||
endif()
|
||||
file(RELATIVE_PATH OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG
|
||||
"${CMAKE_INSTALL_PREFIX}/${OPENCV_SETUPVARS_INSTALL_PATH}/" "${CMAKE_INSTALL_PREFIX}/")
|
||||
ocv_path_join(OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG "${OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG}" "python_loader") # https://github.com/opencv/opencv/pull/12977
|
||||
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")
|
||||
else()
|
||||
ocv_path_join(OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG "${OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG}" "${OPENCV_PYTHON_INSTALL_PATH}")
|
||||
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}"
|
||||
DESTINATION "${OPENCV_SETUPVARS_INSTALL_PATH}"
|
||||
|
@ -605,7 +605,9 @@ macro(OCV_OPTION variable description value)
|
||||
option(${variable} "${description}" ${__value})
|
||||
endif()
|
||||
else()
|
||||
if(DEFINED ${variable} AND NOT OPENCV_HIDE_WARNING_UNSUPPORTED_OPTION)
|
||||
if(DEFINED ${variable} AND "${${variable}}" # emit warnings about turned ON options only.
|
||||
AND NOT (OPENCV_HIDE_WARNING_UNSUPPORTED_OPTION OR "$ENV{OPENCV_HIDE_WARNING_UNSUPPORTED_OPTION}")
|
||||
)
|
||||
message(WARNING "Unexpected option: ${variable} (=${${variable}})\nCondition: IF (${__condition})")
|
||||
endif()
|
||||
if(OPENCV_UNSET_UNSUPPORTED_OPTION)
|
||||
|
@ -1,18 +1,36 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL EnableDelayedExpansion
|
||||
|
||||
SET "SCRIPT_DIR=%~dp0"
|
||||
|
||||
IF NOT DEFINED OPENCV_QUIET ( ECHO Setting vars for OpenCV @OPENCV_VERSION@ )
|
||||
SET "PATH=!SCRIPT_DIR!\@OPENCV_LIB_RUNTIME_DIR_RELATIVE_CMAKECONFIG@;%PATH%"
|
||||
SET "PATH=%SCRIPT_DIR%\@OPENCV_LIB_RUNTIME_DIR_RELATIVE_CMAKECONFIG@;%PATH%"
|
||||
|
||||
IF NOT DEFINED OPENCV_SKIP_PYTHON (
|
||||
SET "PYTHONPATH_OPENCV=!SCRIPT_DIR!\@OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG@"
|
||||
IF NOT DEFINED OPENCV_QUIET ( ECHO Append PYTHONPATH: !PYTHONPATH_OPENCV! )
|
||||
SET "PYTHONPATH=!PYTHONPATH_OPENCV!;%PYTHONPATH%"
|
||||
)
|
||||
IF NOT DEFINED OPENCV_SKIP_PYTHON CALL :SET_PYTHON
|
||||
|
||||
SET SCRIPT_DIR=
|
||||
|
||||
IF NOT [%1] == [] GOTO :RUN_COMMAND
|
||||
|
||||
GOTO :EOF
|
||||
|
||||
:RUN_COMMAND
|
||||
SET RUN_INTERACTIVE=1
|
||||
echo %CMDCMDLINE% | find /i "%~0" >nul
|
||||
IF NOT errorlevel 1 set RUN_INTERACTIVE=0
|
||||
|
||||
IF NOT [%1] == [] (
|
||||
%*
|
||||
EXIT /B !errorlevel!
|
||||
SET RESULT=%ERRORLEVEL%
|
||||
IF %RESULT% NEQ 0 (
|
||||
IF _%RUN_INTERACTIVE%_==_0_ ( IF NOT DEFINED OPENCV_BATCH_MODE ( pause ) )
|
||||
)
|
||||
EXIT /B %RESULT%
|
||||
|
||||
:SET_PYTHON
|
||||
SET "PYTHONPATH_OPENCV=%SCRIPT_DIR%\@OPENCV_PYTHON_DIR_RELATIVE_CMAKECONFIG@"
|
||||
IF NOT DEFINED OPENCV_QUIET ( ECHO Append PYTHONPATH: %PYTHONPATH_OPENCV% )
|
||||
SET "PYTHONPATH=%PYTHONPATH_OPENCV%;%PYTHONPATH%"
|
||||
SET PYTHONPATH_OPENCV=
|
||||
EXIT /B
|
||||
|
||||
|
||||
:EOF
|
||||
|
@ -257,6 +257,7 @@ PREDEFINED = __cplusplus=1 \
|
||||
CV_SSE2=1 \
|
||||
CV__DEBUG_NS_BEGIN= \
|
||||
CV__DEBUG_NS_END= \
|
||||
CV_DEPRECATED_EXTERNAL= \
|
||||
CV_DEPRECATED=
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
|
@ -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.3-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.4-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`.
|
||||
|
||||
|
@ -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/3.4.3
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.0.0
|
||||
@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/3.4.3
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.0.0
|
||||
@endcode
|
||||
|
||||
Doxygen can now use the information from the tag file to link to the OpenCV
|
||||
|
@ -78,5 +78,5 @@ there are two flags that should be used to set/get property of the needed genera
|
||||
flag value is assumed by default if neither of the two possible values of the property is set.
|
||||
|
||||
For more information please refer to the example of usage
|
||||
[intelperc_capture.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/intelperc_capture.cpp)
|
||||
[videocapture_intelperc.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/videocapture_intelperc.cpp)
|
||||
in opencv/samples/cpp folder.
|
||||
|
@ -134,5 +134,5 @@ property. The following properties of cameras available through OpenNI interface
|
||||
- CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION = CAP_OPENNI_DEPTH_GENERATOR + CAP_PROP_OPENNI_REGISTRATION
|
||||
|
||||
For more information please refer to the example of usage
|
||||
[openni_capture.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/openni_capture.cpp) in
|
||||
[videocapture_openni.cpp](https://github.com/opencv/opencv/tree/master/samples/cpp/videocapture_openni.cpp) in
|
||||
opencv/samples/cpp folder.
|
||||
|
@ -86,3 +86,47 @@ ocv_add_accuracy_tests()
|
||||
ocv_add_perf_tests()
|
||||
|
||||
ocv_install_3rdparty_licenses(SoftFloat "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/SoftFloat/COPYING.txt")
|
||||
|
||||
|
||||
# generate data (samples data) config file
|
||||
set(OPENCV_DATA_CONFIG_FILE "${CMAKE_BINARY_DIR}/opencv_data_config.hpp")
|
||||
set(OPENCV_DATA_CONFIG_STR "")
|
||||
|
||||
if(CMAKE_INSTALL_PREFIX)
|
||||
set(OPENCV_DATA_CONFIG_STR "${OPENCV_DATA_CONFIG_STR}
|
||||
#define OPENCV_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\"
|
||||
")
|
||||
endif()
|
||||
if(OPENCV_OTHER_INSTALL_PATH)
|
||||
set(OPENCV_DATA_CONFIG_STR "${OPENCV_DATA_CONFIG_STR}
|
||||
#define OPENCV_DATA_INSTALL_PATH \"${OPENCV_OTHER_INSTALL_PATH}\"
|
||||
")
|
||||
endif()
|
||||
|
||||
set(OPENCV_DATA_CONFIG_STR "${OPENCV_DATA_CONFIG_STR}
|
||||
#define OPENCV_BUILD_DIR \"${CMAKE_BINARY_DIR}\"
|
||||
")
|
||||
|
||||
file(RELATIVE_PATH SOURCE_DIR_RELATIVE ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR})
|
||||
set(OPENCV_DATA_CONFIG_STR "${OPENCV_DATA_CONFIG_STR}
|
||||
#define OPENCV_DATA_BUILD_DIR_SEARCH_PATHS \\
|
||||
\"${SOURCE_DIR_RELATIVE}/\"
|
||||
")
|
||||
|
||||
if(WIN32)
|
||||
file(RELATIVE_PATH INSTALL_DATA_DIR_RELATIVE "${CMAKE_INSTALL_PREFIX}/${OPENCV_BIN_INSTALL_PATH}" "${CMAKE_INSTALL_PREFIX}/${OPENCV_OTHER_INSTALL_PATH}")
|
||||
else()
|
||||
file(RELATIVE_PATH INSTALL_DATA_DIR_RELATIVE "${CMAKE_INSTALL_PREFIX}/${OPENCV_LIB_INSTALL_PATH}" "${CMAKE_INSTALL_PREFIX}/${OPENCV_OTHER_INSTALL_PATH}")
|
||||
endif()
|
||||
list(APPEND OPENCV_INSTALL_DATA_DIR_RELATIVE "${INSTALL_DATA_DIR_RELATIVE}")
|
||||
string(REPLACE ";" "\",\\\n \"" OPENCV_INSTALL_DATA_DIR_RELATIVE_STR "\"${OPENCV_INSTALL_DATA_DIR_RELATIVE}\"")
|
||||
set(OPENCV_DATA_CONFIG_STR "${OPENCV_DATA_CONFIG_STR}
|
||||
#define OPENCV_INSTALL_DATA_DIR_RELATIVE ${OPENCV_INSTALL_DATA_DIR_RELATIVE_STR}
|
||||
")
|
||||
|
||||
if(EXISTS "${OPENCV_DATA_CONFIG_FILE}")
|
||||
file(READ "${OPENCV_DATA_CONFIG_FILE}" __content)
|
||||
endif()
|
||||
if(NOT OPENCV_DATA_CONFIG_STR STREQUAL "${__content}")
|
||||
file(WRITE "${OPENCV_DATA_CONFIG_FILE}" "${OPENCV_DATA_CONFIG_STR}")
|
||||
endif()
|
||||
|
@ -75,6 +75,7 @@
|
||||
@defgroup core_utils_sse SSE utilities
|
||||
@defgroup core_utils_neon NEON utilities
|
||||
@defgroup core_utils_softfloat Softfloat support
|
||||
@defgroup core_utils_samples Utility functions for OpenCV samples
|
||||
@}
|
||||
@defgroup core_opengl OpenGL interoperability
|
||||
@defgroup core_ipp Intel IPP Asynchronous C/C++ Converters
|
||||
|
@ -349,6 +349,15 @@ Cv64suf;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef CV_DEPRECATED_EXTERNAL
|
||||
# if defined(__OPENCV_BUILD)
|
||||
# define CV_DEPRECATED_EXTERNAL /* nothing */
|
||||
# else
|
||||
# define CV_DEPRECATED_EXTERNAL CV_DEPRECATED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CV_EXTERN_C
|
||||
# ifdef __cplusplus
|
||||
# define CV_EXTERN_C extern "C"
|
||||
|
@ -1363,25 +1363,22 @@ inline v_float64x4 v_cvt_f64_high(const v_float32x8& a)
|
||||
|
||||
inline v_int32x8 v_lut(const int* tab, const v_int32x8& idxvec)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[8];
|
||||
v_store_aligned(idx, idxvec);
|
||||
return v_int32x8(_mm256_setr_epi32(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]],
|
||||
tab[idx[4]], tab[idx[5]], tab[idx[6]], tab[idx[7]]));
|
||||
return v_int32x8(_mm256_i32gather_epi32(tab, idxvec.val, 4));
|
||||
}
|
||||
|
||||
inline v_uint32x8 v_lut(const unsigned* tab, const v_int32x8& idxvec)
|
||||
{
|
||||
return v_reinterpret_as_u32(v_lut((const int *)tab, idxvec));
|
||||
}
|
||||
|
||||
inline v_float32x8 v_lut(const float* tab, const v_int32x8& idxvec)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[8];
|
||||
v_store_aligned(idx, idxvec);
|
||||
return v_float32x8(_mm256_setr_ps(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]],
|
||||
tab[idx[4]], tab[idx[5]], tab[idx[6]], tab[idx[7]]));
|
||||
return v_float32x8(_mm256_i32gather_ps(tab, idxvec.val, 4));
|
||||
}
|
||||
|
||||
inline v_float64x4 v_lut(const double* tab, const v_int32x8& idxvec)
|
||||
{
|
||||
int CV_DECL_ALIGNED(32) idx[8];
|
||||
v_store_aligned(idx, idxvec);
|
||||
return v_float64x4(_mm256_setr_pd(tab[idx[0]], tab[idx[1]], tab[idx[2]], tab[idx[3]]));
|
||||
return v_float64x4(_mm256_i32gather_pd(tab, _mm256_castsi256_si128(idxvec.val), 8));
|
||||
}
|
||||
|
||||
inline void v_lut_deinterleave(const float* tab, const v_int32x8& idxvec, v_float32x8& x, v_float32x8& y)
|
||||
|
@ -794,6 +794,82 @@ CV_EXPORTS InstrNode* getCurrentNode();
|
||||
#define CV_INSTRUMENT_REGION(); CV_INSTRUMENT_REGION_();
|
||||
#endif
|
||||
|
||||
namespace cv {
|
||||
|
||||
namespace utils {
|
||||
|
||||
//! @addtogroup core_utils
|
||||
//! @{
|
||||
|
||||
/** @brief Try to find requested data file
|
||||
|
||||
Search directories:
|
||||
|
||||
1. Directories passed via `addDataSearchPath()`
|
||||
2. Check path specified by configuration parameter with "_HINT" suffix (name of environment variable).
|
||||
3. Check path specified by configuration parameter (name of environment variable).
|
||||
If parameter value is not empty and nothing is found then stop searching.
|
||||
4. Detects build/install path based on:
|
||||
a. current working directory (CWD)
|
||||
b. and/or binary module location (opencv_core/opencv_world, doesn't work with static linkage)
|
||||
5. Scan `<source>/{,data}` directories if build directory is detected or the current directory is in source tree.
|
||||
6. Scan `<install>/share/OpenCV` directory if install directory is detected.
|
||||
|
||||
@param relative_path Relative path to data file
|
||||
@param required Specify "file not found" handling.
|
||||
If true, function prints information message and raises cv::Exception.
|
||||
If false, function returns empty result
|
||||
@param configuration_parameter specify configuration parameter name. Default NULL value means "OPENCV_DATA_PATH".
|
||||
@return Returns path (absolute or relative to the current directory) or empty string if file is not found
|
||||
|
||||
@note Implementation is not thread-safe.
|
||||
*/
|
||||
CV_EXPORTS
|
||||
cv::String findDataFile(const cv::String& relative_path, bool required = true,
|
||||
const char* configuration_parameter = NULL);
|
||||
|
||||
/** @overload
|
||||
@param relative_path Relative path to data file
|
||||
@param configuration_parameter specify configuration parameter name. Default NULL value means "OPENCV_DATA_PATH".
|
||||
@param search_paths override addDataSearchPath() settings.
|
||||
@param subdir_paths override addDataSearchSubDirectory() settings.
|
||||
@return Returns path (absolute or relative to the current directory) or empty string if file is not found
|
||||
|
||||
@note Implementation is not thread-safe.
|
||||
*/
|
||||
CV_EXPORTS
|
||||
cv::String findDataFile(const cv::String& relative_path,
|
||||
const char* configuration_parameter,
|
||||
const std::vector<String>* search_paths,
|
||||
const std::vector<String>* subdir_paths);
|
||||
|
||||
/** @brief Override default search data path by adding new search location
|
||||
|
||||
Use this only to override default behavior
|
||||
Passed paths are used in LIFO order.
|
||||
|
||||
@param path Path to used samples data
|
||||
|
||||
@note Implementation is not thread-safe.
|
||||
*/
|
||||
CV_EXPORTS void addDataSearchPath(const cv::String& path);
|
||||
|
||||
/** @brief Append default search data sub directory
|
||||
|
||||
General usage is to add OpenCV modules name (`<opencv_contrib>/modules/<name>/data` -> `modules/<name>/data` + `<name>/data`).
|
||||
Passed subdirectories are used in LIFO order.
|
||||
|
||||
@param subdir samples data sub directory
|
||||
|
||||
@note Implementation is not thread-safe.
|
||||
*/
|
||||
CV_EXPORTS void addDataSearchSubDirectory(const cv::String& subdir);
|
||||
|
||||
//! @}
|
||||
|
||||
} // namespace utils
|
||||
} // namespace cv
|
||||
|
||||
//! @endcond
|
||||
|
||||
#endif // OPENCV_CORE_PRIVATE_HPP
|
||||
|
@ -1234,8 +1234,75 @@ enum FLAGS
|
||||
CV_EXPORTS void setFlags(FLAGS modeFlags);
|
||||
static inline void setFlags(int modeFlags) { setFlags((FLAGS)modeFlags); }
|
||||
CV_EXPORTS FLAGS getFlags();
|
||||
|
||||
} // namespace instr
|
||||
|
||||
|
||||
namespace samples {
|
||||
|
||||
//! @addtogroup core_utils_samples
|
||||
// This section describes utility functions for OpenCV samples.
|
||||
//
|
||||
// @note Implementation of these utilities is not thread-safe.
|
||||
//
|
||||
//! @{
|
||||
|
||||
/** @brief Try to find requested data file
|
||||
|
||||
Search directories:
|
||||
|
||||
1. Directories passed via `addSamplesDataSearchPath()`
|
||||
2. OPENCV_SAMPLES_DATA_PATH_HINT environment variable
|
||||
3. OPENCV_SAMPLES_DATA_PATH environment variable
|
||||
If parameter value is not empty and nothing is found then stop searching.
|
||||
4. Detects build/install path based on:
|
||||
a. current working directory (CWD)
|
||||
b. and/or binary module location (opencv_core/opencv_world, doesn't work with static linkage)
|
||||
5. Scan `<source>/{,data,samples/data}` directories if build directory is detected or the current directory is in source tree.
|
||||
6. Scan `<install>/share/OpenCV` directory if install directory is detected.
|
||||
|
||||
@see cv::utils::findDataFile
|
||||
|
||||
@param relative_path Relative path to data file
|
||||
@param required Specify "file not found" handling.
|
||||
If true, function prints information message and raises cv::Exception.
|
||||
If false, function returns empty result
|
||||
@param silentMode Disables messages
|
||||
@return Returns path (absolute or relative to the current directory) or empty string if file is not found
|
||||
*/
|
||||
CV_EXPORTS_W cv::String findFile(const cv::String& relative_path, bool required = true, bool silentMode = false);
|
||||
|
||||
CV_EXPORTS_W cv::String findFileOrKeep(const cv::String& relative_path, bool silentMode = false);
|
||||
|
||||
inline cv::String findFileOrKeep(const cv::String& relative_path, bool silentMode)
|
||||
{
|
||||
cv::String res = findFile(relative_path, false, silentMode);
|
||||
if (res.empty())
|
||||
return relative_path;
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Override search data path by adding new search location
|
||||
|
||||
Use this only to override default behavior
|
||||
Passed paths are used in LIFO order.
|
||||
|
||||
@param path Path to used samples data
|
||||
*/
|
||||
CV_EXPORTS_W void addSamplesDataSearchPath(const cv::String& path);
|
||||
|
||||
/** @brief Append samples search data sub directory
|
||||
|
||||
General usage is to add OpenCV modules name (`<opencv_contrib>/modules/<name>/samples/data` -> `<name>/samples/data` + `modules/<name>/samples/data`).
|
||||
Passed subdirectories are used in LIFO order.
|
||||
|
||||
@param subdir samples data sub directory
|
||||
*/
|
||||
CV_EXPORTS_W void addSamplesDataSearchSubDirectory(const cv::String& subdir);
|
||||
|
||||
//! @}
|
||||
} // namespace samples
|
||||
|
||||
namespace utils {
|
||||
|
||||
CV_EXPORTS int getThreadID();
|
||||
|
@ -16,6 +16,13 @@ CV_EXPORTS void remove_all(const cv::String& path);
|
||||
|
||||
CV_EXPORTS cv::String getcwd();
|
||||
|
||||
/** @brief Converts path p to a canonical absolute path
|
||||
* Symlinks are processed if there is support for them on running platform.
|
||||
*
|
||||
* @param path input path. Target file/directory should exist.
|
||||
*/
|
||||
CV_EXPORTS cv::String canonical(const cv::String& path);
|
||||
|
||||
/** Join path components */
|
||||
CV_EXPORTS cv::String join(const cv::String& base, const cv::String& path);
|
||||
|
||||
|
@ -297,19 +297,21 @@ void cv::batchDistance( InputArray _src1, InputArray _src2,
|
||||
nidx = Scalar::all(-1);
|
||||
}
|
||||
|
||||
|
||||
if( crosscheck )
|
||||
{
|
||||
CV_Assert( K == 1 && update == 0 && mask.empty() );
|
||||
CV_Assert(!nidx.empty());
|
||||
Mat tdist, tidx;
|
||||
Mat tdist, tidx, sdist, sidx;
|
||||
batchDistance(src2, src1, tdist, dtype, tidx, normType, K, mask, 0, false);
|
||||
batchDistance(src1, src2, sdist, dtype, sidx, normType, K, mask, 0, false);
|
||||
|
||||
// if an idx-th element from src1 appeared to be the nearest to i-th element of src2,
|
||||
// we update the minimum mutual distance between idx-th element of src1 and the whole src2 set.
|
||||
// As a result, if nidx[idx] = i*, it means that idx-th element of src1 is the nearest
|
||||
// to i*-th element of src2 and i*-th element of src2 is the closest to idx-th element of src1.
|
||||
// If nidx[idx] = -1, it means that there is no such ideal couple for it in src2.
|
||||
// This O(N) procedure is called cross-check and it helps to eliminate some false matches.
|
||||
// This O(2N) procedure is called cross-check and it helps to eliminate some false matches.
|
||||
if( dtype == CV_32S )
|
||||
{
|
||||
for( int i = 0; i < tdist.rows; i++ )
|
||||
@ -336,6 +338,13 @@ void cv::batchDistance( InputArray _src1, InputArray _src2,
|
||||
}
|
||||
}
|
||||
}
|
||||
for( int i = 0; i < sdist.rows; i++ )
|
||||
{
|
||||
if( tidx.at<int>(sidx.at<int>(i)) != i )
|
||||
{
|
||||
nidx.at<int>(i) = -1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1183,9 +1183,9 @@ void cv::copyMakeBorder( InputArray _src, OutputArray _dst, int top, int bottom,
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
CV_Assert( top >= 0 && bottom >= 0 && left >= 0 && right >= 0 );
|
||||
CV_Assert( top >= 0 && bottom >= 0 && left >= 0 && right >= 0 && _src.dims() <= 2);
|
||||
|
||||
CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2,
|
||||
CV_OCL_RUN(_dst.isUMat(),
|
||||
ocl_copyMakeBorder(_src, _dst, top, bottom, left, right, borderType, value))
|
||||
|
||||
Mat src = _src.getMat();
|
||||
|
@ -1699,7 +1699,7 @@ transform_( const T* src, T* dst, const WT* m, int len, int scn, int dcn )
|
||||
}
|
||||
}
|
||||
|
||||
#if CV_SIMD128
|
||||
#if CV_SIMD128 && !defined(__aarch64__)
|
||||
static inline void
|
||||
load3x3Matrix(const float* m, v_float32x4& m0, v_float32x4& m1, v_float32x4& m2, v_float32x4& m3)
|
||||
{
|
||||
@ -1708,7 +1708,9 @@ load3x3Matrix(const float* m, v_float32x4& m0, v_float32x4& m1, v_float32x4& m2,
|
||||
m2 = v_float32x4(m[2], m[6], m[10], 0);
|
||||
m3 = v_float32x4(m[3], m[7], m[11], 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CV_SIMD128
|
||||
static inline v_int16x8
|
||||
v_matmulvec(const v_int16x8 &v0, const v_int16x8 &m0, const v_int16x8 &m1, const v_int16x8 &m2, const v_int32x4 &m3, const int BITS)
|
||||
{
|
||||
|
398
modules/core/src/utils/datafile.cpp
Normal file
398
modules/core/src/utils/datafile.cpp
Normal file
@ -0,0 +1,398 @@
|
||||
// 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 "../precomp.hpp"
|
||||
|
||||
#include "opencv_data_config.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
#include <opencv2/core/utils/logger.defines.hpp>
|
||||
#undef CV_LOG_STRIP_LEVEL
|
||||
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE + 1
|
||||
#include "opencv2/core/utils/logger.hpp"
|
||||
#include "opencv2/core/utils/filesystem.hpp"
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef small
|
||||
#undef min
|
||||
#undef max
|
||||
#undef abs
|
||||
#elif defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_MAC
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace cv { namespace utils {
|
||||
|
||||
static cv::Ptr< std::vector<cv::String> > g_data_search_path;
|
||||
static cv::Ptr< std::vector<cv::String> > g_data_search_subdir;
|
||||
|
||||
static std::vector<cv::String>& _getDataSearchPath()
|
||||
{
|
||||
if (g_data_search_path.empty())
|
||||
g_data_search_path.reset(new std::vector<cv::String>());
|
||||
return *(g_data_search_path.get());
|
||||
}
|
||||
|
||||
static std::vector<cv::String>& _getDataSearchSubDirectory()
|
||||
{
|
||||
if (g_data_search_subdir.empty())
|
||||
{
|
||||
g_data_search_subdir.reset(new std::vector<cv::String>());
|
||||
g_data_search_subdir->push_back("data");
|
||||
g_data_search_subdir->push_back("");
|
||||
}
|
||||
return *(g_data_search_subdir.get());
|
||||
}
|
||||
|
||||
|
||||
CV_EXPORTS void addDataSearchPath(const cv::String& path)
|
||||
{
|
||||
if (utils::fs::isDirectory(path))
|
||||
_getDataSearchPath().push_back(path);
|
||||
}
|
||||
CV_EXPORTS void addDataSearchSubDirectory(const cv::String& subdir)
|
||||
{
|
||||
_getDataSearchSubDirectory().push_back(subdir);
|
||||
}
|
||||
|
||||
static bool isPathSep(char c)
|
||||
{
|
||||
return c == '/' || c == '\\';
|
||||
}
|
||||
static bool isSubDirectory_(const cv::String& base_path, const cv::String& path)
|
||||
{
|
||||
size_t N = base_path.size();
|
||||
if (N == 0)
|
||||
return false;
|
||||
if (isPathSep(base_path[N - 1]))
|
||||
N--;
|
||||
if (path.size() < N)
|
||||
return false;
|
||||
for (size_t i = 0; i < N; i++)
|
||||
{
|
||||
if (path[i] == base_path[i])
|
||||
continue;
|
||||
if (isPathSep(path[i]) && isPathSep(base_path[i]))
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
size_t M = path.size();
|
||||
if (M > N)
|
||||
{
|
||||
if (!isPathSep(path[N]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static bool isSubDirectory(const cv::String& base_path, const cv::String& path)
|
||||
{
|
||||
bool res = isSubDirectory_(base_path, path);
|
||||
CV_LOG_VERBOSE(NULL, 0, "isSubDirectory(): base: " << base_path << " path: " << path << " => result: " << (res ? "TRUE" : "FALSE"));
|
||||
return res;
|
||||
}
|
||||
|
||||
static cv::String getModuleLocation(const void* addr)
|
||||
{
|
||||
CV_UNUSED(addr);
|
||||
#ifdef _WIN32
|
||||
HMODULE m = 0;
|
||||
#if _WIN32_WINNT >= 0x0501
|
||||
::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPCTSTR>(addr),
|
||||
&m);
|
||||
#endif
|
||||
if (m)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
const size_t path_size = sizeof(path)/sizeof(*path);
|
||||
size_t sz = GetModuleFileNameA(m, path, path_size); // no unicode support
|
||||
if (sz > 0 && sz < path_size)
|
||||
{
|
||||
path[sz] = '\0';
|
||||
return cv::String(path);
|
||||
}
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
std::ifstream fs("/proc/self/maps");
|
||||
std::string line;
|
||||
while (std::getline(fs, line, '\n'))
|
||||
{
|
||||
long long int addr_begin = 0, addr_end = 0;
|
||||
if (2 == sscanf(line.c_str(), "%llx-%llx", &addr_begin, &addr_end))
|
||||
{
|
||||
if ((intptr_t)addr >= (intptr_t)addr_begin && (intptr_t)addr < (intptr_t)addr_end)
|
||||
{
|
||||
size_t pos = line.rfind(" "); // 2 spaces
|
||||
if (pos == cv::String::npos)
|
||||
pos = line.rfind(' '); // 1 spaces
|
||||
else
|
||||
pos++;
|
||||
if (pos == cv::String::npos)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "Can't parse module path: '" << line << '\'');
|
||||
}
|
||||
return line.substr(pos + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
# if TARGET_OS_MAC
|
||||
Dl_info info;
|
||||
if (0 != dladdr(addr, &info))
|
||||
{
|
||||
return cv::String(info.dli_fname);
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
// not supported, skip
|
||||
#endif
|
||||
return cv::String();
|
||||
}
|
||||
|
||||
cv::String findDataFile(const cv::String& relative_path,
|
||||
const char* configuration_parameter,
|
||||
const std::vector<String>* search_paths,
|
||||
const std::vector<String>* subdir_paths)
|
||||
{
|
||||
configuration_parameter = configuration_parameter ? configuration_parameter : "OPENCV_DATA_PATH";
|
||||
CV_LOG_DEBUG(NULL, cv::format("utils::findDataFile('%s', %s)", relative_path.c_str(), configuration_parameter));
|
||||
|
||||
#define TRY_FILE_WITH_PREFIX(prefix) \
|
||||
{ \
|
||||
cv::String path = utils::fs::join(prefix, relative_path); \
|
||||
CV_LOG_DEBUG(NULL, cv::format("... Line %d: trying open '%s'", __LINE__, path.c_str())); \
|
||||
FILE* f = fopen(path.c_str(), "rb"); \
|
||||
if(f) { \
|
||||
fclose(f); \
|
||||
return path; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
// Step 0: check current directory or absolute path at first
|
||||
TRY_FILE_WITH_PREFIX("");
|
||||
|
||||
|
||||
// Step 1
|
||||
const std::vector<cv::String>& search_path = search_paths ? *search_paths : _getDataSearchPath();
|
||||
for(size_t i = search_path.size(); i > 0; i--)
|
||||
{
|
||||
const cv::String& prefix = search_path[i - 1];
|
||||
TRY_FILE_WITH_PREFIX(prefix);
|
||||
}
|
||||
|
||||
const std::vector<cv::String>& search_subdir = subdir_paths ? *subdir_paths : _getDataSearchSubDirectory();
|
||||
|
||||
|
||||
// Step 2
|
||||
const cv::String configuration_parameter_s(configuration_parameter ? configuration_parameter : "");
|
||||
const cv::utils::Paths& search_hint = configuration_parameter_s.empty() ? cv::utils::Paths()
|
||||
: getConfigurationParameterPaths((configuration_parameter_s + "_HINT").c_str());
|
||||
for (size_t k = 0; k < search_hint.size(); k++)
|
||||
{
|
||||
cv::String datapath = search_hint[k];
|
||||
if (datapath.empty())
|
||||
continue;
|
||||
if (utils::fs::isDirectory(datapath))
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): trying " << configuration_parameter << "_HINT=" << datapath);
|
||||
for(size_t i = search_subdir.size(); i > 0; i--)
|
||||
{
|
||||
const cv::String& subdir = search_subdir[i - 1];
|
||||
cv::String prefix = utils::fs::join(datapath, subdir);
|
||||
TRY_FILE_WITH_PREFIX(prefix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_LOG_WARNING(NULL, configuration_parameter << "_HINT is specified but it is not a directory: " << datapath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Step 3
|
||||
const cv::utils::Paths& override_paths = configuration_parameter_s.empty() ? cv::utils::Paths()
|
||||
: getConfigurationParameterPaths(configuration_parameter);
|
||||
for (size_t k = 0; k < override_paths.size(); k++)
|
||||
{
|
||||
cv::String datapath = override_paths[k];
|
||||
if (datapath.empty())
|
||||
continue;
|
||||
if (utils::fs::isDirectory(datapath))
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): trying " << configuration_parameter << "=" << datapath);
|
||||
for(size_t i = search_subdir.size(); i > 0; i--)
|
||||
{
|
||||
const cv::String& subdir = search_subdir[i - 1];
|
||||
cv::String prefix = utils::fs::join(datapath, subdir);
|
||||
TRY_FILE_WITH_PREFIX(prefix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_LOG_WARNING(NULL, configuration_parameter << " is specified but it is not a directory: " << datapath);
|
||||
}
|
||||
}
|
||||
if (!override_paths.empty())
|
||||
{
|
||||
CV_LOG_INFO(NULL, "utils::findDataFile(): can't find data file via " << configuration_parameter << " configuration override: " << relative_path);
|
||||
return cv::String();
|
||||
}
|
||||
|
||||
|
||||
// Steps: 4, 5, 6
|
||||
cv::String cwd = utils::fs::getcwd();
|
||||
cv::String build_dir(OPENCV_BUILD_DIR);
|
||||
bool has_tested_build_directory = false;
|
||||
if (isSubDirectory(build_dir, cwd) || isSubDirectory(utils::fs::canonical(build_dir), utils::fs::canonical(cwd)))
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): the current directory is build sub-directory: " << cwd);
|
||||
const char* build_subdirs[] = { OPENCV_DATA_BUILD_DIR_SEARCH_PATHS };
|
||||
for (size_t k = 0; k < sizeof(build_subdirs)/sizeof(build_subdirs[0]); k++)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): <build>/" << build_subdirs[k]);
|
||||
cv::String datapath = utils::fs::join(build_dir, build_subdirs[k]);
|
||||
if (utils::fs::isDirectory(datapath))
|
||||
{
|
||||
for(size_t i = search_subdir.size(); i > 0; i--)
|
||||
{
|
||||
const cv::String& subdir = search_subdir[i - 1];
|
||||
cv::String prefix = utils::fs::join(datapath, subdir);
|
||||
TRY_FILE_WITH_PREFIX(prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
has_tested_build_directory = true;
|
||||
}
|
||||
|
||||
cv::String source_dir;
|
||||
cv::String try_source_dir = cwd;
|
||||
for (int levels = 0; levels < 3; ++levels)
|
||||
{
|
||||
if (utils::fs::exists(utils::fs::join(try_source_dir, "modules/core/include/opencv2/core/version.hpp")))
|
||||
{
|
||||
source_dir = try_source_dir;
|
||||
break;
|
||||
}
|
||||
try_source_dir = utils::fs::join(try_source_dir, "/..");
|
||||
}
|
||||
if (!source_dir.empty())
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): the current directory is source sub-directory: " << source_dir);
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): <source>" << source_dir);
|
||||
cv::String datapath = source_dir;
|
||||
if (utils::fs::isDirectory(datapath))
|
||||
{
|
||||
for(size_t i = search_subdir.size(); i > 0; i--)
|
||||
{
|
||||
const cv::String& subdir = search_subdir[i - 1];
|
||||
cv::String prefix = utils::fs::join(datapath, subdir);
|
||||
TRY_FILE_WITH_PREFIX(prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cv::String module_path = getModuleLocation((void*)getModuleLocation); // use code addr, doesn't work with static linkage!
|
||||
CV_LOG_DEBUG(NULL, "Detected module path: '" << module_path << '\'');
|
||||
|
||||
if (!has_tested_build_directory &&
|
||||
(isSubDirectory(build_dir, module_path) || isSubDirectory(utils::fs::canonical(build_dir), utils::fs::canonical(module_path)))
|
||||
)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): the binary module directory is build sub-directory: " << module_path);
|
||||
const char* build_subdirs[] = { OPENCV_DATA_BUILD_DIR_SEARCH_PATHS };
|
||||
for (size_t k = 0; k < sizeof(build_subdirs)/sizeof(build_subdirs[0]); k++)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): <build>/" << build_subdirs[k]);
|
||||
cv::String datapath = utils::fs::join(build_dir, build_subdirs[k]);
|
||||
if (utils::fs::isDirectory(datapath))
|
||||
{
|
||||
for(size_t i = search_subdir.size(); i > 0; i--)
|
||||
{
|
||||
const cv::String& subdir = search_subdir[i - 1];
|
||||
cv::String prefix = utils::fs::join(datapath, subdir);
|
||||
TRY_FILE_WITH_PREFIX(prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined OPENCV_INSTALL_DATA_DIR_RELATIVE
|
||||
if (!module_path.empty()) // require module path
|
||||
{
|
||||
size_t pos = module_path.rfind('/');
|
||||
if (pos == cv::String::npos)
|
||||
pos = module_path.rfind('\\');
|
||||
cv::String module_dir = (pos == cv::String::npos) ? module_path : module_path.substr(0, pos);
|
||||
const char* install_subdirs[] = { OPENCV_INSTALL_DATA_DIR_RELATIVE };
|
||||
for (size_t k = 0; k < sizeof(install_subdirs)/sizeof(install_subdirs[0]); k++)
|
||||
{
|
||||
cv::String datapath = utils::fs::join(module_dir, install_subdirs[k]);
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): trying install path (from binary path): " << datapath);
|
||||
if (utils::fs::isDirectory(datapath))
|
||||
{
|
||||
for(size_t i = search_subdir.size(); i > 0; i--)
|
||||
{
|
||||
const cv::String& subdir = search_subdir[i - 1];
|
||||
cv::String prefix = utils::fs::join(datapath, subdir);
|
||||
TRY_FILE_WITH_PREFIX(prefix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): ... skip, not a valid directory: " << datapath);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined OPENCV_INSTALL_PREFIX && defined OPENCV_DATA_INSTALL_PATH
|
||||
cv::String install_dir(OPENCV_INSTALL_PREFIX);
|
||||
// use core/world module path and verify that library is running from installation directory
|
||||
// It is neccessary to avoid touching of unrelated common /usr/local path
|
||||
if (module_path.empty()) // can't determine
|
||||
module_path = install_dir;
|
||||
if (isSubDirectory(install_dir, module_path) || isSubDirectory(utils::fs::canonical(install_dir), utils::fs::canonical(module_path)))
|
||||
{
|
||||
cv::String datapath = utils::fs::join(install_dir, OPENCV_DATA_INSTALL_PATH);
|
||||
if (utils::fs::isDirectory(datapath))
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "utils::findDataFile(): trying install path: " << datapath);
|
||||
for(size_t i = search_subdir.size(); i > 0; i--)
|
||||
{
|
||||
const cv::String& subdir = search_subdir[i - 1];
|
||||
cv::String prefix = utils::fs::join(datapath, subdir);
|
||||
TRY_FILE_WITH_PREFIX(prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return cv::String(); // not found
|
||||
}
|
||||
|
||||
cv::String findDataFile(const cv::String& relative_path, bool required, const char* configuration_parameter)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, cv::format("cv::utils::findDataFile('%s', %s, %s)",
|
||||
relative_path.c_str(), required ? "true" : "false",
|
||||
configuration_parameter ? configuration_parameter : "NULL"));
|
||||
cv::String result = cv::utils::findDataFile(relative_path,
|
||||
configuration_parameter,
|
||||
NULL,
|
||||
NULL);
|
||||
if (result.empty() && required)
|
||||
CV_Error(cv::Error::StsError, cv::format("OpenCV: Can't find required data file: %s", relative_path.c_str()));
|
||||
return result;
|
||||
}
|
||||
|
||||
}} // namespace
|
@ -85,6 +85,23 @@ cv::String join(const cv::String& base, const cv::String& path)
|
||||
|
||||
#if OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||
|
||||
cv::String canonical(const cv::String& path)
|
||||
{
|
||||
cv::String result;
|
||||
#ifdef _WIN32
|
||||
const char* result_str = _fullpath(NULL, path.c_str(), 0);
|
||||
#else
|
||||
const char* result_str = realpath(path.c_str(), NULL);
|
||||
#endif
|
||||
if (result_str)
|
||||
{
|
||||
result = cv::String(result_str);
|
||||
free((void*)result_str);
|
||||
}
|
||||
return result.empty() ? path : result;
|
||||
}
|
||||
|
||||
|
||||
bool exists(const cv::String& path)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@ -543,11 +560,12 @@ cv::String getCacheDirectory(const char* sub_directory_name, const char* configu
|
||||
|
||||
#else
|
||||
#define NOT_IMPLEMENTED CV_Error(Error::StsNotImplemented, "");
|
||||
CV_EXPORTS bool exists(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
CV_EXPORTS void remove_all(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
CV_EXPORTS bool createDirectory(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
CV_EXPORTS bool createDirectories(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
CV_EXPORTS cv::String getCacheDirectory(const char* /*sub_directory_name*/, const char* /*configuration_name = NULL*/) { NOT_IMPLEMENTED }
|
||||
cv::String canonical(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
bool exists(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
void remove_all(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
bool createDirectory(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
bool createDirectories(const cv::String& /*path*/) { NOT_IMPLEMENTED }
|
||||
cv::String getCacheDirectory(const char* /*sub_directory_name*/, const char* /*configuration_name = NULL*/) { NOT_IMPLEMENTED }
|
||||
#undef NOT_IMPLEMENTED
|
||||
#endif // OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||
|
||||
|
67
modules/core/src/utils/samples.cpp
Normal file
67
modules/core/src/utils/samples.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
// 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 "../precomp.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <opencv2/core/utils/logger.defines.hpp>
|
||||
#undef CV_LOG_STRIP_LEVEL
|
||||
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE + 1
|
||||
#include "opencv2/core/utils/logger.hpp"
|
||||
#include "opencv2/core/utils/filesystem.hpp"
|
||||
|
||||
namespace cv { namespace samples {
|
||||
|
||||
static cv::Ptr< std::vector<cv::String> > g_data_search_path;
|
||||
static cv::Ptr< std::vector<cv::String> > g_data_search_subdir;
|
||||
|
||||
static std::vector<cv::String>& _getDataSearchPath()
|
||||
{
|
||||
if (g_data_search_path.empty())
|
||||
g_data_search_path.reset(new std::vector<cv::String>());
|
||||
return *(g_data_search_path.get());
|
||||
}
|
||||
|
||||
static std::vector<cv::String>& _getDataSearchSubDirectory()
|
||||
{
|
||||
if (g_data_search_subdir.empty())
|
||||
{
|
||||
g_data_search_subdir.reset(new std::vector<cv::String>());
|
||||
g_data_search_subdir->push_back("samples/data");
|
||||
g_data_search_subdir->push_back("data");
|
||||
g_data_search_subdir->push_back("");
|
||||
}
|
||||
return *(g_data_search_subdir.get());
|
||||
}
|
||||
|
||||
|
||||
CV_EXPORTS void addSamplesDataSearchPath(const cv::String& path)
|
||||
{
|
||||
if (utils::fs::isDirectory(path))
|
||||
_getDataSearchPath().push_back(path);
|
||||
}
|
||||
CV_EXPORTS void addSamplesDataSearchSubDirectory(const cv::String& subdir)
|
||||
{
|
||||
_getDataSearchSubDirectory().push_back(subdir);
|
||||
}
|
||||
|
||||
cv::String findFile(const cv::String& relative_path, bool required, bool silentMode)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, cv::format("cv::samples::findFile('%s', %s)", relative_path.c_str(), required ? "true" : "false"));
|
||||
cv::String result = cv::utils::findDataFile(relative_path,
|
||||
"OPENCV_SAMPLES_DATA_PATH",
|
||||
&_getDataSearchPath(),
|
||||
&_getDataSearchSubDirectory());
|
||||
if (result != relative_path && !silentMode)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "cv::samples::findFile('" << relative_path << "') => '" << result << "'");
|
||||
}
|
||||
if (result.empty() && required)
|
||||
CV_Error(cv::Error::StsError, cv::format("OpenCV samples: Can't find required data file: %s", relative_path.c_str()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}} // namespace
|
@ -2,6 +2,7 @@
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/core/utils/logger.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
@ -283,4 +284,21 @@ TEST(CommandLineParser, testScalar)
|
||||
EXPECT_EQ(parser.get<Scalar>("s5"), Scalar(5, -4, 3, 2));
|
||||
}
|
||||
|
||||
TEST(Samples, findFile)
|
||||
{
|
||||
cv::utils::logging::LogLevel prev = cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_VERBOSE);
|
||||
cv::String path;
|
||||
ASSERT_NO_THROW(path = samples::findFile("lena.jpg", false));
|
||||
EXPECT_NE(std::string(), path.c_str());
|
||||
cv::utils::logging::setLogLevel(prev);
|
||||
}
|
||||
|
||||
TEST(Samples, findFile_missing)
|
||||
{
|
||||
cv::utils::logging::LogLevel prev = cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_VERBOSE);
|
||||
cv::String path;
|
||||
ASSERT_ANY_THROW(path = samples::findFile("non-existed.file", true));
|
||||
cv::utils::logging::setLogLevel(prev);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
@ -20,11 +20,6 @@ else()
|
||||
ocv_cmake_hook_append(INIT_MODULE_SOURCES_opencv_dnn "${CMAKE_CURRENT_LIST_DIR}/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake")
|
||||
endif()
|
||||
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-shadow -Wno-parentheses -Wmaybe-uninitialized -Wsign-promo
|
||||
-Wmissing-declarations -Wmissing-prototypes
|
||||
)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4701 /wd4100)
|
||||
|
||||
if(MSVC)
|
||||
add_definitions( -D_CRT_SECURE_NO_WARNINGS=1 )
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146
|
||||
@ -33,12 +28,14 @@ if(MSVC)
|
||||
)
|
||||
else()
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated -Wmissing-prototypes -Wmissing-declarations -Wshadow
|
||||
-Wunused-parameter -Wunused-local-typedefs -Wsign-compare -Wsign-promo
|
||||
-Wundef -Wtautological-undefined-compare -Wignored-qualifiers -Wextra
|
||||
-Wunused-function -Wunused-const-variable -Wdeprecated-declarations
|
||||
-Wunused-parameter -Wsign-compare
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_CXX11)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-undef) # LANG_CXX11 from protobuf files
|
||||
endif()
|
||||
|
||||
if(APPLE_FRAMEWORK)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshorten-64-to-32)
|
||||
endif()
|
||||
@ -55,8 +52,6 @@ add_definitions(-DHAVE_PROTOBUF=1)
|
||||
|
||||
#suppress warnings in autogenerated caffe.pb.* files
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS
|
||||
-Wunused-parameter -Wundef -Wignored-qualifiers -Wno-enum-compare
|
||||
-Wdeprecated-declarations
|
||||
/wd4125 /wd4267 /wd4127 /wd4244 /wd4512 /wd4702
|
||||
/wd4456 /wd4510 /wd4610 /wd4800
|
||||
/wd4701 /wd4703 # potentially uninitialized local/pointer variable 'value' used
|
||||
|
@ -236,7 +236,7 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
int type;
|
||||
Size kernel, stride;
|
||||
int pad_l, pad_t, pad_r, pad_b;
|
||||
CV_DEPRECATED Size pad;
|
||||
CV_DEPRECATED_EXTERNAL Size pad;
|
||||
bool globalPooling;
|
||||
bool computeMaxIdx;
|
||||
String padMode;
|
||||
@ -578,7 +578,7 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
{
|
||||
public:
|
||||
float pnorm, epsilon;
|
||||
CV_DEPRECATED bool acrossSpatial;
|
||||
CV_DEPRECATED_EXTERNAL bool acrossSpatial;
|
||||
|
||||
static Ptr<NormalizeBBoxLayer> create(const LayerParams& params);
|
||||
};
|
||||
|
@ -60,6 +60,7 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
struct CV_EXPORTS_W DictValue
|
||||
{
|
||||
DictValue(const DictValue &r);
|
||||
DictValue(bool i) : type(Param::INT), pi(new AutoBuffer<int64,1>) { (*pi)[0] = i ? 1 : 0; } //!< Constructs integer scalar
|
||||
DictValue(int64 i = 0) : type(Param::INT), pi(new AutoBuffer<int64,1>) { (*pi)[0] = i; } //!< Constructs integer scalar
|
||||
CV_WRAP DictValue(int i) : type(Param::INT), pi(new AutoBuffer<int64,1>) { (*pi)[0] = i; } //!< Constructs integer scalar
|
||||
DictValue(unsigned p) : type(Param::INT), pi(new AutoBuffer<int64,1>) { (*pi)[0] = p; } //!< Constructs integer scalar
|
||||
|
@ -181,7 +181,8 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
* If this method is called after network has allocated all memory for input and output blobs
|
||||
* and before inferencing.
|
||||
*/
|
||||
CV_DEPRECATED virtual void finalize(const std::vector<Mat*> &input, std::vector<Mat> &output);
|
||||
CV_DEPRECATED_EXTERNAL
|
||||
virtual void finalize(const std::vector<Mat*> &input, std::vector<Mat> &output);
|
||||
|
||||
/** @brief Computes and sets internal parameters according to inputs, outputs and blobs.
|
||||
* @param[in] inputs vector of already allocated input blobs
|
||||
@ -198,7 +199,8 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
* @param[out] output allocated output blobs, which will store results of the computation.
|
||||
* @param[out] internals allocated internal blobs
|
||||
*/
|
||||
CV_DEPRECATED virtual void forward(std::vector<Mat*> &input, std::vector<Mat> &output, std::vector<Mat> &internals);
|
||||
CV_DEPRECATED_EXTERNAL
|
||||
virtual void forward(std::vector<Mat*> &input, std::vector<Mat> &output, std::vector<Mat> &internals);
|
||||
|
||||
/** @brief Given the @p input blobs, computes the output @p blobs.
|
||||
* @param[in] inputs the input blobs.
|
||||
@ -218,7 +220,8 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
* @overload
|
||||
* @deprecated Use Layer::finalize(InputArrayOfArrays, OutputArrayOfArrays) instead
|
||||
*/
|
||||
CV_DEPRECATED void finalize(const std::vector<Mat> &inputs, CV_OUT std::vector<Mat> &outputs);
|
||||
CV_DEPRECATED_EXTERNAL
|
||||
void finalize(const std::vector<Mat> &inputs, CV_OUT std::vector<Mat> &outputs);
|
||||
|
||||
/** @brief
|
||||
* @overload
|
||||
|
@ -175,8 +175,7 @@ PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
|
||||
PERF_TEST_P_(DNNTestNetwork, DenseNet_121)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL_FP16 ||
|
||||
target == DNN_TARGET_MYRIAD))
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)))
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/DenseNet_121.caffemodel", "dnn/DenseNet_121.prototxt", "",
|
||||
Mat(cv::Size(224, 224), CV_32FC3));
|
||||
@ -185,7 +184,7 @@ PERF_TEST_P_(DNNTestNetwork, DenseNet_121)
|
||||
PERF_TEST_P_(DNNTestNetwork, OpenPose_pose_coco)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/openpose_pose_coco.caffemodel", "dnn/openpose_pose_coco.prototxt", "",
|
||||
Mat(cv::Size(368, 368), CV_32FC3));
|
||||
@ -194,7 +193,7 @@ PERF_TEST_P_(DNNTestNetwork, OpenPose_pose_coco)
|
||||
PERF_TEST_P_(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt", "",
|
||||
Mat(cv::Size(368, 368), CV_32FC3));
|
||||
@ -203,7 +202,7 @@ PERF_TEST_P_(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
PERF_TEST_P_(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
// The same .caffemodel but modified .prototxt
|
||||
// See https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/src/openpose/pose/poseParameters.cpp
|
||||
@ -230,7 +229,7 @@ PERF_TEST_P_(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
PERF_TEST_P_(DNNTestNetwork, YOLOv3)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/dog416.png", false));
|
||||
Mat inp;
|
||||
@ -241,7 +240,7 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv3)
|
||||
PERF_TEST_P_(DNNTestNetwork, EAST_text_detection)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/frozen_east_text_detection.pb", "", "", Mat(cv::Size(320, 320), CV_32FC3));
|
||||
}
|
||||
|
@ -404,7 +404,7 @@ bool UpgradeV0LayerParameter(V1LayerParameter* v0_layer_connection_,
|
||||
PoolingParameter_PoolMethod_STOCHASTIC);
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Unknown pool method " << pool;
|
||||
LOG(ERROR) << "Unknown pool method " << (int)pool;
|
||||
is_fully_compatible = false;
|
||||
}
|
||||
} else {
|
||||
@ -863,7 +863,7 @@ bool UpgradeV1LayerParameter(V1LayerParameter* v1_layer_param_,
|
||||
while (layer_param->param_size() <= i) { layer_param->add_param(); }
|
||||
layer_param->mutable_param(i)->set_name(v1_layer_param.param(i));
|
||||
}
|
||||
ParamSpec_DimCheckMode mode;
|
||||
ParamSpec_DimCheckMode mode = ParamSpec_DimCheckMode_STRICT;
|
||||
for (int i = 0; i < v1_layer_param.blob_share_mode_size(); ++i) {
|
||||
while (layer_param->param_size() <= i) { layer_param->add_param(); }
|
||||
switch (v1_layer_param.blob_share_mode(i)) {
|
||||
@ -875,8 +875,8 @@ bool UpgradeV1LayerParameter(V1LayerParameter* v1_layer_param_,
|
||||
break;
|
||||
default:
|
||||
LOG(FATAL) << "Unknown blob_share_mode: "
|
||||
<< v1_layer_param.blob_share_mode(i);
|
||||
break;
|
||||
<< (int)v1_layer_param.blob_share_mode(i);
|
||||
CV_Error_(Error::StsError, ("Unknown blob_share_mode: %d", (int)v1_layer_param.blob_share_mode(i)));
|
||||
}
|
||||
layer_param->mutable_param(i)->set_share_mode(mode);
|
||||
}
|
||||
@ -1102,12 +1102,12 @@ const char* UpgradeV1LayerType(const V1LayerParameter_LayerType type) {
|
||||
case V1LayerParameter_LayerType_THRESHOLD:
|
||||
return "Threshold";
|
||||
default:
|
||||
LOG(FATAL) << "Unknown V1LayerParameter layer type: " << type;
|
||||
LOG(FATAL) << "Unknown V1LayerParameter layer type: " << (int)type;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
const int kProtoReadBytesLimit = INT_MAX; // Max size of 2 GB minus 1 byte.
|
||||
static const int kProtoReadBytesLimit = INT_MAX; // Max size of 2 GB minus 1 byte.
|
||||
|
||||
bool ReadProtoFromBinary(ZeroCopyInputStream* input, Message *proto) {
|
||||
CodedInputStream coded_input(input);
|
||||
|
@ -353,7 +353,7 @@ struct LayerPin
|
||||
|
||||
bool operator<(const LayerPin &r) const
|
||||
{
|
||||
return lid < r.lid || lid == r.lid && oid < r.oid;
|
||||
return lid < r.lid || (lid == r.lid && oid < r.oid);
|
||||
}
|
||||
|
||||
bool operator ==(const LayerPin &r) const
|
||||
@ -428,7 +428,7 @@ struct DataLayer : public Layer
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && inputsData.size() == 1;
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && inputsData.size() == 1);
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
|
||||
@ -1665,6 +1665,23 @@ struct Net::Impl
|
||||
|
||||
if (!ieNode->net->isInitialized())
|
||||
{
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R3)
|
||||
// For networks which is built in runtime we need to specify a
|
||||
// version of it's hyperparameters.
|
||||
std::string versionTrigger = "<net name=\"TestInput\" version=\"3\" batch=\"1\">"
|
||||
"<layers>"
|
||||
"<layer name=\"data\" type=\"Input\" precision=\"FP32\" id=\"0\">"
|
||||
"<output>"
|
||||
"<port id=\"0\">"
|
||||
"<dim>1</dim>"
|
||||
"</port>"
|
||||
"</output>"
|
||||
"</layer>"
|
||||
"</layers>"
|
||||
"</net>";
|
||||
InferenceEngine::CNNNetReader reader;
|
||||
reader.ReadNetwork(versionTrigger.data(), versionTrigger.size());
|
||||
#endif
|
||||
ieNode->net->init(preferableTarget);
|
||||
ld.skip = false;
|
||||
}
|
||||
@ -1787,8 +1804,8 @@ struct Net::Impl
|
||||
|
||||
void fuseLayers(const std::vector<LayerPin>& blobsToKeep_)
|
||||
{
|
||||
if( !fusion || preferableBackend != DNN_BACKEND_OPENCV &&
|
||||
preferableBackend != DNN_BACKEND_INFERENCE_ENGINE)
|
||||
if( !fusion || (preferableBackend != DNN_BACKEND_OPENCV &&
|
||||
preferableBackend != DNN_BACKEND_INFERENCE_ENGINE))
|
||||
return;
|
||||
|
||||
CV_TRACE_FUNCTION();
|
||||
|
@ -151,8 +151,8 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine();
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide()) ||
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine());
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine();
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine());
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
@ -107,14 +107,21 @@ public:
|
||||
inputs[i].copyTo(outputs[i]);
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> >&) CV_OVERRIDE
|
||||
virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> >& inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
InferenceEngine::DataPtr input = infEngineDataNode(inputs[0]);
|
||||
CV_Assert(!input->dims.empty());
|
||||
|
||||
InferenceEngine::LayerParams lp;
|
||||
lp.name = name;
|
||||
lp.type = "Split";
|
||||
lp.precision = InferenceEngine::Precision::FP32;
|
||||
std::shared_ptr<InferenceEngine::SplitLayer> ieLayer(new InferenceEngine::SplitLayer(lp));
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R3)
|
||||
ieLayer->params["axis"] = format("%d", input->dims.size() - 1);
|
||||
ieLayer->params["out_sizes"] = format("%d", input->dims[0]);
|
||||
#endif
|
||||
return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
|
||||
#endif // HAVE_INF_ENGINE
|
||||
return Ptr<BackendNode>();
|
||||
|
@ -105,9 +105,9 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() && axis == 1 && !padding || // By channels
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && !padding ||
|
||||
backendId == DNN_BACKEND_VKCOM && haveVulkan() && !padding;
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && axis == 1 && !padding) || // By channels
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && !padding) ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan() && !padding);
|
||||
}
|
||||
|
||||
class ChannelConcatInvoker : public ParallelLoopBody
|
||||
|
@ -225,7 +225,7 @@ public:
|
||||
else
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_VKCOM && haveVulkan();
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan());
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
@ -530,6 +530,12 @@ public:
|
||||
ieLayer->_pads_end.insert(InferenceEngine::Y_AXIS, pad.height);
|
||||
ieLayer->_dilation.insert(InferenceEngine::X_AXIS, dilation.width);
|
||||
ieLayer->_dilation.insert(InferenceEngine::Y_AXIS, dilation.height);
|
||||
ieLayer->params["output"] = format("%d", outCn);
|
||||
ieLayer->params["kernel"] = format("%d,%d,%d,%d", outCn, inpGroupCn, kernel.height, kernel.width);
|
||||
ieLayer->params["pads_begin"] = format("%d,%d", pad.height, pad.width);
|
||||
ieLayer->params["pads_end"] = format("%d,%d", pad.height, pad.width);
|
||||
ieLayer->params["strides"] = format("%d,%d", stride.height, stride.width);
|
||||
ieLayer->params["dilations"] = format("%d,%d", dilation.height, dilation.width);
|
||||
#else
|
||||
ieLayer->_kernel_x = kernel.width;
|
||||
ieLayer->_kernel_y = kernel.height;
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && crop_ranges.size() == 4;
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && crop_ranges.size() == 4);
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
@ -156,6 +156,14 @@ public:
|
||||
|
||||
CV_Assert(crop_ranges.size() == 4);
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R3)
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
ieLayer->axis.push_back(i);
|
||||
ieLayer->offset.push_back(crop_ranges[i].start);
|
||||
ieLayer->dim.push_back(crop_ranges[i].end - crop_ranges[i].start);
|
||||
}
|
||||
#else
|
||||
ieLayer->axis.push_back(0); // batch
|
||||
ieLayer->offset.push_back(crop_ranges[0].start);
|
||||
ieLayer->dim.push_back(crop_ranges[0].end - crop_ranges[0].start);
|
||||
@ -171,7 +179,7 @@ public:
|
||||
ieLayer->axis.push_back(2); // width
|
||||
ieLayer->offset.push_back(crop_ranges[3].start);
|
||||
ieLayer->dim.push_back(crop_ranges[3].end - crop_ranges[3].start);
|
||||
|
||||
#endif
|
||||
return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
|
||||
#endif // HAVE_INF_ENGINE
|
||||
return Ptr<BackendNode>();
|
||||
|
@ -198,7 +198,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && !_locPredTransposed && _bboxesNormalized && !_clip;
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && !_locPredTransposed && _bboxesNormalized && !_clip);
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && (op != SUM || coeffs.empty());
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && (op != SUM || coeffs.empty()));
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine();
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine());
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -123,8 +123,8 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() && axis == 1 ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && axis == 1;
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && axis == 1) ||
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && axis == 1);
|
||||
}
|
||||
|
||||
virtual bool setActivation(const Ptr<ActivationLayer>& layer) CV_OVERRIDE
|
||||
@ -449,6 +449,9 @@ public:
|
||||
std::shared_ptr<InferenceEngine::FullyConnectedLayer> ieLayer(new InferenceEngine::FullyConnectedLayer(lp));
|
||||
|
||||
ieLayer->_out_num = blobs[0].size[0];
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R3)
|
||||
ieLayer->params["out-size"] = format("%d", blobs[0].size[0]);
|
||||
#endif
|
||||
ieLayer->_weights = wrapToInfEngineBlob(blobs[0], {(size_t)blobs[0].size[0], (size_t)blobs[0].size[1], 1, 1}, InferenceEngine::Layout::OIHW);
|
||||
if (blobs.size() > 1)
|
||||
ieLayer->_biases = wrapToInfEngineBlob(blobs[1], {(size_t)ieLayer->_out_num}, InferenceEngine::Layout::C);
|
||||
|
@ -93,8 +93,8 @@ public:
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && (preferableTarget != DNN_TARGET_MYRIAD || type == CHANNEL_NRM) ||
|
||||
backendId == DNN_BACKEND_VKCOM && haveVulkan() && (size % 2 == 1) && (type == CHANNEL_NRM);
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && (preferableTarget != DNN_TARGET_MYRIAD || type == CHANNEL_NRM)) ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan() && (size % 2 == 1) && (type == CHANNEL_NRM));
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
@ -35,8 +35,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() &&
|
||||
!poolPad.width && !poolPad.height;
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && !poolPad.width && !poolPad.height);
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() && dstRanges.size() == 4;
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && dstRanges.size() == 4);
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
|
||||
|
@ -106,8 +106,8 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() ||
|
||||
backendId == DNN_BACKEND_VKCOM && haveVulkan();
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine()) ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan());
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -155,10 +155,10 @@ public:
|
||||
}
|
||||
else
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() &&
|
||||
(type == MAX || type == AVE && !pad_t && !pad_l && !pad_b && !pad_r) ||
|
||||
backendId == DNN_BACKEND_VKCOM && haveVulkan() &&
|
||||
(type == MAX || type == AVE);
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() &&
|
||||
(type == MAX || (type == AVE && !pad_t && !pad_l && !pad_b && !pad_r))) ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan() &&
|
||||
(type == MAX || type == AVE));
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
@ -313,6 +313,10 @@ public:
|
||||
poolLayer->_padding.insert(InferenceEngine::Y_AXIS, pad_t);
|
||||
poolLayer->_pads_end.insert(InferenceEngine::X_AXIS, pad_r);
|
||||
poolLayer->_pads_end.insert(InferenceEngine::Y_AXIS, pad_b);
|
||||
poolLayer->params["kernel"] = format("%d,%d", kernel.height, kernel.width);
|
||||
poolLayer->params["pads_begin"] = format("%d,%d", pad_t, pad_l);
|
||||
poolLayer->params["pads_end"] = format("%d,%d", pad_b, pad_r);
|
||||
poolLayer->params["strides"] = format("%d,%d", stride.height, stride.width);
|
||||
#else
|
||||
poolLayer->_kernel_x = kernel.width;
|
||||
poolLayer->_kernel_y = kernel.height;
|
||||
@ -380,7 +384,7 @@ public:
|
||||
src.isContinuous(), dst.isContinuous(),
|
||||
src.type() == CV_32F, src.type() == dst.type(),
|
||||
src.dims == 4, dst.dims == 4,
|
||||
((poolingType == ROI || poolingType == PSROI) && dst.size[0] ==rois.size[0] || src.size[0] == dst.size[0]),
|
||||
(((poolingType == ROI || poolingType == PSROI) && dst.size[0] == rois.size[0]) || src.size[0] == dst.size[0]),
|
||||
poolingType == PSROI || src.size[1] == dst.size[1],
|
||||
(mask.empty() || (mask.type() == src.type() && mask.size == dst.size)));
|
||||
|
||||
|
@ -272,8 +272,8 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() ||
|
||||
backendId == DNN_BACKEND_VKCOM && haveVulkan();
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine()) ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan());
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -87,7 +87,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && preferableTarget != DNN_TARGET_MYRIAD;
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && preferableTarget != DNN_TARGET_MYRIAD);
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -175,7 +175,7 @@ public:
|
||||
std::vector<MatShape> &outputs,
|
||||
std::vector<MatShape> &internals) const CV_OVERRIDE
|
||||
{
|
||||
CV_Assert(!usePeephole && blobs.size() == 3 || usePeephole && blobs.size() == 6);
|
||||
CV_Assert((!usePeephole && blobs.size() == 3) || (usePeephole && blobs.size() == 6));
|
||||
CV_Assert(inputs.size() == 1);
|
||||
const MatShape& inp0 = inputs[0];
|
||||
|
||||
@ -221,7 +221,7 @@ public:
|
||||
std::vector<Mat> input;
|
||||
inputs_arr.getMatVector(input);
|
||||
|
||||
CV_Assert(!usePeephole && blobs.size() == 3 || usePeephole && blobs.size() == 6);
|
||||
CV_Assert((!usePeephole && blobs.size() == 3) || (usePeephole && blobs.size() == 6));
|
||||
CV_Assert(input.size() == 1);
|
||||
const Mat& inp0 = input[0];
|
||||
|
||||
|
@ -178,7 +178,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine();
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine());
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -51,9 +51,14 @@ public:
|
||||
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
return interpolation == "nearest" && preferableTarget != DNN_TARGET_MYRIAD;
|
||||
{
|
||||
return (interpolation == "nearest" && preferableTarget != DNN_TARGET_MYRIAD) ||
|
||||
(interpolation == "bilinear" && INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2018R4));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV;
|
||||
}
|
||||
|
||||
@ -160,15 +165,27 @@ public:
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
InferenceEngine::LayerParams lp;
|
||||
lp.name = name;
|
||||
lp.type = "Resample";
|
||||
lp.precision = InferenceEngine::Precision::FP32;
|
||||
|
||||
std::shared_ptr<InferenceEngine::CNNLayer> ieLayer(new InferenceEngine::CNNLayer(lp));
|
||||
std::shared_ptr<InferenceEngine::CNNLayer> ieLayer;
|
||||
if (interpolation == "nearest")
|
||||
{
|
||||
lp.type = "Resample";
|
||||
ieLayer = std::shared_ptr<InferenceEngine::CNNLayer>(new InferenceEngine::CNNLayer(lp));
|
||||
ieLayer->params["type"] = "caffe.ResampleParameter.NEAREST";
|
||||
ieLayer->params["antialias"] = "0";
|
||||
}
|
||||
else if (interpolation == "bilinear")
|
||||
{
|
||||
lp.type = "Interp";
|
||||
ieLayer = std::shared_ptr<InferenceEngine::CNNLayer>(new InferenceEngine::CNNLayer(lp));
|
||||
ieLayer->params["pad_beg"] = "0";
|
||||
ieLayer->params["pad_end"] = "0";
|
||||
ieLayer->params["align_corners"] = "0";
|
||||
}
|
||||
else
|
||||
CV_Error(Error::StsNotImplemented, "Unsupported interpolation: " + interpolation);
|
||||
ieLayer->params["width"] = cv::format("%d", outWidth);
|
||||
ieLayer->params["height"] = cv::format("%d", outHeight);
|
||||
|
||||
return Ptr<BackendNode>(new InfEngineBackendNode(ieLayer));
|
||||
#endif // HAVE_INF_ENGINE
|
||||
return Ptr<BackendNode>();
|
||||
|
@ -45,13 +45,13 @@ public:
|
||||
std::vector<Mat> inputs;
|
||||
inputs_arr.getMatVector(inputs);
|
||||
hasWeights = blobs.size() == 2 || (blobs.size() == 1 && !hasBias);
|
||||
CV_Assert(inputs.size() == 2 && blobs.empty() || blobs.size() == (int)hasWeights + (int)hasBias);
|
||||
CV_Assert((inputs.size() == 2 && blobs.empty()) || blobs.size() == (int)hasWeights + (int)hasBias);
|
||||
}
|
||||
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && axis == 1;
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && axis == 1);
|
||||
}
|
||||
|
||||
void forward(InputArrayOfArrays inputs_arr, OutputArrayOfArrays outputs_arr, OutputArrayOfArrays internals_arr) CV_OVERRIDE
|
||||
|
@ -111,7 +111,7 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && sliceRanges.size() == 1 && sliceRanges[0].size() == 4;
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && sliceRanges.size() == 1 && sliceRanges[0].size() == 4);
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
|
@ -90,9 +90,9 @@ public:
|
||||
virtual bool supportBackend(int backendId) CV_OVERRIDE
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE && haveHalide() && axisRaw == 1 ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && !logSoftMax ||
|
||||
backendId == DNN_BACKEND_VKCOM && haveVulkan();
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && axisRaw == 1) ||
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && !logSoftMax) ||
|
||||
(backendId == DNN_BACKEND_VKCOM && haveVulkan());
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
@ -638,7 +638,7 @@ void OCL4DNNConvSpatial<Dtype>::generateKey()
|
||||
<< "p" << pad_w_ << "x" << pad_h_ << "_"
|
||||
<< "num" << num_ << "_"
|
||||
<< "M" << M_ << "_"
|
||||
<< "activ" << fused_activ_ << "_"
|
||||
<< "activ" << (int)fused_activ_ << "_"
|
||||
<< "eltwise" << fused_eltwise_ << "_"
|
||||
<< precision;
|
||||
|
||||
|
@ -508,6 +508,16 @@ void ONNXImporter::populateNet(Net dstNet)
|
||||
layerParams.set("num_output", layerParams.blobs[0].size[0]);
|
||||
layerParams.set("bias_term", node_proto.input_size() == 3);
|
||||
}
|
||||
else if (layer_type == "ConvTranspose")
|
||||
{
|
||||
CV_Assert(node_proto.input_size() >= 2);
|
||||
layerParams.type = "Deconvolution";
|
||||
for (int j = 1; j < node_proto.input_size(); j++) {
|
||||
layerParams.blobs.push_back(getBlob(node_proto, constBlobs, j));
|
||||
}
|
||||
layerParams.set("num_output", layerParams.blobs[0].size[1]);
|
||||
layerParams.set("bias_term", node_proto.input_size() == 3);
|
||||
}
|
||||
else if (layer_type == "Transpose")
|
||||
{
|
||||
layerParams.type = "Permute";
|
||||
|
@ -309,7 +309,7 @@ void InfEngineBackendNet::setTargetDevice(InferenceEngine::TargetDevice device)
|
||||
|
||||
InferenceEngine::TargetDevice InfEngineBackendNet::getTargetDevice() CV_NOEXCEPT
|
||||
{
|
||||
return targetDevice;
|
||||
return const_cast<const InfEngineBackendNet*>(this)->getTargetDevice();
|
||||
}
|
||||
|
||||
InferenceEngine::TargetDevice InfEngineBackendNet::getTargetDevice() const CV_NOEXCEPT
|
||||
@ -387,6 +387,27 @@ void InfEngineBackendNet::init(int targetId)
|
||||
}
|
||||
}
|
||||
CV_Assert(!inputs.empty());
|
||||
|
||||
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2018R3)
|
||||
for (const auto& inp : inputs)
|
||||
{
|
||||
InferenceEngine::LayerParams lp;
|
||||
lp.name = inp.first;
|
||||
lp.type = "Input";
|
||||
lp.precision = InferenceEngine::Precision::FP32;
|
||||
std::shared_ptr<InferenceEngine::CNNLayer> inpLayer(new InferenceEngine::CNNLayer(lp));
|
||||
|
||||
layers.push_back(inpLayer);
|
||||
|
||||
InferenceEngine::DataPtr dataPtr = inp.second->getInputData();
|
||||
// TODO: remove precision dependency (see setInput.normalization tests)
|
||||
if (dataPtr->precision == InferenceEngine::Precision::FP32)
|
||||
{
|
||||
inpLayer->outData.assign(1, dataPtr);
|
||||
dataPtr->creatorLayer = InferenceEngine::CNNLayerWeakPtr(inpLayer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (outputs.empty())
|
||||
@ -559,7 +580,7 @@ bool InfEngineBackendLayer::getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
bool InfEngineBackendLayer::supportBackend(int backendId)
|
||||
{
|
||||
return backendId == DNN_BACKEND_DEFAULT ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine();
|
||||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine());
|
||||
}
|
||||
|
||||
void InfEngineBackendLayer::forward(InputArrayOfArrays inputs, OutputArrayOfArrays outputs,
|
||||
|
@ -25,10 +25,11 @@
|
||||
#define INF_ENGINE_RELEASE_2018R1 2018010000
|
||||
#define INF_ENGINE_RELEASE_2018R2 2018020000
|
||||
#define INF_ENGINE_RELEASE_2018R3 2018030000
|
||||
#define INF_ENGINE_RELEASE_2018R4 2018040000
|
||||
|
||||
#ifndef INF_ENGINE_RELEASE
|
||||
#warning("IE version have not been provided via command-line. Using 2018R2 by default")
|
||||
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2018R2
|
||||
#warning("IE version have not been provided via command-line. Using 2018R4 by default")
|
||||
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2018R4
|
||||
#endif
|
||||
|
||||
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
|
||||
|
@ -156,6 +156,7 @@ void blobFromTensor(const tensorflow::TensorProto &tensor, Mat &dstBlob)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void printList(const tensorflow::AttrValue::ListValue &val)
|
||||
{
|
||||
std::cout << "(";
|
||||
@ -235,6 +236,7 @@ void printLayerAttr(const tensorflow::NodeDef &layer)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasLayerAttr(const tensorflow::NodeDef &layer, const std::string &name)
|
||||
{
|
||||
|
@ -37,8 +37,6 @@ using namespace tensorflow;
|
||||
using namespace ::google::protobuf;
|
||||
using namespace ::google::protobuf::io;
|
||||
|
||||
const int kProtoReadBytesLimit = INT_MAX; // Max size of 2 GB minus 1 byte.
|
||||
|
||||
void ReadTFNetParamsFromBinaryFileOrDie(const char* param_file,
|
||||
tensorflow::GraphDef* param) {
|
||||
CHECK(ReadProtoFromBinaryFile(param_file, param))
|
||||
|
@ -174,7 +174,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.011 : 0.0;
|
||||
float l1 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.013 : 0.0;
|
||||
float lInf = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.062 : 0.0;
|
||||
processNet("dnn/ssd_mobilenet_v2_coco_2018_03_29.pb", "dnn/ssd_mobilenet_v2_coco_2018_03_29.pbtxt",
|
||||
inp, "detection_out", "", l1, lInf, 0.25);
|
||||
@ -184,7 +184,7 @@ TEST_P(DNNTestNetwork, SSD_VGG16)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE && target == DNN_TARGET_CPU)
|
||||
throw SkipTestException("");
|
||||
double scoreThreshold = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0252 : 0.0;
|
||||
double scoreThreshold = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.0325 : 0.0;
|
||||
Mat sample = imread(findDataFile("dnn/street.png", false));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel",
|
||||
@ -194,7 +194,7 @@ TEST_P(DNNTestNetwork, SSD_VGG16)
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_coco)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/openpose_pose_coco.caffemodel", "dnn/openpose_pose_coco.prototxt",
|
||||
Size(368, 368));
|
||||
@ -203,7 +203,7 @@ TEST_P(DNNTestNetwork, OpenPose_pose_coco)
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt",
|
||||
Size(368, 368));
|
||||
@ -212,7 +212,7 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
// The same .caffemodel but modified .prototxt
|
||||
// See https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/src/openpose/pose/poseParameters.cpp
|
||||
|
@ -512,7 +512,11 @@ INSTANTIATE_TEST_CASE_P(Test_Caffe, opencv_face_detector,
|
||||
|
||||
TEST_P(Test_Caffe_nets, FasterRCNN_vgg16)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE > 2018030000
|
||||
|| (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_OPENCL_FP16)
|
||||
#endif
|
||||
)
|
||||
throw SkipTestException("");
|
||||
static Mat ref = (Mat_<float>(3, 7) << 0, 2, 0.949398, 99.2454, 210.141, 601.205, 462.849,
|
||||
0, 7, 0.997022, 481.841, 92.3218, 722.685, 175.953,
|
||||
|
@ -57,7 +57,7 @@ static inline void PrintTo(const cv::dnn::Backend& v, std::ostream* os)
|
||||
case DNN_BACKEND_OPENCV: *os << "OCV"; return;
|
||||
case DNN_BACKEND_VKCOM: *os << "VKCOM"; return;
|
||||
} // don't use "default:" to emit compiler warnings
|
||||
*os << "DNN_BACKEND_UNKNOWN(" << v << ")";
|
||||
*os << "DNN_BACKEND_UNKNOWN(" << (int)v << ")";
|
||||
}
|
||||
|
||||
static inline void PrintTo(const cv::dnn::Target& v, std::ostream* os)
|
||||
@ -69,7 +69,7 @@ static inline void PrintTo(const cv::dnn::Target& v, std::ostream* os)
|
||||
case DNN_TARGET_MYRIAD: *os << "MYRIAD"; return;
|
||||
case DNN_TARGET_VULKAN: *os << "VULKAN"; return;
|
||||
} // don't use "default:" to emit compiler warnings
|
||||
*os << "DNN_TARGET_UNKNOWN(" << v << ")";
|
||||
*os << "DNN_TARGET_UNKNOWN(" << (int)v << ")";
|
||||
}
|
||||
|
||||
using opencv_test::tuple;
|
||||
@ -237,7 +237,8 @@ namespace opencv_test {
|
||||
|
||||
using namespace cv::dnn;
|
||||
|
||||
static testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargets(
|
||||
static inline
|
||||
testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargets(
|
||||
bool withInferenceEngine = true,
|
||||
bool withHalide = false,
|
||||
bool withCpuOCV = true,
|
||||
@ -290,4 +291,103 @@ static testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAnd
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace opencv_test {
|
||||
using namespace cv::dnn;
|
||||
|
||||
static inline
|
||||
testing::internal::ParamGenerator<Target> availableDnnTargets()
|
||||
{
|
||||
static std::vector<Target> targets;
|
||||
if (targets.empty())
|
||||
{
|
||||
targets.push_back(DNN_TARGET_CPU);
|
||||
#ifdef HAVE_OPENCL
|
||||
if (cv::ocl::useOpenCL())
|
||||
targets.push_back(DNN_TARGET_OPENCL);
|
||||
#endif
|
||||
}
|
||||
return testing::ValuesIn(targets);
|
||||
}
|
||||
|
||||
class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
|
||||
{
|
||||
public:
|
||||
dnn::Backend backend;
|
||||
dnn::Target target;
|
||||
double default_l1, default_lInf;
|
||||
|
||||
DNNTestLayer()
|
||||
{
|
||||
backend = (dnn::Backend)(int)get<0>(GetParam());
|
||||
target = (dnn::Target)(int)get<1>(GetParam());
|
||||
getDefaultThresholds(backend, target, &default_l1, &default_lInf);
|
||||
}
|
||||
|
||||
static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
*l1 = 4e-3;
|
||||
*lInf = 2e-2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*l1 = 1e-5;
|
||||
*lInf = 1e-4;
|
||||
}
|
||||
}
|
||||
|
||||
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
{
|
||||
#ifdef HAVE_OPENCL
|
||||
if (!cv::ocl::useOpenCL())
|
||||
#endif
|
||||
{
|
||||
throw SkipTestException("OpenCL is not available/disabled in OpenCV");
|
||||
}
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
if (!checkMyriadTarget())
|
||||
{
|
||||
throw SkipTestException("Myriad is not available/disabled in OpenCV");
|
||||
}
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE < 2018030000
|
||||
if (inp && ref && inp->size[0] != 1)
|
||||
{
|
||||
// Myriad plugin supports only batch size 1. Slice a single sample.
|
||||
if (inp->size[0] == ref->size[0])
|
||||
{
|
||||
std::vector<cv::Range> range(inp->dims, Range::all());
|
||||
range[0] = Range(0, 1);
|
||||
*inp = inp->operator()(range);
|
||||
|
||||
range = std::vector<cv::Range>(ref->dims, Range::all());
|
||||
range[0] = Range(0, 1);
|
||||
*ref = ref->operator()(range);
|
||||
}
|
||||
else
|
||||
throw SkipTestException("Myriad plugin supports only batch size 1");
|
||||
}
|
||||
#else
|
||||
if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
|
||||
inp->size[0] != 1 && inp->size[0] != ref->size[0])
|
||||
throw SkipTestException("Inconsistent batch size of input and output blobs for Myriad plugin");
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void checkBackend(Mat* inp = 0, Mat* ref = 0)
|
||||
{
|
||||
checkBackend(backend, target, inp, ref);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
@ -306,6 +306,9 @@ 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 (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_MYRIAD)
|
||||
#endif
|
||||
// batch size 2
|
||||
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff);
|
||||
}
|
||||
|
@ -166,6 +166,11 @@ 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 (backendId == DNN_BACKEND_INFERENCE_ENGINE && targetId == DNN_TARGET_CPU &&
|
||||
hasBias && group != 1)
|
||||
throw SkipTestException("Test is disabled for OpenVINO 2018R4");
|
||||
#endif
|
||||
|
||||
int sz[] = {inChannels, outChannels / group, kernel.height, kernel.width};
|
||||
Mat weights(4, &sz[0], CV_32F);
|
||||
|
@ -177,10 +177,20 @@ TEST_P(DNNTestOpenVINO, models)
|
||||
Target target = (dnn::Target)(int)get<0>(GetParam());
|
||||
std::string modelName = get<1>(GetParam());
|
||||
|
||||
#ifdef INF_ENGINE_RELEASE
|
||||
#if INF_ENGINE_RELEASE <= 2018030000
|
||||
if (target == DNN_TARGET_MYRIAD && (modelName == "landmarks-regression-retail-0001" ||
|
||||
modelName == "semantic-segmentation-adas-0001" ||
|
||||
modelName == "face-reidentification-retail-0001"))
|
||||
throw SkipTestException("");
|
||||
#elif INF_ENGINE_RELEASE == 2018040000
|
||||
if (modelName == "single-image-super-resolution-0034" ||
|
||||
(target == DNN_TARGET_MYRIAD && (modelName == "license-plate-recognition-barrier-0001" ||
|
||||
modelName == "landmarks-regression-retail-0009" ||
|
||||
modelName == "semantic-segmentation-adas-0001")))
|
||||
throw SkipTestException("");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
std::string precision = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? "FP16" : "FP32";
|
||||
std::string prefix = utils::fs::join("intel_models",
|
||||
|
@ -137,6 +137,10 @@ TEST_P(Test_Caffe_layers, Convolution)
|
||||
|
||||
TEST_P(Test_Caffe_layers, DeConvolution)
|
||||
{
|
||||
#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
|
||||
testLayerUsingCaffeModels("layer_deconvolution", true, false);
|
||||
}
|
||||
|
||||
@ -558,9 +562,11 @@ TEST_P(Test_Caffe_layers, FasterRCNN_Proposal)
|
||||
normAssert(outs[i].rowRange(0, numDets), ref);
|
||||
|
||||
if (numDets < outs[i].size[0])
|
||||
{
|
||||
EXPECT_EQ(countNonZero(outs[i].rowRange(numDets, outs[i].size[0])), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<tuple<Vec4i, Vec2i, bool> > Scale_untrainable;
|
||||
TEST_P(Scale_untrainable, Accuracy)
|
||||
|
@ -140,9 +140,9 @@ TEST(LayerFactory, custom_layers)
|
||||
net.setPreferableBackend(DNN_BACKEND_OPENCV);
|
||||
Mat output = net.forward();
|
||||
|
||||
if (i == 0) EXPECT_EQ(output.at<float>(0), 1);
|
||||
else if (i == 1) EXPECT_EQ(output.at<float>(0), 2);
|
||||
else if (i == 2) EXPECT_EQ(output.at<float>(0), 1);
|
||||
if (i == 0) { EXPECT_EQ(output.at<float>(0), 1); }
|
||||
else if (i == 1) { EXPECT_EQ(output.at<float>(0), 2); }
|
||||
else if (i == 2) { EXPECT_EQ(output.at<float>(0), 1); }
|
||||
}
|
||||
LayerFactory::unregisterLayer("CustomType");
|
||||
}
|
||||
|
@ -68,6 +68,12 @@ TEST_P(Test_ONNX_layers, Convolution)
|
||||
testONNXModels("two_convolution");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, Deconvolution)
|
||||
{
|
||||
testONNXModels("deconvolution");
|
||||
testONNXModels("two_deconvolution");
|
||||
}
|
||||
|
||||
TEST_P(Test_ONNX_layers, Dropout)
|
||||
{
|
||||
testONNXModels("dropout");
|
||||
@ -118,8 +124,8 @@ TEST_P(Test_ONNX_layers, Transpose)
|
||||
|
||||
TEST_P(Test_ONNX_layers, Multiplication)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16 ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
if ((backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16) ||
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD))
|
||||
throw SkipTestException("");
|
||||
testONNXModels("mul");
|
||||
}
|
||||
@ -296,7 +302,7 @@ TEST_P(Test_ONNX_nets, ResNet101_DUC_HDC)
|
||||
TEST_P(Test_ONNX_nets, TinyYolov2)
|
||||
{
|
||||
if (cvtest::skipUnstableTests ||
|
||||
backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)) {
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))) {
|
||||
throw SkipTestException("");
|
||||
}
|
||||
// output range: [-11; 8]
|
||||
|
@ -49,100 +49,4 @@
|
||||
#include "opencv2/dnn.hpp"
|
||||
#include "test_common.hpp"
|
||||
|
||||
namespace opencv_test {
|
||||
using namespace cv::dnn;
|
||||
|
||||
static testing::internal::ParamGenerator<Target> availableDnnTargets()
|
||||
{
|
||||
static std::vector<Target> targets;
|
||||
if (targets.empty())
|
||||
{
|
||||
targets.push_back(DNN_TARGET_CPU);
|
||||
#ifdef HAVE_OPENCL
|
||||
if (cv::ocl::useOpenCL())
|
||||
targets.push_back(DNN_TARGET_OPENCL);
|
||||
#endif
|
||||
}
|
||||
return testing::ValuesIn(targets);
|
||||
}
|
||||
|
||||
class DNNTestLayer : public TestWithParam<tuple<Backend, Target> >
|
||||
{
|
||||
public:
|
||||
dnn::Backend backend;
|
||||
dnn::Target target;
|
||||
double default_l1, default_lInf;
|
||||
|
||||
DNNTestLayer()
|
||||
{
|
||||
backend = (dnn::Backend)(int)get<0>(GetParam());
|
||||
target = (dnn::Target)(int)get<1>(GetParam());
|
||||
getDefaultThresholds(backend, target, &default_l1, &default_lInf);
|
||||
}
|
||||
|
||||
static void getDefaultThresholds(int backend, int target, double* l1, double* lInf)
|
||||
{
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
*l1 = 4e-3;
|
||||
*lInf = 2e-2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*l1 = 1e-5;
|
||||
*lInf = 1e-4;
|
||||
}
|
||||
}
|
||||
|
||||
static void checkBackend(int backend, int target, Mat* inp = 0, Mat* ref = 0)
|
||||
{
|
||||
if (backend == DNN_BACKEND_OPENCV && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
{
|
||||
#ifdef HAVE_OPENCL
|
||||
if (!cv::ocl::useOpenCL())
|
||||
#endif
|
||||
{
|
||||
throw SkipTestException("OpenCL is not available/disabled in OpenCV");
|
||||
}
|
||||
}
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
{
|
||||
if (!checkMyriadTarget())
|
||||
{
|
||||
throw SkipTestException("Myriad is not available/disabled in OpenCV");
|
||||
}
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_RELEASE < 2018030000
|
||||
if (inp && ref && inp->size[0] != 1)
|
||||
{
|
||||
// Myriad plugin supports only batch size 1. Slice a single sample.
|
||||
if (inp->size[0] == ref->size[0])
|
||||
{
|
||||
std::vector<cv::Range> range(inp->dims, Range::all());
|
||||
range[0] = Range(0, 1);
|
||||
*inp = inp->operator()(range);
|
||||
|
||||
range = std::vector<cv::Range>(ref->dims, Range::all());
|
||||
range[0] = Range(0, 1);
|
||||
*ref = ref->operator()(range);
|
||||
}
|
||||
else
|
||||
throw SkipTestException("Myriad plugin supports only batch size 1");
|
||||
}
|
||||
#else
|
||||
if (inp && ref && inp->dims == 4 && ref->dims == 4 &&
|
||||
inp->size[0] != 1 && inp->size[0] != ref->size[0])
|
||||
throw SkipTestException("Inconsistent batch size of input and output blobs for Myriad plugin");
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void checkBackend(Mat* inp = 0, Mat* ref = 0)
|
||||
{
|
||||
checkBackend(backend, target, inp, ref);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
@ -101,7 +101,9 @@ public:
|
||||
|
||||
string dataConfig;
|
||||
if (hasText)
|
||||
{
|
||||
ASSERT_TRUE(readFileInMemory(netConfig, dataConfig));
|
||||
}
|
||||
|
||||
net = readNetFromTensorflow(dataModel.c_str(), dataModel.size(),
|
||||
dataConfig.c_str(), dataConfig.size());
|
||||
@ -473,7 +475,7 @@ TEST_P(Test_TensorFlow_nets, EAST_text_detection)
|
||||
double l1_geometry = default_l1, lInf_geometry = default_lInf;
|
||||
if (target == DNN_TARGET_OPENCL_FP16)
|
||||
{
|
||||
lInf_scores = 0.11;
|
||||
lInf_scores = backend == DNN_BACKEND_INFERENCE_ENGINE ? 0.16 : 0.11;
|
||||
l1_geometry = 0.28; lInf_geometry = 5.94;
|
||||
}
|
||||
else if (target == DNN_TARGET_MYRIAD)
|
||||
|
@ -136,6 +136,10 @@ 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 (backend == DNN_BACKEND_INFERENCE_ENGINE && target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled for OpenVINO 2018R4");
|
||||
#endif
|
||||
runTorchNet("net_reshape_batch");
|
||||
runTorchNet("net_reshape_channels", "", false, true);
|
||||
}
|
||||
@ -168,6 +172,10 @@ TEST_P(Test_Torch_layers, run_depth_concat)
|
||||
|
||||
TEST_P(Test_Torch_layers, run_deconv)
|
||||
{
|
||||
#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
|
||||
runTorchNet("net_deconv");
|
||||
}
|
||||
|
||||
|
@ -595,4 +595,23 @@ TEST( Features2d_FlannBasedMatcher, read_write )
|
||||
EXPECT_EQ(ymlfile, out);
|
||||
}
|
||||
|
||||
|
||||
TEST(Features2d_DMatch, issue_11855)
|
||||
{
|
||||
Mat sources = (Mat_<uchar>(2, 3) << 1, 1, 0,
|
||||
1, 1, 1);
|
||||
Mat targets = (Mat_<uchar>(2, 3) << 1, 1, 1,
|
||||
0, 0, 0);
|
||||
|
||||
Ptr<BFMatcher> bf = BFMatcher::create(NORM_HAMMING, true);
|
||||
vector<vector<DMatch> > match;
|
||||
bf->knnMatch(sources, targets, match, 1, noArray(), true);
|
||||
|
||||
ASSERT_EQ((size_t)1, match.size());
|
||||
ASSERT_EQ((size_t)1, match[0].size());
|
||||
EXPECT_EQ(1, match[0][0].queryIdx);
|
||||
EXPECT_EQ(0, match[0][0].trainIdx);
|
||||
EXPECT_EQ(0.0f, match[0][0].distance);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
759
modules/imgproc/src/bilateral_filter.cpp
Normal file
759
modules/imgproc/src/bilateral_filter.cpp
Normal file
@ -0,0 +1,759 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, 2018, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014-2015, Itseez Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "opencl_kernels_imgproc.hpp"
|
||||
|
||||
/****************************************************************************************\
|
||||
Bilateral Filtering
|
||||
\****************************************************************************************/
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class BilateralFilter_8u_Invoker :
|
||||
public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
BilateralFilter_8u_Invoker(Mat& _dest, const Mat& _temp, int _radius, int _maxk,
|
||||
int* _space_ofs, float *_space_weight, float *_color_weight) :
|
||||
temp(&_temp), dest(&_dest), radius(_radius),
|
||||
maxk(_maxk), space_ofs(_space_ofs), space_weight(_space_weight), color_weight(_color_weight)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
int i, j, cn = dest->channels(), k;
|
||||
Size size = dest->size();
|
||||
|
||||
for( i = range.start; i < range.end; i++ )
|
||||
{
|
||||
const uchar* sptr = temp->ptr(i+radius) + radius*cn;
|
||||
uchar* dptr = dest->ptr(i);
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
AutoBuffer<float> buf(alignSize(size.width, CV_SIMD_WIDTH) + size.width + CV_SIMD_WIDTH - 1);
|
||||
memset(buf.data(), 0, buf.size() * sizeof(float));
|
||||
float *sum = alignPtr(buf.data(), CV_SIMD_WIDTH);
|
||||
float *wsum = sum + alignSize(size.width, CV_SIMD_WIDTH);
|
||||
for( k = 0; k < maxk; k++ )
|
||||
{
|
||||
const uchar* ksptr = sptr + space_ofs[k];
|
||||
j = 0;
|
||||
#if CV_SIMD
|
||||
v_float32 kweight = vx_setall_f32(space_weight[k]);
|
||||
for (; j <= size.width - v_float32::nlanes; j += v_float32::nlanes)
|
||||
{
|
||||
v_uint32 val = vx_load_expand_q(ksptr + j);
|
||||
v_float32 w = kweight * v_lut(color_weight, v_reinterpret_as_s32(v_absdiff(val, vx_load_expand_q(sptr + j))));
|
||||
v_store_aligned(wsum + j, vx_load_aligned(wsum + j) + w);
|
||||
v_store_aligned(sum + j, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val)), w, vx_load_aligned(sum + j)));
|
||||
}
|
||||
#endif
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
int val = ksptr[j];
|
||||
float w = space_weight[k] * color_weight[std::abs(val - sptr[j])];
|
||||
wsum[j] += w;
|
||||
sum[j] += val * w;
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
#if CV_SIMD
|
||||
for (; j <= size.width - 2*v_float32::nlanes; j += 2*v_float32::nlanes)
|
||||
v_pack_u_store(dptr + j, v_pack(v_round(vx_load_aligned(sum + j ) / vx_load_aligned(wsum + j )),
|
||||
v_round(vx_load_aligned(sum + j + v_float32::nlanes) / vx_load_aligned(wsum + j + v_float32::nlanes))));
|
||||
#endif
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
// overflow is not possible here => there is no need to use cv::saturate_cast
|
||||
CV_DbgAssert(fabs(wsum[j]) > 0);
|
||||
dptr[j] = (uchar)cvRound(sum[j]/wsum[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( cn == 3 );
|
||||
AutoBuffer<float> buf(alignSize(size.width, CV_SIMD_WIDTH)*3 + size.width + CV_SIMD_WIDTH - 1);
|
||||
memset(buf.data(), 0, buf.size() * sizeof(float));
|
||||
float *sum_b = alignPtr(buf.data(), CV_SIMD_WIDTH);
|
||||
float *sum_g = sum_b + alignSize(size.width, CV_SIMD_WIDTH);
|
||||
float *sum_r = sum_g + alignSize(size.width, CV_SIMD_WIDTH);
|
||||
float *wsum = sum_r + alignSize(size.width, CV_SIMD_WIDTH);
|
||||
for(k = 0; k < maxk; k++ )
|
||||
{
|
||||
const uchar* ksptr = sptr + space_ofs[k];
|
||||
const uchar* rsptr = sptr;
|
||||
j = 0;
|
||||
#if CV_SIMD
|
||||
v_float32 kweight = vx_setall_f32(space_weight[k]);
|
||||
for (; j <= size.width - v_uint8::nlanes; j += v_uint8::nlanes, ksptr += 3*v_uint8::nlanes, rsptr += 3*v_uint8::nlanes)
|
||||
{
|
||||
v_uint8 kb, kg, kr, rb, rg, rr;
|
||||
v_load_deinterleave(ksptr, kb, kg, kr);
|
||||
v_load_deinterleave(rsptr, rb, rg, rr);
|
||||
|
||||
v_uint16 b_l, b_h, g_l, g_h, r_l, r_h;
|
||||
v_expand(v_absdiff(kb, rb), b_l, b_h);
|
||||
v_expand(v_absdiff(kg, rg), g_l, g_h);
|
||||
v_expand(v_absdiff(kr, rr), r_l, r_h);
|
||||
|
||||
v_uint32 val0, val1, val2, val3;
|
||||
v_expand(b_l + g_l + r_l, val0, val1);
|
||||
v_expand(b_h + g_h + r_h, val2, val3);
|
||||
|
||||
v_expand(kb, b_l, b_h);
|
||||
v_expand(kg, g_l, g_h);
|
||||
v_expand(kr, r_l, r_h);
|
||||
|
||||
v_float32 w0 = kweight * v_lut(color_weight, v_reinterpret_as_s32(val0));
|
||||
v_float32 w1 = kweight * v_lut(color_weight, v_reinterpret_as_s32(val1));
|
||||
v_float32 w2 = kweight * v_lut(color_weight, v_reinterpret_as_s32(val2));
|
||||
v_float32 w3 = kweight * v_lut(color_weight, v_reinterpret_as_s32(val3));
|
||||
v_store_aligned(wsum + j , w0 + vx_load_aligned(wsum + j));
|
||||
v_store_aligned(wsum + j + v_float32::nlanes, w1 + vx_load_aligned(wsum + j + v_float32::nlanes));
|
||||
v_store_aligned(wsum + j + 2*v_float32::nlanes, w2 + vx_load_aligned(wsum + j + 2*v_float32::nlanes));
|
||||
v_store_aligned(wsum + j + 3*v_float32::nlanes, w3 + vx_load_aligned(wsum + j + 3*v_float32::nlanes));
|
||||
v_expand(b_l, val0, val1);
|
||||
v_expand(b_h, val2, val3);
|
||||
v_store_aligned(sum_b + j , v_muladd(v_cvt_f32(v_reinterpret_as_s32(val0)), w0, vx_load_aligned(sum_b + j)));
|
||||
v_store_aligned(sum_b + j + v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val1)), w1, vx_load_aligned(sum_b + j + v_float32::nlanes)));
|
||||
v_store_aligned(sum_b + j + 2*v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val2)), w2, vx_load_aligned(sum_b + j + 2*v_float32::nlanes)));
|
||||
v_store_aligned(sum_b + j + 3*v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val3)), w3, vx_load_aligned(sum_b + j + 3*v_float32::nlanes)));
|
||||
v_expand(g_l, val0, val1);
|
||||
v_expand(g_h, val2, val3);
|
||||
v_store_aligned(sum_g + j , v_muladd(v_cvt_f32(v_reinterpret_as_s32(val0)), w0, vx_load_aligned(sum_g + j)));
|
||||
v_store_aligned(sum_g + j + v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val1)), w1, vx_load_aligned(sum_g + j + v_float32::nlanes)));
|
||||
v_store_aligned(sum_g + j + 2*v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val2)), w2, vx_load_aligned(sum_g + j + 2*v_float32::nlanes)));
|
||||
v_store_aligned(sum_g + j + 3*v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val3)), w3, vx_load_aligned(sum_g + j + 3*v_float32::nlanes)));
|
||||
v_expand(r_l, val0, val1);
|
||||
v_expand(r_h, val2, val3);
|
||||
v_store_aligned(sum_r + j , v_muladd(v_cvt_f32(v_reinterpret_as_s32(val0)), w0, vx_load_aligned(sum_r + j)));
|
||||
v_store_aligned(sum_r + j + v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val1)), w1, vx_load_aligned(sum_r + j + v_float32::nlanes)));
|
||||
v_store_aligned(sum_r + j + 2*v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val2)), w2, vx_load_aligned(sum_r + j + 2*v_float32::nlanes)));
|
||||
v_store_aligned(sum_r + j + 3*v_float32::nlanes, v_muladd(v_cvt_f32(v_reinterpret_as_s32(val3)), w3, vx_load_aligned(sum_r + j + 3*v_float32::nlanes)));
|
||||
}
|
||||
#endif
|
||||
for(; j < size.width; j++, ksptr += 3, rsptr += 3)
|
||||
{
|
||||
int b = ksptr[0], g = ksptr[1], r = ksptr[2];
|
||||
float w = space_weight[k]*color_weight[std::abs(b - rsptr[0]) + std::abs(g - rsptr[1]) + std::abs(r - rsptr[2])];
|
||||
wsum[j] += w;
|
||||
sum_b[j] += b*w; sum_g[j] += g*w; sum_r[j] += r*w;
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
#if CV_SIMD
|
||||
v_float32 v_one = vx_setall_f32(1.f);
|
||||
for(; j <= size.width - v_uint8::nlanes; j += v_uint8::nlanes, dptr += 3*v_uint8::nlanes)
|
||||
{
|
||||
v_float32 w0 = v_one / vx_load_aligned(wsum + j);
|
||||
v_float32 w1 = v_one / vx_load_aligned(wsum + j + v_float32::nlanes);
|
||||
v_float32 w2 = v_one / vx_load_aligned(wsum + j + 2*v_float32::nlanes);
|
||||
v_float32 w3 = v_one / vx_load_aligned(wsum + j + 3*v_float32::nlanes);
|
||||
|
||||
v_store_interleave(dptr, v_pack_u(v_pack(v_round(w0 * vx_load_aligned(sum_b + j)),
|
||||
v_round(w1 * vx_load_aligned(sum_b + j + v_float32::nlanes))),
|
||||
v_pack(v_round(w2 * vx_load_aligned(sum_b + j + 2*v_float32::nlanes)),
|
||||
v_round(w3 * vx_load_aligned(sum_b + j + 3*v_float32::nlanes)))),
|
||||
v_pack_u(v_pack(v_round(w0 * vx_load_aligned(sum_g + j)),
|
||||
v_round(w1 * vx_load_aligned(sum_g + j + v_float32::nlanes))),
|
||||
v_pack(v_round(w2 * vx_load_aligned(sum_g + j + 2*v_float32::nlanes)),
|
||||
v_round(w3 * vx_load_aligned(sum_g + j + 3*v_float32::nlanes)))),
|
||||
v_pack_u(v_pack(v_round(w0 * vx_load_aligned(sum_r + j)),
|
||||
v_round(w1 * vx_load_aligned(sum_r + j + v_float32::nlanes))),
|
||||
v_pack(v_round(w2 * vx_load_aligned(sum_r + j + 2*v_float32::nlanes)),
|
||||
v_round(w3 * vx_load_aligned(sum_r + j + 3*v_float32::nlanes)))));
|
||||
}
|
||||
#endif
|
||||
for(; j < size.width; j++)
|
||||
{
|
||||
CV_DbgAssert(fabs(wsum[j]) > 0);
|
||||
wsum[j] = 1.f/wsum[j];
|
||||
*(dptr++) = (uchar)cvRound(sum_b[j]*wsum[j]);
|
||||
*(dptr++) = (uchar)cvRound(sum_g[j]*wsum[j]);
|
||||
*(dptr++) = (uchar)cvRound(sum_r[j]*wsum[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if CV_SIMD
|
||||
vx_cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
const Mat *temp;
|
||||
Mat *dest;
|
||||
int radius, maxk, *space_ofs;
|
||||
float *space_weight, *color_weight;
|
||||
};
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
static bool ocl_bilateralFilter_8u(InputArray _src, OutputArray _dst, int d,
|
||||
double sigma_color, double sigma_space,
|
||||
int borderType)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
if (ocl::Device::getDefault().isNVidia())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
int i, j, maxk, radius;
|
||||
|
||||
if (depth != CV_8U || cn > 4)
|
||||
return false;
|
||||
|
||||
if (sigma_color <= 0)
|
||||
sigma_color = 1;
|
||||
if (sigma_space <= 0)
|
||||
sigma_space = 1;
|
||||
|
||||
double gauss_color_coeff = -0.5 / (sigma_color * sigma_color);
|
||||
double gauss_space_coeff = -0.5 / (sigma_space * sigma_space);
|
||||
|
||||
if ( d <= 0 )
|
||||
radius = cvRound(sigma_space * 1.5);
|
||||
else
|
||||
radius = d / 2;
|
||||
radius = MAX(radius, 1);
|
||||
d = radius * 2 + 1;
|
||||
|
||||
UMat src = _src.getUMat(), dst = _dst.getUMat(), temp;
|
||||
if (src.u == dst.u)
|
||||
return false;
|
||||
|
||||
copyMakeBorder(src, temp, radius, radius, radius, radius, borderType);
|
||||
std::vector<float> _space_weight(d * d);
|
||||
std::vector<int> _space_ofs(d * d);
|
||||
float * const space_weight = &_space_weight[0];
|
||||
int * const space_ofs = &_space_ofs[0];
|
||||
|
||||
// initialize space-related bilateral filter coefficients
|
||||
for( i = -radius, maxk = 0; i <= radius; i++ )
|
||||
for( j = -radius; j <= radius; j++ )
|
||||
{
|
||||
double r = std::sqrt((double)i * i + (double)j * j);
|
||||
if ( r > radius )
|
||||
continue;
|
||||
space_weight[maxk] = (float)std::exp(r * r * gauss_space_coeff);
|
||||
space_ofs[maxk++] = (int)(i * temp.step + j * cn);
|
||||
}
|
||||
|
||||
char cvt[3][40];
|
||||
String cnstr = cn > 1 ? format("%d", cn) : "";
|
||||
String kernelName("bilateral");
|
||||
size_t sizeDiv = 1;
|
||||
if ((ocl::Device::getDefault().isIntel()) &&
|
||||
(ocl::Device::getDefault().type() == ocl::Device::TYPE_GPU))
|
||||
{
|
||||
//Intel GPU
|
||||
if (dst.cols % 4 == 0 && cn == 1) // For single channel x4 sized images.
|
||||
{
|
||||
kernelName = "bilateral_float4";
|
||||
sizeDiv = 4;
|
||||
}
|
||||
}
|
||||
ocl::Kernel k(kernelName.c_str(), ocl::imgproc::bilateral_oclsrc,
|
||||
format("-D radius=%d -D maxk=%d -D cn=%d -D int_t=%s -D uint_t=uint%s -D convert_int_t=%s"
|
||||
" -D uchar_t=%s -D float_t=%s -D convert_float_t=%s -D convert_uchar_t=%s -D gauss_color_coeff=(float)%f",
|
||||
radius, maxk, cn, ocl::typeToStr(CV_32SC(cn)), cnstr.c_str(),
|
||||
ocl::convertTypeStr(CV_8U, CV_32S, cn, cvt[0]),
|
||||
ocl::typeToStr(type), ocl::typeToStr(CV_32FC(cn)),
|
||||
ocl::convertTypeStr(CV_32S, CV_32F, cn, cvt[1]),
|
||||
ocl::convertTypeStr(CV_32F, CV_8U, cn, cvt[2]), gauss_color_coeff));
|
||||
if (k.empty())
|
||||
return false;
|
||||
|
||||
Mat mspace_weight(1, d * d, CV_32FC1, space_weight);
|
||||
Mat mspace_ofs(1, d * d, CV_32SC1, space_ofs);
|
||||
UMat ucolor_weight, uspace_weight, uspace_ofs;
|
||||
|
||||
mspace_weight.copyTo(uspace_weight);
|
||||
mspace_ofs.copyTo(uspace_ofs);
|
||||
|
||||
k.args(ocl::KernelArg::ReadOnlyNoSize(temp), ocl::KernelArg::WriteOnly(dst),
|
||||
ocl::KernelArg::PtrReadOnly(uspace_weight),
|
||||
ocl::KernelArg::PtrReadOnly(uspace_ofs));
|
||||
|
||||
size_t globalsize[2] = { (size_t)dst.cols / sizeDiv, (size_t)dst.rows };
|
||||
return k.run(2, globalsize, NULL, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
static void
|
||||
bilateralFilter_8u( const Mat& src, Mat& dst, int d,
|
||||
double sigma_color, double sigma_space,
|
||||
int borderType )
|
||||
{
|
||||
int cn = src.channels();
|
||||
int i, j, maxk, radius;
|
||||
Size size = src.size();
|
||||
|
||||
CV_Assert( (src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.data != dst.data );
|
||||
|
||||
if( sigma_color <= 0 )
|
||||
sigma_color = 1;
|
||||
if( sigma_space <= 0 )
|
||||
sigma_space = 1;
|
||||
|
||||
double gauss_color_coeff = -0.5/(sigma_color*sigma_color);
|
||||
double gauss_space_coeff = -0.5/(sigma_space*sigma_space);
|
||||
|
||||
if( d <= 0 )
|
||||
radius = cvRound(sigma_space*1.5);
|
||||
else
|
||||
radius = d/2;
|
||||
radius = MAX(radius, 1);
|
||||
d = radius*2 + 1;
|
||||
|
||||
Mat temp;
|
||||
copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );
|
||||
|
||||
std::vector<float> _color_weight(cn*256);
|
||||
std::vector<float> _space_weight(d*d);
|
||||
std::vector<int> _space_ofs(d*d);
|
||||
float* color_weight = &_color_weight[0];
|
||||
float* space_weight = &_space_weight[0];
|
||||
int* space_ofs = &_space_ofs[0];
|
||||
|
||||
// initialize color-related bilateral filter coefficients
|
||||
|
||||
for( i = 0; i < 256*cn; i++ )
|
||||
color_weight[i] = (float)std::exp(i*i*gauss_color_coeff);
|
||||
|
||||
// initialize space-related bilateral filter coefficients
|
||||
for( i = -radius, maxk = 0; i <= radius; i++ )
|
||||
{
|
||||
j = -radius;
|
||||
|
||||
for( ; j <= radius; j++ )
|
||||
{
|
||||
double r = std::sqrt((double)i*i + (double)j*j);
|
||||
if( r > radius )
|
||||
continue;
|
||||
space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff);
|
||||
space_ofs[maxk++] = (int)(i*temp.step + j*cn);
|
||||
}
|
||||
}
|
||||
|
||||
BilateralFilter_8u_Invoker body(dst, temp, radius, maxk, space_ofs, space_weight, color_weight);
|
||||
parallel_for_(Range(0, size.height), body, dst.total()/(double)(1<<16));
|
||||
}
|
||||
|
||||
|
||||
class BilateralFilter_32f_Invoker :
|
||||
public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
|
||||
BilateralFilter_32f_Invoker(int _cn, int _radius, int _maxk, int *_space_ofs,
|
||||
const Mat& _temp, Mat& _dest, float _scale_index, float *_space_weight, float *_expLUT) :
|
||||
cn(_cn), radius(_radius), maxk(_maxk), space_ofs(_space_ofs),
|
||||
temp(&_temp), dest(&_dest), scale_index(_scale_index), space_weight(_space_weight), expLUT(_expLUT)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
int i, j, k;
|
||||
Size size = dest->size();
|
||||
|
||||
for( i = range.start; i < range.end; i++ )
|
||||
{
|
||||
const float* sptr = temp->ptr<float>(i+radius) + radius*cn;
|
||||
float* dptr = dest->ptr<float>(i);
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
AutoBuffer<float> buf(alignSize(size.width, CV_SIMD_WIDTH) + size.width + CV_SIMD_WIDTH - 1);
|
||||
memset(buf.data(), 0, buf.size() * sizeof(float));
|
||||
float *sum = alignPtr(buf.data(), CV_SIMD_WIDTH);
|
||||
float *wsum = sum + alignSize(size.width, CV_SIMD_WIDTH);
|
||||
#if CV_SIMD
|
||||
v_float32 v_one = vx_setall_f32(1.f);
|
||||
v_float32 sindex = vx_setall_f32(scale_index);
|
||||
#endif
|
||||
for( k = 0; k < maxk; k++ )
|
||||
{
|
||||
const float* ksptr = sptr + space_ofs[k];
|
||||
j = 0;
|
||||
#if CV_SIMD
|
||||
v_float32 kweight = vx_setall_f32(space_weight[k]);
|
||||
for (; j <= size.width - v_float32::nlanes; j += v_float32::nlanes)
|
||||
{
|
||||
v_float32 val = vx_load(ksptr + j);
|
||||
|
||||
v_float32 alpha = v_absdiff(val, vx_load(sptr + j)) * sindex;
|
||||
v_int32 idx = v_trunc(alpha);
|
||||
alpha -= v_cvt_f32(idx);
|
||||
|
||||
v_float32 w = kweight * v_muladd(v_lut(expLUT + 1, idx), alpha, v_lut(expLUT, idx) * (v_one-alpha));
|
||||
v_store_aligned(wsum + j, vx_load_aligned(wsum + j) + w);
|
||||
v_store_aligned(sum + j, v_muladd(val, w, vx_load_aligned(sum + j)));
|
||||
}
|
||||
#endif
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
float val = ksptr[j];
|
||||
float alpha = std::abs(val - sptr[j]) * scale_index;
|
||||
int idx = cvFloor(alpha);
|
||||
alpha -= idx;
|
||||
float w = space_weight[k] * (expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx]));
|
||||
wsum[j] += w;
|
||||
sum[j] += val * w;
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
#if CV_SIMD
|
||||
for (; j <= size.width - v_float32::nlanes; j += v_float32::nlanes)
|
||||
v_store(dptr + j, vx_load_aligned(sum + j) / vx_load_aligned(wsum + j));
|
||||
#endif
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
CV_DbgAssert(fabs(wsum[j]) > 0);
|
||||
dptr[j] = sum[j] / wsum[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert( cn == 3 );
|
||||
AutoBuffer<float> buf(alignSize(size.width, CV_SIMD_WIDTH)*3 + size.width + CV_SIMD_WIDTH - 1);
|
||||
memset(buf.data(), 0, buf.size() * sizeof(float));
|
||||
float *sum_b = alignPtr(buf.data(), CV_SIMD_WIDTH);
|
||||
float *sum_g = sum_b + alignSize(size.width, CV_SIMD_WIDTH);
|
||||
float *sum_r = sum_g + alignSize(size.width, CV_SIMD_WIDTH);
|
||||
float *wsum = sum_r + alignSize(size.width, CV_SIMD_WIDTH);
|
||||
#if CV_SIMD
|
||||
v_float32 v_one = vx_setall_f32(1.f);
|
||||
v_float32 sindex = vx_setall_f32(scale_index);
|
||||
#endif
|
||||
for (k = 0; k < maxk; k++)
|
||||
{
|
||||
const float* ksptr = sptr + space_ofs[k];
|
||||
const float* rsptr = sptr;
|
||||
j = 0;
|
||||
#if CV_SIMD
|
||||
v_float32 kweight = vx_setall_f32(space_weight[k]);
|
||||
for (; j <= size.width - v_float32::nlanes; j += v_float32::nlanes, ksptr += 3*v_float32::nlanes, rsptr += 3*v_float32::nlanes)
|
||||
{
|
||||
v_float32 kb, kg, kr, rb, rg, rr;
|
||||
v_load_deinterleave(ksptr, kb, kg, kr);
|
||||
v_load_deinterleave(rsptr, rb, rg, rr);
|
||||
|
||||
v_float32 alpha = (v_absdiff(kb, rb) + v_absdiff(kg, rg) + v_absdiff(kr, rr)) * sindex;
|
||||
v_int32 idx = v_trunc(alpha);
|
||||
alpha -= v_cvt_f32(idx);
|
||||
|
||||
v_float32 w = kweight * v_muladd(v_lut(expLUT + 1, idx), alpha, v_lut(expLUT, idx) * (v_one - alpha));
|
||||
v_store_aligned(wsum + j, vx_load_aligned(wsum + j) + w);
|
||||
v_store_aligned(sum_b + j, v_muladd(kb, w, vx_load_aligned(sum_b + j)));
|
||||
v_store_aligned(sum_g + j, v_muladd(kg, w, vx_load_aligned(sum_g + j)));
|
||||
v_store_aligned(sum_r + j, v_muladd(kr, w, vx_load_aligned(sum_r + j)));
|
||||
}
|
||||
#endif
|
||||
for (; j < size.width; j++, ksptr += 3, rsptr += 3)
|
||||
{
|
||||
float b = ksptr[0], g = ksptr[1], r = ksptr[2];
|
||||
float alpha = (std::abs(b - rsptr[0]) + std::abs(g - rsptr[1]) + std::abs(r - rsptr[2])) * scale_index;
|
||||
int idx = cvFloor(alpha);
|
||||
alpha -= idx;
|
||||
float w = space_weight[k] * (expLUT[idx] + alpha*(expLUT[idx + 1] - expLUT[idx]));
|
||||
wsum[j] += w;
|
||||
sum_b[j] += b*w;
|
||||
sum_g[j] += g*w;
|
||||
sum_r[j] += r*w;
|
||||
}
|
||||
}
|
||||
j = 0;
|
||||
#if CV_SIMD
|
||||
for (; j <= size.width - v_float32::nlanes; j += v_float32::nlanes, dptr += 3*v_float32::nlanes)
|
||||
{
|
||||
v_float32 w = v_one / vx_load_aligned(wsum + j);
|
||||
v_store_interleave(dptr, vx_load_aligned(sum_b + j) * w, vx_load_aligned(sum_g + j) * w, vx_load_aligned(sum_r + j) * w);
|
||||
}
|
||||
#endif
|
||||
for (; j < size.width; j++)
|
||||
{
|
||||
CV_DbgAssert(fabs(wsum[j]) > 0);
|
||||
wsum[j] = 1.f / wsum[j];
|
||||
*(dptr++) = sum_b[j] * wsum[j];
|
||||
*(dptr++) = sum_g[j] * wsum[j];
|
||||
*(dptr++) = sum_r[j] * wsum[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
#if CV_SIMD
|
||||
vx_cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
int cn, radius, maxk, *space_ofs;
|
||||
const Mat* temp;
|
||||
Mat *dest;
|
||||
float scale_index, *space_weight, *expLUT;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
bilateralFilter_32f( const Mat& src, Mat& dst, int d,
|
||||
double sigma_color, double sigma_space,
|
||||
int borderType )
|
||||
{
|
||||
int cn = src.channels();
|
||||
int i, j, maxk, radius;
|
||||
double minValSrc=-1, maxValSrc=1;
|
||||
const int kExpNumBinsPerChannel = 1 << 12;
|
||||
int kExpNumBins = 0;
|
||||
float lastExpVal = 1.f;
|
||||
float len, scale_index;
|
||||
Size size = src.size();
|
||||
|
||||
CV_Assert( (src.type() == CV_32FC1 || src.type() == CV_32FC3) && src.data != dst.data );
|
||||
|
||||
if( sigma_color <= 0 )
|
||||
sigma_color = 1;
|
||||
if( sigma_space <= 0 )
|
||||
sigma_space = 1;
|
||||
|
||||
double gauss_color_coeff = -0.5/(sigma_color*sigma_color);
|
||||
double gauss_space_coeff = -0.5/(sigma_space*sigma_space);
|
||||
|
||||
if( d <= 0 )
|
||||
radius = cvRound(sigma_space*1.5);
|
||||
else
|
||||
radius = d/2;
|
||||
radius = MAX(radius, 1);
|
||||
d = radius*2 + 1;
|
||||
// compute the min/max range for the input image (even if multichannel)
|
||||
|
||||
minMaxLoc( src.reshape(1), &minValSrc, &maxValSrc );
|
||||
if(std::abs(minValSrc - maxValSrc) < FLT_EPSILON)
|
||||
{
|
||||
src.copyTo(dst);
|
||||
return;
|
||||
}
|
||||
|
||||
// temporary copy of the image with borders for easy processing
|
||||
Mat temp;
|
||||
copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );
|
||||
minValSrc -= 5. * sigma_color;
|
||||
patchNaNs( temp, minValSrc ); // this replacement of NaNs makes the assumption that depth values are nonnegative
|
||||
// TODO: make replacement parameter avalible in the outside function interface
|
||||
// allocate lookup tables
|
||||
std::vector<float> _space_weight(d*d);
|
||||
std::vector<int> _space_ofs(d*d);
|
||||
float* space_weight = &_space_weight[0];
|
||||
int* space_ofs = &_space_ofs[0];
|
||||
|
||||
// assign a length which is slightly more than needed
|
||||
len = (float)(maxValSrc - minValSrc) * cn;
|
||||
kExpNumBins = kExpNumBinsPerChannel * cn;
|
||||
std::vector<float> _expLUT(kExpNumBins+2);
|
||||
float* expLUT = &_expLUT[0];
|
||||
|
||||
scale_index = kExpNumBins/len;
|
||||
|
||||
// initialize the exp LUT
|
||||
for( i = 0; i < kExpNumBins+2; i++ )
|
||||
{
|
||||
if( lastExpVal > 0.f )
|
||||
{
|
||||
double val = i / scale_index;
|
||||
expLUT[i] = (float)std::exp(val * val * gauss_color_coeff);
|
||||
lastExpVal = expLUT[i];
|
||||
}
|
||||
else
|
||||
expLUT[i] = 0.f;
|
||||
}
|
||||
|
||||
// initialize space-related bilateral filter coefficients
|
||||
for( i = -radius, maxk = 0; i <= radius; i++ )
|
||||
for( j = -radius; j <= radius; j++ )
|
||||
{
|
||||
double r = std::sqrt((double)i*i + (double)j*j);
|
||||
if( r > radius )
|
||||
continue;
|
||||
space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff);
|
||||
space_ofs[maxk++] = (int)(i*(temp.step/sizeof(float)) + j*cn);
|
||||
}
|
||||
|
||||
// parallel_for usage
|
||||
|
||||
BilateralFilter_32f_Invoker body(cn, radius, maxk, space_ofs, temp, dst, scale_index, space_weight, expLUT);
|
||||
parallel_for_(Range(0, size.height), body, dst.total()/(double)(1<<16));
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#define IPP_BILATERAL_PARALLEL 1
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
class ipp_bilateralFilterParallel: public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
ipp_bilateralFilterParallel(::ipp::IwiImage &_src, ::ipp::IwiImage &_dst, int _radius, Ipp32f _valSquareSigma, Ipp32f _posSquareSigma, ::ipp::IwiBorderType _borderType, bool *_ok):
|
||||
src(_src), dst(_dst)
|
||||
{
|
||||
pOk = _ok;
|
||||
|
||||
radius = _radius;
|
||||
valSquareSigma = _valSquareSigma;
|
||||
posSquareSigma = _posSquareSigma;
|
||||
borderType = _borderType;
|
||||
|
||||
*pOk = true;
|
||||
}
|
||||
~ipp_bilateralFilterParallel() {}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
if(*pOk == false)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, src, dst, radius, valSquareSigma, posSquareSigma, ::ipp::IwDefault(), borderType, tile);
|
||||
}
|
||||
catch(const ::ipp::IwException &)
|
||||
{
|
||||
*pOk = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
private:
|
||||
::ipp::IwiImage &src;
|
||||
::ipp::IwiImage &dst;
|
||||
|
||||
int radius;
|
||||
Ipp32f valSquareSigma;
|
||||
Ipp32f posSquareSigma;
|
||||
::ipp::IwiBorderType borderType;
|
||||
|
||||
bool *pOk;
|
||||
const ipp_bilateralFilterParallel& operator= (const ipp_bilateralFilterParallel&);
|
||||
};
|
||||
#endif
|
||||
|
||||
static bool ipp_bilateralFilter(Mat &src, Mat &dst, int d, double sigmaColor, double sigmaSpace, int borderType)
|
||||
{
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
int radius = IPP_MAX(((d <= 0)?cvRound(sigmaSpace*1.5):d/2), 1);
|
||||
Ipp32f valSquareSigma = (Ipp32f)((sigmaColor <= 0)?1:sigmaColor*sigmaColor);
|
||||
Ipp32f posSquareSigma = (Ipp32f)((sigmaSpace <= 0)?1:sigmaSpace*sigmaSpace);
|
||||
|
||||
// Acquire data and begin processing
|
||||
try
|
||||
{
|
||||
::ipp::IwiImage iwSrc = ippiGetImage(src);
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
::ipp::IwiBorderSize borderSize(radius);
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
|
||||
if(!ippBorder)
|
||||
return false;
|
||||
|
||||
const int threads = ippiSuggestThreadsNum(iwDst, 2);
|
||||
if(IPP_BILATERAL_PARALLEL && threads > 1) {
|
||||
bool ok = true;
|
||||
Range range(0, (int)iwDst.m_size.height);
|
||||
ipp_bilateralFilterParallel invoker(iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ippBorder, &ok);
|
||||
if(!ok)
|
||||
return false;
|
||||
|
||||
parallel_for_(range, invoker, threads*4);
|
||||
|
||||
if(!ok)
|
||||
return false;
|
||||
} else {
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ::ipp::IwDefault(), ippBorder);
|
||||
}
|
||||
}
|
||||
catch (const ::ipp::IwException &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(d); CV_UNUSED(sigmaColor); CV_UNUSED(sigmaSpace); CV_UNUSED(borderType);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void cv::bilateralFilter( InputArray _src, OutputArray _dst, int d,
|
||||
double sigmaColor, double sigmaSpace,
|
||||
int borderType )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
_dst.create( _src.size(), _src.type() );
|
||||
|
||||
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
|
||||
ocl_bilateralFilter_8u(_src, _dst, d, sigmaColor, sigmaSpace, borderType))
|
||||
|
||||
Mat src = _src.getMat(), dst = _dst.getMat();
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_bilateralFilter(src, dst, d, sigmaColor, sigmaSpace, borderType));
|
||||
|
||||
if( src.depth() == CV_8U )
|
||||
bilateralFilter_8u( src, dst, d, sigmaColor, sigmaSpace, borderType );
|
||||
else if( src.depth() == CV_32F )
|
||||
bilateralFilter_32f( src, dst, d, sigmaColor, sigmaSpace, borderType );
|
||||
else
|
||||
CV_Error( CV_StsUnsupportedFormat,
|
||||
"Bilateral filtering is only implemented for 8u and 32f images" );
|
||||
}
|
||||
|
||||
/* End of file. */
|
@ -2505,762 +2505,6 @@ void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
|
||||
sepFilter2D(src, dst, sdepth, kx, ky, Point(-1, -1), 0, borderType);
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
Bilateral Filtering
|
||||
\****************************************************************************************/
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
class BilateralFilter_8u_Invoker :
|
||||
public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
BilateralFilter_8u_Invoker(Mat& _dest, const Mat& _temp, int _radius, int _maxk,
|
||||
int* _space_ofs, float *_space_weight, float *_color_weight) :
|
||||
temp(&_temp), dest(&_dest), radius(_radius),
|
||||
maxk(_maxk), space_ofs(_space_ofs), space_weight(_space_weight), color_weight(_color_weight)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
int i, j, cn = dest->channels(), k;
|
||||
Size size = dest->size();
|
||||
#if CV_SIMD128
|
||||
int CV_DECL_ALIGNED(16) buf[4];
|
||||
bool haveSIMD128 = hasSIMD128();
|
||||
#endif
|
||||
|
||||
for( i = range.start; i < range.end; i++ )
|
||||
{
|
||||
const uchar* sptr = temp->ptr(i+radius) + radius*cn;
|
||||
uchar* dptr = dest->ptr(i);
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
for( j = 0; j < size.width; j++ )
|
||||
{
|
||||
float sum = 0, wsum = 0;
|
||||
int val0 = sptr[j];
|
||||
k = 0;
|
||||
#if CV_SIMD128
|
||||
if( haveSIMD128 )
|
||||
{
|
||||
v_float32x4 _val0 = v_setall_f32(static_cast<float>(val0));
|
||||
v_float32x4 vsumw = v_setzero_f32();
|
||||
v_float32x4 vsumc = v_setzero_f32();
|
||||
|
||||
for( ; k <= maxk - 4; k += 4 )
|
||||
{
|
||||
v_float32x4 _valF = v_float32x4(sptr[j + space_ofs[k]],
|
||||
sptr[j + space_ofs[k + 1]],
|
||||
sptr[j + space_ofs[k + 2]],
|
||||
sptr[j + space_ofs[k + 3]]);
|
||||
v_float32x4 _val = v_abs(_valF - _val0);
|
||||
v_store(buf, v_round(_val));
|
||||
|
||||
v_float32x4 _cw = v_float32x4(color_weight[buf[0]],
|
||||
color_weight[buf[1]],
|
||||
color_weight[buf[2]],
|
||||
color_weight[buf[3]]);
|
||||
v_float32x4 _sw = v_load(space_weight+k);
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1700/* MSVS 2012 */ && CV_AVX
|
||||
// details: https://github.com/opencv/opencv/issues/11004
|
||||
vsumw += _cw * _sw;
|
||||
vsumc += _cw * _sw * _valF;
|
||||
#else
|
||||
v_float32x4 _w = _cw * _sw;
|
||||
_cw = _w * _valF;
|
||||
|
||||
vsumw += _w;
|
||||
vsumc += _cw;
|
||||
#endif
|
||||
}
|
||||
float *bufFloat = (float*)buf;
|
||||
v_float32x4 sum4 = v_reduce_sum4(vsumw, vsumc, vsumw, vsumc);
|
||||
v_store(bufFloat, sum4);
|
||||
sum += bufFloat[1];
|
||||
wsum += bufFloat[0];
|
||||
}
|
||||
#endif
|
||||
for( ; k < maxk; k++ )
|
||||
{
|
||||
int val = sptr[j + space_ofs[k]];
|
||||
float w = space_weight[k]*color_weight[std::abs(val - val0)];
|
||||
sum += val*w;
|
||||
wsum += w;
|
||||
}
|
||||
// overflow is not possible here => there is no need to use cv::saturate_cast
|
||||
CV_DbgAssert(fabs(wsum) > 0);
|
||||
dptr[j] = (uchar)cvRound(sum/wsum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( cn == 3 );
|
||||
for( j = 0; j < size.width*3; j += 3 )
|
||||
{
|
||||
float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0;
|
||||
int b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2];
|
||||
k = 0;
|
||||
#if CV_SIMD128
|
||||
if( haveSIMD128 )
|
||||
{
|
||||
v_float32x4 vsumw = v_setzero_f32();
|
||||
v_float32x4 vsumb = v_setzero_f32();
|
||||
v_float32x4 vsumg = v_setzero_f32();
|
||||
v_float32x4 vsumr = v_setzero_f32();
|
||||
const v_float32x4 _b0 = v_setall_f32(static_cast<float>(b0));
|
||||
const v_float32x4 _g0 = v_setall_f32(static_cast<float>(g0));
|
||||
const v_float32x4 _r0 = v_setall_f32(static_cast<float>(r0));
|
||||
|
||||
for( ; k <= maxk - 4; k += 4 )
|
||||
{
|
||||
const uchar* const sptr_k0 = sptr + j + space_ofs[k];
|
||||
const uchar* const sptr_k1 = sptr + j + space_ofs[k+1];
|
||||
const uchar* const sptr_k2 = sptr + j + space_ofs[k+2];
|
||||
const uchar* const sptr_k3 = sptr + j + space_ofs[k+3];
|
||||
|
||||
v_float32x4 __b = v_cvt_f32(v_reinterpret_as_s32(v_load_expand_q(sptr_k0)));
|
||||
v_float32x4 __g = v_cvt_f32(v_reinterpret_as_s32(v_load_expand_q(sptr_k1)));
|
||||
v_float32x4 __r = v_cvt_f32(v_reinterpret_as_s32(v_load_expand_q(sptr_k2)));
|
||||
v_float32x4 __z = v_cvt_f32(v_reinterpret_as_s32(v_load_expand_q(sptr_k3)));
|
||||
v_float32x4 _b, _g, _r, _z;
|
||||
|
||||
v_transpose4x4(__b, __g, __r, __z, _b, _g, _r, _z);
|
||||
|
||||
v_float32x4 bt = v_abs(_b -_b0);
|
||||
v_float32x4 gt = v_abs(_g -_g0);
|
||||
v_float32x4 rt = v_abs(_r -_r0);
|
||||
|
||||
bt = rt + bt + gt;
|
||||
v_store(buf, v_round(bt));
|
||||
|
||||
v_float32x4 _w = v_float32x4(color_weight[buf[0]],color_weight[buf[1]],
|
||||
color_weight[buf[2]],color_weight[buf[3]]);
|
||||
v_float32x4 _sw = v_load(space_weight+k);
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1700/* MSVS 2012 */ && CV_AVX
|
||||
// details: https://github.com/opencv/opencv/issues/11004
|
||||
vsumw += _w * _sw;
|
||||
vsumb += _w * _sw * _b;
|
||||
vsumg += _w * _sw * _g;
|
||||
vsumr += _w * _sw * _r;
|
||||
#else
|
||||
_w *= _sw;
|
||||
_b *= _w;
|
||||
_g *= _w;
|
||||
_r *= _w;
|
||||
|
||||
vsumw += _w;
|
||||
vsumb += _b;
|
||||
vsumg += _g;
|
||||
vsumr += _r;
|
||||
#endif
|
||||
}
|
||||
float *bufFloat = (float*)buf;
|
||||
v_float32x4 sum4 = v_reduce_sum4(vsumw, vsumb, vsumg, vsumr);
|
||||
v_store(bufFloat, sum4);
|
||||
wsum += bufFloat[0];
|
||||
sum_b += bufFloat[1];
|
||||
sum_g += bufFloat[2];
|
||||
sum_r += bufFloat[3];
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; k < maxk; k++ )
|
||||
{
|
||||
const uchar* sptr_k = sptr + j + space_ofs[k];
|
||||
int b = sptr_k[0], g = sptr_k[1], r = sptr_k[2];
|
||||
float w = space_weight[k]*color_weight[std::abs(b - b0) +
|
||||
std::abs(g - g0) + std::abs(r - r0)];
|
||||
sum_b += b*w; sum_g += g*w; sum_r += r*w;
|
||||
wsum += w;
|
||||
}
|
||||
CV_DbgAssert(fabs(wsum) > 0);
|
||||
wsum = 1.f/wsum;
|
||||
b0 = cvRound(sum_b*wsum);
|
||||
g0 = cvRound(sum_g*wsum);
|
||||
r0 = cvRound(sum_r*wsum);
|
||||
dptr[j] = (uchar)b0; dptr[j+1] = (uchar)g0; dptr[j+2] = (uchar)r0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const Mat *temp;
|
||||
Mat *dest;
|
||||
int radius, maxk, *space_ofs;
|
||||
float *space_weight, *color_weight;
|
||||
};
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
static bool ocl_bilateralFilter_8u(InputArray _src, OutputArray _dst, int d,
|
||||
double sigma_color, double sigma_space,
|
||||
int borderType)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
if (ocl::Device::getDefault().isNVidia())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
int i, j, maxk, radius;
|
||||
|
||||
if (depth != CV_8U || cn > 4)
|
||||
return false;
|
||||
|
||||
if (sigma_color <= 0)
|
||||
sigma_color = 1;
|
||||
if (sigma_space <= 0)
|
||||
sigma_space = 1;
|
||||
|
||||
double gauss_color_coeff = -0.5 / (sigma_color * sigma_color);
|
||||
double gauss_space_coeff = -0.5 / (sigma_space * sigma_space);
|
||||
|
||||
if ( d <= 0 )
|
||||
radius = cvRound(sigma_space * 1.5);
|
||||
else
|
||||
radius = d / 2;
|
||||
radius = MAX(radius, 1);
|
||||
d = radius * 2 + 1;
|
||||
|
||||
UMat src = _src.getUMat(), dst = _dst.getUMat(), temp;
|
||||
if (src.u == dst.u)
|
||||
return false;
|
||||
|
||||
copyMakeBorder(src, temp, radius, radius, radius, radius, borderType);
|
||||
std::vector<float> _space_weight(d * d);
|
||||
std::vector<int> _space_ofs(d * d);
|
||||
float * const space_weight = &_space_weight[0];
|
||||
int * const space_ofs = &_space_ofs[0];
|
||||
|
||||
// initialize space-related bilateral filter coefficients
|
||||
for( i = -radius, maxk = 0; i <= radius; i++ )
|
||||
for( j = -radius; j <= radius; j++ )
|
||||
{
|
||||
double r = std::sqrt((double)i * i + (double)j * j);
|
||||
if ( r > radius )
|
||||
continue;
|
||||
space_weight[maxk] = (float)std::exp(r * r * gauss_space_coeff);
|
||||
space_ofs[maxk++] = (int)(i * temp.step + j * cn);
|
||||
}
|
||||
|
||||
char cvt[3][40];
|
||||
String cnstr = cn > 1 ? format("%d", cn) : "";
|
||||
String kernelName("bilateral");
|
||||
size_t sizeDiv = 1;
|
||||
if ((ocl::Device::getDefault().isIntel()) &&
|
||||
(ocl::Device::getDefault().type() == ocl::Device::TYPE_GPU))
|
||||
{
|
||||
//Intel GPU
|
||||
if (dst.cols % 4 == 0 && cn == 1) // For single channel x4 sized images.
|
||||
{
|
||||
kernelName = "bilateral_float4";
|
||||
sizeDiv = 4;
|
||||
}
|
||||
}
|
||||
ocl::Kernel k(kernelName.c_str(), ocl::imgproc::bilateral_oclsrc,
|
||||
format("-D radius=%d -D maxk=%d -D cn=%d -D int_t=%s -D uint_t=uint%s -D convert_int_t=%s"
|
||||
" -D uchar_t=%s -D float_t=%s -D convert_float_t=%s -D convert_uchar_t=%s -D gauss_color_coeff=(float)%f",
|
||||
radius, maxk, cn, ocl::typeToStr(CV_32SC(cn)), cnstr.c_str(),
|
||||
ocl::convertTypeStr(CV_8U, CV_32S, cn, cvt[0]),
|
||||
ocl::typeToStr(type), ocl::typeToStr(CV_32FC(cn)),
|
||||
ocl::convertTypeStr(CV_32S, CV_32F, cn, cvt[1]),
|
||||
ocl::convertTypeStr(CV_32F, CV_8U, cn, cvt[2]), gauss_color_coeff));
|
||||
if (k.empty())
|
||||
return false;
|
||||
|
||||
Mat mspace_weight(1, d * d, CV_32FC1, space_weight);
|
||||
Mat mspace_ofs(1, d * d, CV_32SC1, space_ofs);
|
||||
UMat ucolor_weight, uspace_weight, uspace_ofs;
|
||||
|
||||
mspace_weight.copyTo(uspace_weight);
|
||||
mspace_ofs.copyTo(uspace_ofs);
|
||||
|
||||
k.args(ocl::KernelArg::ReadOnlyNoSize(temp), ocl::KernelArg::WriteOnly(dst),
|
||||
ocl::KernelArg::PtrReadOnly(uspace_weight),
|
||||
ocl::KernelArg::PtrReadOnly(uspace_ofs));
|
||||
|
||||
size_t globalsize[2] = { (size_t)dst.cols / sizeDiv, (size_t)dst.rows };
|
||||
return k.run(2, globalsize, NULL, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
static void
|
||||
bilateralFilter_8u( const Mat& src, Mat& dst, int d,
|
||||
double sigma_color, double sigma_space,
|
||||
int borderType )
|
||||
{
|
||||
int cn = src.channels();
|
||||
int i, j, maxk, radius;
|
||||
Size size = src.size();
|
||||
|
||||
CV_Assert( (src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.data != dst.data );
|
||||
|
||||
if( sigma_color <= 0 )
|
||||
sigma_color = 1;
|
||||
if( sigma_space <= 0 )
|
||||
sigma_space = 1;
|
||||
|
||||
double gauss_color_coeff = -0.5/(sigma_color*sigma_color);
|
||||
double gauss_space_coeff = -0.5/(sigma_space*sigma_space);
|
||||
|
||||
if( d <= 0 )
|
||||
radius = cvRound(sigma_space*1.5);
|
||||
else
|
||||
radius = d/2;
|
||||
radius = MAX(radius, 1);
|
||||
d = radius*2 + 1;
|
||||
|
||||
Mat temp;
|
||||
copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );
|
||||
|
||||
std::vector<float> _color_weight(cn*256);
|
||||
std::vector<float> _space_weight(d*d);
|
||||
std::vector<int> _space_ofs(d*d);
|
||||
float* color_weight = &_color_weight[0];
|
||||
float* space_weight = &_space_weight[0];
|
||||
int* space_ofs = &_space_ofs[0];
|
||||
|
||||
// initialize color-related bilateral filter coefficients
|
||||
|
||||
for( i = 0; i < 256*cn; i++ )
|
||||
color_weight[i] = (float)std::exp(i*i*gauss_color_coeff);
|
||||
|
||||
// initialize space-related bilateral filter coefficients
|
||||
for( i = -radius, maxk = 0; i <= radius; i++ )
|
||||
{
|
||||
j = -radius;
|
||||
|
||||
for( ; j <= radius; j++ )
|
||||
{
|
||||
double r = std::sqrt((double)i*i + (double)j*j);
|
||||
if( r > radius )
|
||||
continue;
|
||||
space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff);
|
||||
space_ofs[maxk++] = (int)(i*temp.step + j*cn);
|
||||
}
|
||||
}
|
||||
|
||||
BilateralFilter_8u_Invoker body(dst, temp, radius, maxk, space_ofs, space_weight, color_weight);
|
||||
parallel_for_(Range(0, size.height), body, dst.total()/(double)(1<<16));
|
||||
}
|
||||
|
||||
|
||||
class BilateralFilter_32f_Invoker :
|
||||
public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
|
||||
BilateralFilter_32f_Invoker(int _cn, int _radius, int _maxk, int *_space_ofs,
|
||||
const Mat& _temp, Mat& _dest, float _scale_index, float *_space_weight, float *_expLUT) :
|
||||
cn(_cn), radius(_radius), maxk(_maxk), space_ofs(_space_ofs),
|
||||
temp(&_temp), dest(&_dest), scale_index(_scale_index), space_weight(_space_weight), expLUT(_expLUT)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
int i, j, k;
|
||||
Size size = dest->size();
|
||||
#if CV_SIMD128
|
||||
int CV_DECL_ALIGNED(16) idxBuf[4];
|
||||
bool haveSIMD128 = hasSIMD128();
|
||||
#endif
|
||||
|
||||
for( i = range.start; i < range.end; i++ )
|
||||
{
|
||||
const float* sptr = temp->ptr<float>(i+radius) + radius*cn;
|
||||
float* dptr = dest->ptr<float>(i);
|
||||
|
||||
if( cn == 1 )
|
||||
{
|
||||
for( j = 0; j < size.width; j++ )
|
||||
{
|
||||
float sum = 0, wsum = 0;
|
||||
float val0 = sptr[j];
|
||||
k = 0;
|
||||
#if CV_SIMD128
|
||||
if( haveSIMD128 )
|
||||
{
|
||||
v_float32x4 vecwsum = v_setzero_f32();
|
||||
v_float32x4 vecvsum = v_setzero_f32();
|
||||
const v_float32x4 _val0 = v_setall_f32(sptr[j]);
|
||||
const v_float32x4 _scale_index = v_setall_f32(scale_index);
|
||||
|
||||
for (; k <= maxk - 4; k += 4)
|
||||
{
|
||||
v_float32x4 _sw = v_load(space_weight + k);
|
||||
v_float32x4 _val = v_float32x4(sptr[j + space_ofs[k]],
|
||||
sptr[j + space_ofs[k + 1]],
|
||||
sptr[j + space_ofs[k + 2]],
|
||||
sptr[j + space_ofs[k + 3]]);
|
||||
v_float32x4 _alpha = v_abs(_val - _val0) * _scale_index;
|
||||
|
||||
v_int32x4 _idx = v_round(_alpha);
|
||||
v_store(idxBuf, _idx);
|
||||
_alpha -= v_cvt_f32(_idx);
|
||||
|
||||
v_float32x4 _explut = v_float32x4(expLUT[idxBuf[0]],
|
||||
expLUT[idxBuf[1]],
|
||||
expLUT[idxBuf[2]],
|
||||
expLUT[idxBuf[3]]);
|
||||
v_float32x4 _explut1 = v_float32x4(expLUT[idxBuf[0] + 1],
|
||||
expLUT[idxBuf[1] + 1],
|
||||
expLUT[idxBuf[2] + 1],
|
||||
expLUT[idxBuf[3] + 1]);
|
||||
|
||||
v_float32x4 _w = _sw * (_explut + (_alpha * (_explut1 - _explut)));
|
||||
_val *= _w;
|
||||
|
||||
vecwsum += _w;
|
||||
vecvsum += _val;
|
||||
}
|
||||
float *bufFloat = (float*)idxBuf;
|
||||
v_float32x4 sum4 = v_reduce_sum4(vecwsum, vecvsum, vecwsum, vecvsum);
|
||||
v_store(bufFloat, sum4);
|
||||
sum += bufFloat[1];
|
||||
wsum += bufFloat[0];
|
||||
}
|
||||
#endif
|
||||
|
||||
for( ; k < maxk; k++ )
|
||||
{
|
||||
float val = sptr[j + space_ofs[k]];
|
||||
float alpha = (float)(std::abs(val - val0)*scale_index);
|
||||
int idx = cvFloor(alpha);
|
||||
alpha -= idx;
|
||||
float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx]));
|
||||
sum += val*w;
|
||||
wsum += w;
|
||||
}
|
||||
CV_DbgAssert(fabs(wsum) > 0);
|
||||
dptr[j] = (float)(sum/wsum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Assert( cn == 3 );
|
||||
for( j = 0; j < size.width*3; j += 3 )
|
||||
{
|
||||
float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0;
|
||||
float b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2];
|
||||
k = 0;
|
||||
#if CV_SIMD128
|
||||
if( haveSIMD128 )
|
||||
{
|
||||
v_float32x4 sumw = v_setzero_f32();
|
||||
v_float32x4 sumb = v_setzero_f32();
|
||||
v_float32x4 sumg = v_setzero_f32();
|
||||
v_float32x4 sumr = v_setzero_f32();
|
||||
const v_float32x4 _b0 = v_setall_f32(b0);
|
||||
const v_float32x4 _g0 = v_setall_f32(g0);
|
||||
const v_float32x4 _r0 = v_setall_f32(r0);
|
||||
const v_float32x4 _scale_index = v_setall_f32(scale_index);
|
||||
|
||||
for( ; k <= maxk-4; k += 4 )
|
||||
{
|
||||
v_float32x4 _sw = v_load(space_weight + k);
|
||||
|
||||
const float* const sptr_k0 = sptr + j + space_ofs[k];
|
||||
const float* const sptr_k1 = sptr + j + space_ofs[k+1];
|
||||
const float* const sptr_k2 = sptr + j + space_ofs[k+2];
|
||||
const float* const sptr_k3 = sptr + j + space_ofs[k+3];
|
||||
|
||||
v_float32x4 _v0 = v_load(sptr_k0);
|
||||
v_float32x4 _v1 = v_load(sptr_k1);
|
||||
v_float32x4 _v2 = v_load(sptr_k2);
|
||||
v_float32x4 _v3 = v_load(sptr_k3);
|
||||
v_float32x4 _b, _g, _r, _dummy;
|
||||
|
||||
v_transpose4x4(_v0, _v1, _v2, _v3, _b, _g, _r, _dummy);
|
||||
|
||||
v_float32x4 _bt = v_abs(_b - _b0);
|
||||
v_float32x4 _gt = v_abs(_g - _g0);
|
||||
v_float32x4 _rt = v_abs(_r - _r0);
|
||||
v_float32x4 _alpha = _scale_index * (_bt + _gt + _rt);
|
||||
|
||||
v_int32x4 _idx = v_round(_alpha);
|
||||
v_store((int*)idxBuf, _idx);
|
||||
_alpha -= v_cvt_f32(_idx);
|
||||
|
||||
v_float32x4 _explut = v_float32x4(expLUT[idxBuf[0]],
|
||||
expLUT[idxBuf[1]],
|
||||
expLUT[idxBuf[2]],
|
||||
expLUT[idxBuf[3]]);
|
||||
v_float32x4 _explut1 = v_float32x4(expLUT[idxBuf[0] + 1],
|
||||
expLUT[idxBuf[1] + 1],
|
||||
expLUT[idxBuf[2] + 1],
|
||||
expLUT[idxBuf[3] + 1]);
|
||||
|
||||
v_float32x4 _w = _sw * (_explut + (_alpha * (_explut1 - _explut)));
|
||||
|
||||
_b *= _w;
|
||||
_g *= _w;
|
||||
_r *= _w;
|
||||
sumw += _w;
|
||||
sumb += _b;
|
||||
sumg += _g;
|
||||
sumr += _r;
|
||||
}
|
||||
v_float32x4 sum4 = v_reduce_sum4(sumw, sumb, sumg, sumr);
|
||||
float *bufFloat = (float*)idxBuf;
|
||||
v_store(bufFloat, sum4);
|
||||
wsum += bufFloat[0];
|
||||
sum_b += bufFloat[1];
|
||||
sum_g += bufFloat[2];
|
||||
sum_r += bufFloat[3];
|
||||
}
|
||||
#endif
|
||||
|
||||
for(; k < maxk; k++ )
|
||||
{
|
||||
const float* sptr_k = sptr + j + space_ofs[k];
|
||||
float b = sptr_k[0], g = sptr_k[1], r = sptr_k[2];
|
||||
float alpha = (float)((std::abs(b - b0) +
|
||||
std::abs(g - g0) + std::abs(r - r0))*scale_index);
|
||||
int idx = cvFloor(alpha);
|
||||
alpha -= idx;
|
||||
float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx]));
|
||||
sum_b += b*w; sum_g += g*w; sum_r += r*w;
|
||||
wsum += w;
|
||||
}
|
||||
CV_DbgAssert(fabs(wsum) > 0);
|
||||
wsum = 1.f/wsum;
|
||||
b0 = sum_b*wsum;
|
||||
g0 = sum_g*wsum;
|
||||
r0 = sum_r*wsum;
|
||||
dptr[j] = b0; dptr[j+1] = g0; dptr[j+2] = r0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int cn, radius, maxk, *space_ofs;
|
||||
const Mat* temp;
|
||||
Mat *dest;
|
||||
float scale_index, *space_weight, *expLUT;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
bilateralFilter_32f( const Mat& src, Mat& dst, int d,
|
||||
double sigma_color, double sigma_space,
|
||||
int borderType )
|
||||
{
|
||||
int cn = src.channels();
|
||||
int i, j, maxk, radius;
|
||||
double minValSrc=-1, maxValSrc=1;
|
||||
const int kExpNumBinsPerChannel = 1 << 12;
|
||||
int kExpNumBins = 0;
|
||||
float lastExpVal = 1.f;
|
||||
float len, scale_index;
|
||||
Size size = src.size();
|
||||
|
||||
CV_Assert( (src.type() == CV_32FC1 || src.type() == CV_32FC3) && src.data != dst.data );
|
||||
|
||||
if( sigma_color <= 0 )
|
||||
sigma_color = 1;
|
||||
if( sigma_space <= 0 )
|
||||
sigma_space = 1;
|
||||
|
||||
double gauss_color_coeff = -0.5/(sigma_color*sigma_color);
|
||||
double gauss_space_coeff = -0.5/(sigma_space*sigma_space);
|
||||
|
||||
if( d <= 0 )
|
||||
radius = cvRound(sigma_space*1.5);
|
||||
else
|
||||
radius = d/2;
|
||||
radius = MAX(radius, 1);
|
||||
d = radius*2 + 1;
|
||||
// compute the min/max range for the input image (even if multichannel)
|
||||
|
||||
minMaxLoc( src.reshape(1), &minValSrc, &maxValSrc );
|
||||
if(std::abs(minValSrc - maxValSrc) < FLT_EPSILON)
|
||||
{
|
||||
src.copyTo(dst);
|
||||
return;
|
||||
}
|
||||
|
||||
// temporary copy of the image with borders for easy processing
|
||||
Mat temp;
|
||||
copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );
|
||||
const double insteadNaNValue = -5. * sigma_color;
|
||||
patchNaNs( temp, insteadNaNValue ); // this replacement of NaNs makes the assumption that depth values are nonnegative
|
||||
// TODO: make insteadNaNValue avalible in the outside function interface to control the cases breaking the assumption
|
||||
// allocate lookup tables
|
||||
std::vector<float> _space_weight(d*d);
|
||||
std::vector<int> _space_ofs(d*d);
|
||||
float* space_weight = &_space_weight[0];
|
||||
int* space_ofs = &_space_ofs[0];
|
||||
|
||||
// assign a length which is slightly more than needed
|
||||
len = (float)(maxValSrc - minValSrc) * cn;
|
||||
kExpNumBins = kExpNumBinsPerChannel * cn;
|
||||
std::vector<float> _expLUT(kExpNumBins+2);
|
||||
float* expLUT = &_expLUT[0];
|
||||
|
||||
scale_index = kExpNumBins/len;
|
||||
|
||||
// initialize the exp LUT
|
||||
for( i = 0; i < kExpNumBins+2; i++ )
|
||||
{
|
||||
if( lastExpVal > 0.f )
|
||||
{
|
||||
double val = i / scale_index;
|
||||
expLUT[i] = (float)std::exp(val * val * gauss_color_coeff);
|
||||
lastExpVal = expLUT[i];
|
||||
}
|
||||
else
|
||||
expLUT[i] = 0.f;
|
||||
}
|
||||
|
||||
// initialize space-related bilateral filter coefficients
|
||||
for( i = -radius, maxk = 0; i <= radius; i++ )
|
||||
for( j = -radius; j <= radius; j++ )
|
||||
{
|
||||
double r = std::sqrt((double)i*i + (double)j*j);
|
||||
if( r > radius )
|
||||
continue;
|
||||
space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff);
|
||||
space_ofs[maxk++] = (int)(i*(temp.step/sizeof(float)) + j*cn);
|
||||
}
|
||||
|
||||
// parallel_for usage
|
||||
|
||||
BilateralFilter_32f_Invoker body(cn, radius, maxk, space_ofs, temp, dst, scale_index, space_weight, expLUT);
|
||||
parallel_for_(Range(0, size.height), body, dst.total()/(double)(1<<16));
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#define IPP_BILATERAL_PARALLEL 1
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
class ipp_bilateralFilterParallel: public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
ipp_bilateralFilterParallel(::ipp::IwiImage &_src, ::ipp::IwiImage &_dst, int _radius, Ipp32f _valSquareSigma, Ipp32f _posSquareSigma, ::ipp::IwiBorderType _borderType, bool *_ok):
|
||||
src(_src), dst(_dst)
|
||||
{
|
||||
pOk = _ok;
|
||||
|
||||
radius = _radius;
|
||||
valSquareSigma = _valSquareSigma;
|
||||
posSquareSigma = _posSquareSigma;
|
||||
borderType = _borderType;
|
||||
|
||||
*pOk = true;
|
||||
}
|
||||
~ipp_bilateralFilterParallel() {}
|
||||
|
||||
virtual void operator() (const Range& range) const CV_OVERRIDE
|
||||
{
|
||||
if(*pOk == false)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
::ipp::IwiTile tile = ::ipp::IwiRoi(0, range.start, dst.m_size.width, range.end - range.start);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, src, dst, radius, valSquareSigma, posSquareSigma, ::ipp::IwDefault(), borderType, tile);
|
||||
}
|
||||
catch(const ::ipp::IwException &)
|
||||
{
|
||||
*pOk = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
private:
|
||||
::ipp::IwiImage &src;
|
||||
::ipp::IwiImage &dst;
|
||||
|
||||
int radius;
|
||||
Ipp32f valSquareSigma;
|
||||
Ipp32f posSquareSigma;
|
||||
::ipp::IwiBorderType borderType;
|
||||
|
||||
bool *pOk;
|
||||
const ipp_bilateralFilterParallel& operator= (const ipp_bilateralFilterParallel&);
|
||||
};
|
||||
#endif
|
||||
|
||||
static bool ipp_bilateralFilter(Mat &src, Mat &dst, int d, double sigmaColor, double sigmaSpace, int borderType)
|
||||
{
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
int radius = IPP_MAX(((d <= 0)?cvRound(sigmaSpace*1.5):d/2), 1);
|
||||
Ipp32f valSquareSigma = (Ipp32f)((sigmaColor <= 0)?1:sigmaColor*sigmaColor);
|
||||
Ipp32f posSquareSigma = (Ipp32f)((sigmaSpace <= 0)?1:sigmaSpace*sigmaSpace);
|
||||
|
||||
// Acquire data and begin processing
|
||||
try
|
||||
{
|
||||
::ipp::IwiImage iwSrc = ippiGetImage(src);
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
::ipp::IwiBorderSize borderSize(radius);
|
||||
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
|
||||
if(!ippBorder)
|
||||
return false;
|
||||
|
||||
const int threads = ippiSuggestThreadsNum(iwDst, 2);
|
||||
if(IPP_BILATERAL_PARALLEL && threads > 1) {
|
||||
bool ok = true;
|
||||
Range range(0, (int)iwDst.m_size.height);
|
||||
ipp_bilateralFilterParallel invoker(iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ippBorder, &ok);
|
||||
if(!ok)
|
||||
return false;
|
||||
|
||||
parallel_for_(range, invoker, threads*4);
|
||||
|
||||
if(!ok)
|
||||
return false;
|
||||
} else {
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ::ipp::IwDefault(), ippBorder);
|
||||
}
|
||||
}
|
||||
catch (const ::ipp::IwException &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(d); CV_UNUSED(sigmaColor); CV_UNUSED(sigmaSpace); CV_UNUSED(borderType);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void cv::bilateralFilter( InputArray _src, OutputArray _dst, int d,
|
||||
double sigmaColor, double sigmaSpace,
|
||||
int borderType )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
_dst.create( _src.size(), _src.type() );
|
||||
|
||||
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
|
||||
ocl_bilateralFilter_8u(_src, _dst, d, sigmaColor, sigmaSpace, borderType))
|
||||
|
||||
Mat src = _src.getMat(), dst = _dst.getMat();
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_bilateralFilter(src, dst, d, sigmaColor, sigmaSpace, borderType));
|
||||
|
||||
if( src.depth() == CV_8U )
|
||||
bilateralFilter_8u( src, dst, d, sigmaColor, sigmaSpace, borderType );
|
||||
else if( src.depth() == CV_32F )
|
||||
bilateralFilter_32f( src, dst, d, sigmaColor, sigmaSpace, borderType );
|
||||
else
|
||||
CV_Error( CV_StsUnsupportedFormat,
|
||||
"Bilateral filtering is only implemented for 8u and 32f images" );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CV_IMPL void
|
||||
|
@ -3,11 +3,10 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
if(DEFINED OPENCV_INITIAL_PASS) # OpenCV build
|
||||
|
||||
add_subdirectory(bindings)
|
||||
|
||||
if(ANDROID OR APPLE_FRAMEWORK OR WINRT)
|
||||
set(__disable_python2 ON)
|
||||
set(__disable_python3 ON)
|
||||
ocv_module_disable_(python2)
|
||||
ocv_module_disable_(python3)
|
||||
return()
|
||||
elseif(BUILD_opencv_world OR (WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||
if(NOT DEFINED BUILD_opencv_python2)
|
||||
set(__disable_python2 ON)
|
||||
@ -17,6 +16,12 @@ elseif(BUILD_opencv_world OR (WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(bindings)
|
||||
|
||||
if(NOT OPENCV_SKIP_PYTHON_LOADER)
|
||||
include("./python_loader.cmake")
|
||||
endif()
|
||||
|
||||
if(__disable_python2)
|
||||
ocv_module_disable_(python2)
|
||||
endif()
|
||||
|
@ -42,6 +42,7 @@ ocv_list_filterout(opencv_hdrs "modules/.*\\\\.inl\\\\.h*")
|
||||
ocv_list_filterout(opencv_hdrs "modules/.*_inl\\\\.h*")
|
||||
ocv_list_filterout(opencv_hdrs "modules/.*\\\\.details\\\\.h*")
|
||||
ocv_list_filterout(opencv_hdrs "modules/.*\\\\.private\\\\.h*")
|
||||
ocv_list_filterout(opencv_hdrs "modules/.*/private\\\\.h*")
|
||||
ocv_list_filterout(opencv_hdrs "modules/.*/detection_based_tracker\\\\.hpp") # Conditional compilation
|
||||
if(NOT HAVE_CUDA)
|
||||
ocv_list_filterout(opencv_hdrs "modules/cuda.*")
|
||||
@ -104,6 +105,7 @@ ocv_cmake_script_append_var(PYTHON_CONFIG_SCRIPT
|
||||
|
||||
CMAKE_MODULE_LINKER_FLAGS
|
||||
CMAKE_INSTALL_PREFIX
|
||||
OPENCV_PYTHON_INSTALL_PATH
|
||||
|
||||
OpenCV_SOURCE_DIR
|
||||
|
||||
|
@ -56,8 +56,10 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
ocv_update(OPENCV_PYTHON_EXTENSION_BUILD_PATH "${LIBRARY_OUTPUT_PATH}/${MODULE_INSTALL_SUBDIR}")
|
||||
|
||||
set_target_properties(${the_module} PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${LIBRARY_OUTPUT_PATH}/${MODULE_INSTALL_SUBDIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${OPENCV_PYTHON_EXTENSION_BUILD_PATH}"
|
||||
ARCHIVE_OUTPUT_NAME ${the_module} # prevent name conflict for python2/3 outputs
|
||||
DEFINE_SYMBOL CVAPI_EXPORTS
|
||||
PREFIX ""
|
||||
@ -110,33 +112,67 @@ else()
|
||||
set(PYTHON_INSTALL_ARCHIVE ARCHIVE DESTINATION ${${PYTHON}_PACKAGES_PATH} COMPONENT python)
|
||||
endif()
|
||||
|
||||
if(DEFINED OPENCV_${PYTHON}_INSTALL_PATH)
|
||||
set(__dst "${OPENCV_${PYTHON}_INSTALL_PATH}")
|
||||
elseif(NOT INSTALL_CREATE_DISTRIB AND DEFINED ${PYTHON}_PACKAGES_PATH)
|
||||
set(__dst "${${PYTHON}_PACKAGES_PATH}")
|
||||
ocv_assert(${PYTHON}_VERSION_MAJOR)
|
||||
ocv_assert(${PYTHON}_VERSION_MINOR)
|
||||
|
||||
set(__python_loader_subdir "")
|
||||
if(NOT OPENCV_SKIP_PYTHON_LOADER)
|
||||
set(__python_loader_subdir "cv2/")
|
||||
endif()
|
||||
if(NOT __dst)
|
||||
if(DEFINED ${PYTHON}_VERSION_MAJOR)
|
||||
set(__ver "${${PYTHON}_VERSION_MAJOR}.${${PYTHON}_VERSION_MINOR}")
|
||||
elseif(DEFINED ${PYTHON}_VERSION_STRING)
|
||||
set(__ver "${${PYTHON}_VERSION_STRING}")
|
||||
|
||||
if(NOT " ${PYTHON}" STREQUAL " PYTHON" AND DEFINED OPENCV_${PYTHON}_INSTALL_PATH)
|
||||
set(__python_binary_install_path "${OPENCV_${PYTHON}_INSTALL_PATH}")
|
||||
else()
|
||||
set(__ver "unknown")
|
||||
endif()
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
set(__dst "python/${__ver}/${OpenCV_ARCH}")
|
||||
else()
|
||||
set(__dst "python/${__ver}")
|
||||
endif()
|
||||
ocv_assert(DEFINED OPENCV_PYTHON_INSTALL_PATH)
|
||||
set(__python_binary_install_path "${OPENCV_PYTHON_INSTALL_PATH}/${__python_loader_subdir}python-${${PYTHON}_VERSION_MAJOR}.${${PYTHON}_VERSION_MINOR}")
|
||||
endif()
|
||||
|
||||
install(TARGETS ${the_module}
|
||||
${PYTHON_INSTALL_CONFIGURATIONS}
|
||||
RUNTIME DESTINATION "${__dst}" COMPONENT python
|
||||
LIBRARY DESTINATION "${__dst}" COMPONENT python
|
||||
RUNTIME DESTINATION "${__python_binary_install_path}" COMPONENT python
|
||||
LIBRARY DESTINATION "${__python_binary_install_path}" COMPONENT python
|
||||
${PYTHON_INSTALL_ARCHIVE}
|
||||
)
|
||||
|
||||
if(NOT OPENCV_SKIP_PYTHON_LOADER)
|
||||
ocv_assert(DEFINED OPENCV_PYTHON_INSTALL_PATH)
|
||||
if(OpenCV_FOUND)
|
||||
set(__loader_path "${OpenCV_BINARY_DIR}/python_loader")
|
||||
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}'")
|
||||
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()
|
||||
|
||||
if(DEFINED ${PYTHON}_VERSION_MINOR)
|
||||
set(__target_config "config-${${PYTHON}_VERSION_MAJOR}.${${PYTHON}_VERSION_MINOR}.py")
|
||||
else()
|
||||
set(__target_config "config-${${PYTHON}_VERSION_MAJOR}.py")
|
||||
endif()
|
||||
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set(CMAKE_PYTHON_EXTENSION_PATH "'${OPENCV_PYTHON_EXTENSION_BUILD_PATH}/Release'") # TODO: CMAKE_BUILD_TYPE is not defined
|
||||
else()
|
||||
set(CMAKE_PYTHON_EXTENSION_PATH "'${OPENCV_PYTHON_EXTENSION_BUILD_PATH}'")
|
||||
endif()
|
||||
configure_file("${PYTHON_SOURCE_DIR}/package/template/config-x.y.py.in" "${__loader_path}/cv2/${__target_config}" @ONLY)
|
||||
|
||||
if(IS_ABSOLUTE __python_binary_install_path)
|
||||
set(CMAKE_PYTHON_EXTENSION_PATH "'${__python_binary_install_path}'")
|
||||
else()
|
||||
set(CMAKE_PYTHON_EXTENSION_PATH "os.path.join(${CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE}, '${__python_binary_install_path}')")
|
||||
endif()
|
||||
configure_file("${PYTHON_SOURCE_DIR}/package/template/config-x.y.py.in" "${__python_loader_install_tmp_path}/cv2/${__target_config}" @ONLY)
|
||||
install(FILES "${__python_loader_install_tmp_path}/cv2/${__target_config}" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/cv2/" COMPONENT python)
|
||||
endif() # NOT OPENCV_SKIP_PYTHON_LOADER
|
||||
|
||||
unset(PYTHON_SRC_DIR)
|
||||
unset(PYTHON_CVPY_PROCESS)
|
||||
unset(CVPY_SUFFIX)
|
||||
|
4
modules/python/package/.gitignore
vendored
Normal file
4
modules/python/package/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.egg-info
|
||||
*dist
|
89
modules/python/package/cv2/__init__.py
Normal file
89
modules/python/package/cv2/__init__.py
Normal file
@ -0,0 +1,89 @@
|
||||
'''
|
||||
OpenCV Python binary extension loader
|
||||
'''
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
import numpy
|
||||
import numpy.core.multiarray
|
||||
except ImportError:
|
||||
print('OpenCV bindings requires "numpy" package.')
|
||||
print('Install it via command:')
|
||||
print(' pip install numpy')
|
||||
raise
|
||||
|
||||
# TODO
|
||||
# is_x64 = sys.maxsize > 2**32
|
||||
|
||||
def bootstrap():
|
||||
import sys
|
||||
if hasattr(sys, 'OpenCV_LOADER'):
|
||||
print(sys.path)
|
||||
raise ImportError('ERROR: recursion is detected during loading of "cv2" binary extensions. Check OpenCV installation.')
|
||||
sys.OpenCV_LOADER = True
|
||||
|
||||
DEBUG = False
|
||||
if hasattr(sys, 'OpenCV_LOADER_DEBUG'):
|
||||
DEBUG = True
|
||||
|
||||
import platform
|
||||
if DEBUG: print('OpenCV loader: os.name="{}" platform.system()="{}"'.format(os.name, str(platform.system())))
|
||||
|
||||
LOADER_DIR=os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
PYTHON_EXTENSIONS_PATHS = []
|
||||
BINARIES_PATHS = []
|
||||
|
||||
g_vars = globals()
|
||||
l_vars = locals()
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
from cv2.load_config_py2 import exec_file_wrapper
|
||||
else:
|
||||
from . load_config_py3 import exec_file_wrapper
|
||||
|
||||
def load_first_config(fnames, required=True):
|
||||
for fname in fnames:
|
||||
fpath = os.path.join(LOADER_DIR, fname)
|
||||
if not os.path.exists(fpath):
|
||||
if DEBUG: print('OpenCV loader: config not found, skip: {}'.format(fpath))
|
||||
continue
|
||||
if DEBUG: print('OpenCV loader: loading config: {}'.format(fpath))
|
||||
exec_file_wrapper(fpath, g_vars, l_vars)
|
||||
return True
|
||||
if required:
|
||||
raise ImportError('OpenCV loader: missing configuration file: {}. Check OpenCV installation.'.format(fnames))
|
||||
|
||||
load_first_config(['config.py'], True)
|
||||
load_first_config([
|
||||
'config-{}.{}.py'.format(sys.version_info[0], sys.version_info[1]),
|
||||
'config-{}.py'.format(sys.version_info[0])
|
||||
], True)
|
||||
|
||||
if DEBUG: print('OpenCV loader: PYTHON_EXTENSIONS_PATHS={}'.format(str(l_vars['PYTHON_EXTENSIONS_PATHS'])))
|
||||
if DEBUG: print('OpenCV loader: BINARIES_PATHS={}'.format(str(l_vars['BINARIES_PATHS'])))
|
||||
|
||||
for p in reversed(l_vars['PYTHON_EXTENSIONS_PATHS']):
|
||||
sys.path.insert(0, p)
|
||||
|
||||
if os.name == 'nt':
|
||||
os.environ['PATH'] = ';'.join(l_vars['BINARIES_PATHS']) + ';' + os.environ.get('PATH', '')
|
||||
if DEBUG: print('OpenCV loader: PATH={}'.format(str(os.environ['PATH'])))
|
||||
else:
|
||||
# amending of LD_LIBRARY_PATH works for sub-processes only
|
||||
os.environ['LD_LIBRARY_PATH'] = ':'.join(l_vars['BINARIES_PATHS']) + ':' + os.environ.get('LD_LIBRARY_PATH', '')
|
||||
|
||||
if DEBUG: print('OpenCV loader: replacing cv2 module')
|
||||
del sys.modules['cv2']
|
||||
import cv2
|
||||
|
||||
try:
|
||||
import sys
|
||||
del sys.OpenCV_LOADER
|
||||
except:
|
||||
pass
|
||||
|
||||
if DEBUG: print('OpenCV loader: DONE')
|
||||
|
||||
bootstrap()
|
6
modules/python/package/cv2/load_config_py2.py
Normal file
6
modules/python/package/cv2/load_config_py2.py
Normal file
@ -0,0 +1,6 @@
|
||||
# flake8: noqa
|
||||
import sys
|
||||
|
||||
if sys.version_info[:2] < (3, 0):
|
||||
def exec_file_wrapper(fpath, g_vars, l_vars):
|
||||
execfile(fpath, g_vars, l_vars)
|
9
modules/python/package/cv2/load_config_py3.py
Normal file
9
modules/python/package/cv2/load_config_py3.py
Normal file
@ -0,0 +1,9 @@
|
||||
# flake8: noqa
|
||||
import os
|
||||
import sys
|
||||
|
||||
if sys.version_info[:2] >= (3, 0):
|
||||
def exec_file_wrapper(fpath, g_vars, l_vars):
|
||||
with open(fpath) as f:
|
||||
code = compile(f.read(), os.path.basename(fpath), 'exec')
|
||||
exec(code, g_vars, l_vars)
|
57
modules/python/package/setup.py
Normal file
57
modules/python/package/setup.py
Normal file
@ -0,0 +1,57 @@
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
import setuptools
|
||||
|
||||
SCRIPT_DIR=os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
def main():
|
||||
os.chdir(SCRIPT_DIR)
|
||||
|
||||
package_name = 'opencv'
|
||||
package_version = os.environ.get('OPENCV_VERSION', '4.0.0') # TODO
|
||||
|
||||
long_description = 'Open Source Computer Vision Library Python bindings' # TODO
|
||||
|
||||
setuptools.setup(
|
||||
name=package_name,
|
||||
version=package_version,
|
||||
url='https://github.com/opencv/opencv',
|
||||
license='BSD',
|
||||
description='OpenCV python bindings',
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
packages=setuptools.find_packages(),
|
||||
maintainer="OpenCV Team",
|
||||
install_requires="numpy",
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Console',
|
||||
'Intended Audience :: Developers',
|
||||
'Intended Audience :: Education',
|
||||
'Intended Audience :: Information Technology',
|
||||
'Intended Audience :: Science/Research',
|
||||
'License :: BSD License',
|
||||
'Operating System :: MacOS',
|
||||
'Operating System :: Microsoft :: Windows',
|
||||
'Operating System :: POSIX',
|
||||
'Operating System :: Unix',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: C++',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Topic :: Scientific/Engineering',
|
||||
'Topic :: Scientific/Engineering :: Image Recognition',
|
||||
'Topic :: Software Development',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
],
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
3
modules/python/package/template/config-x.y.py.in
Normal file
3
modules/python/package/template/config-x.y.py.in
Normal file
@ -0,0 +1,3 @@
|
||||
PYTHON_EXTENSIONS_PATHS = [
|
||||
@CMAKE_PYTHON_EXTENSION_PATH@
|
||||
] + PYTHON_EXTENSIONS_PATHS
|
3
modules/python/package/template/config.py.in
Normal file
3
modules/python/package/template/config.py.in
Normal file
@ -0,0 +1,3 @@
|
||||
BINARIES_PATHS = [
|
||||
@CMAKE_PYTHON_BINARIES_PATH@
|
||||
] + BINARIES_PATHS
|
54
modules/python/python_loader.cmake
Normal file
54
modules/python/python_loader.cmake
Normal file
@ -0,0 +1,54 @@
|
||||
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")
|
||||
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}'")
|
||||
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()
|
||||
|
||||
set(PYTHON_LOADER_FILES
|
||||
"setup.py" "cv2/__init__.py"
|
||||
"cv2/load_config_py2.py" "cv2/load_config_py3.py"
|
||||
)
|
||||
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)
|
||||
endforeach()
|
||||
|
||||
if(NOT OpenCV_FOUND) # Ignore "standalone" builds of Python bindings
|
||||
if(WIN32)
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "'${EXECUTABLE_OUTPUT_PATH}/Release'") # TODO: CMAKE_BUILD_TYPE is not defined
|
||||
else()
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "'${EXECUTABLE_OUTPUT_PATH}'")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "'${LIBRARY_OUTPUT_PATH}'")
|
||||
endif()
|
||||
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}')")
|
||||
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()
|
@ -432,7 +432,7 @@ class CppHeaderParser(object):
|
||||
# it means class methods, not instance methods
|
||||
decl_str = self.batch_replace(decl_str, [("static inline", ""), ("inline", ""),\
|
||||
("CV_EXPORTS_W", ""), ("CV_EXPORTS", ""), ("CV_CDECL", ""), ("CV_WRAP ", " "), ("CV_INLINE", ""),
|
||||
("CV_DEPRECATED", "")]).strip()
|
||||
("CV_DEPRECATED", ""), ("CV_DEPRECATED_EXTERNAL", "")]).strip()
|
||||
|
||||
|
||||
if decl_str.strip().startswith('virtual'):
|
||||
|
@ -84,6 +84,23 @@ class Arguments(NewOpenCVTests):
|
||||
self.assertEqual(res4, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=3 dims(-1)=1 size(-1)=3x1 type(0)=CV_32FC2 dims(0)=2 size(0)=3x1 type(0)=CV_32FC2")
|
||||
|
||||
|
||||
class SamplesFindFile(NewOpenCVTests):
|
||||
|
||||
def test_ExistedFile(self):
|
||||
res = cv.samples.findFile('lena.jpg', False)
|
||||
self.assertNotEqual(res, '')
|
||||
|
||||
def test_MissingFile(self):
|
||||
res = cv.samples.findFile('non_existed.file', False)
|
||||
self.assertEqual(res, '')
|
||||
|
||||
def test_MissingFileException(self):
|
||||
try:
|
||||
res = cv.samples.findFile('non_existed.file', True)
|
||||
self.assertEqual("Dead code", 0)
|
||||
except cv.error as _e:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
|
@ -210,7 +210,7 @@ class Builder:
|
||||
# Add extra data
|
||||
apkxmldest = check_dir(os.path.join(apkdest, "res", "xml"), create=True)
|
||||
apklibdest = check_dir(os.path.join(apkdest, "libs", abi.name), create=True)
|
||||
for ver, d in self.extra_packs + [("3.4.3", os.path.join(self.libdest, "lib"))]:
|
||||
for ver, d in self.extra_packs + [("3.4.4", os.path.join(self.libdest, "lib"))]:
|
||||
r = ET.Element("library", attrib={"version": ver})
|
||||
log.info("Adding libraries from %s", d)
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.opencv.engine"
|
||||
android:versionCode="343@ANDROID_PLATFORM_ID@"
|
||||
android:versionName="3.43">
|
||||
android:versionCode="344@ANDROID_PLATFORM_ID@"
|
||||
android:versionName="3.44">
|
||||
|
||||
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" android:targetSdkVersion="22"/>
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
|
||||
|
@ -137,7 +137,7 @@ public class OpenCVEngineService extends Service {
|
||||
|
||||
@Override
|
||||
public int getEngineVersion() throws RemoteException {
|
||||
int version = 3430;
|
||||
int version = 3440;
|
||||
try {
|
||||
version = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
|
||||
} catch (NameNotFoundException e) {
|
||||
|
@ -12,7 +12,7 @@ manually using adb tool:
|
||||
|
||||
adb install <path-to-OpenCV-sdk>/apk/OpenCV_<version>_Manager_<app_version>_<platform>.apk
|
||||
|
||||
Example: OpenCV_3.4.3-dev_Manager_3.43_armeabi-v7a.apk
|
||||
Example: OpenCV_3.4.4-dev_Manager_3.44_armeabi-v7a.apk
|
||||
|
||||
Use the list of platforms below to determine proper OpenCV Manager package for your device:
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv-parent</artifactId>
|
||||
<version>3.4.3</version>
|
||||
<version>4.0.0</version>
|
||||
</parent>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv-it</artifactId>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv-parent</artifactId>
|
||||
<version>3.4.3</version>
|
||||
<version>4.0.0</version>
|
||||
</parent>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.opencv</groupId>
|
||||
<artifactId>opencv-parent</artifactId>
|
||||
<version>3.4.3</version>
|
||||
<version>4.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>OpenCV Parent POM</name>
|
||||
<licenses>
|
||||
|
@ -134,6 +134,13 @@
|
||||
fun:_ZNK2cv7TLSDataINS_11CoreTLSDataEE18createDataInstanceEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-UMatDataAutoLockerTLS
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN2cvL21getUMatDataAutoLockerEv
|
||||
}
|
||||
|
||||
{
|
||||
OpenCV-haveOpenCL
|
||||
Memcheck:Leak
|
||||
|
@ -7,7 +7,7 @@
|
||||
:: - MSVS 2015/2017
|
||||
:: (tools are searched on default paths or environment should be pre-configured)
|
||||
@echo off
|
||||
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
|
||||
setlocal
|
||||
|
||||
set SCRIPTDIR=%~dp0
|
||||
if NOT exist "%SCRIPTDIR%\..\..\build" (
|
||||
@ -28,20 +28,20 @@ if NOT "%~x1" == ".cpp" (
|
||||
goto die
|
||||
)
|
||||
set SRC_FILENAME=%~dpnx1
|
||||
echo SRC_FILENAME=!SRC_FILENAME!
|
||||
call :dirname "!SRC_FILENAME!" SRC_DIR
|
||||
echo SRC_DIR=!SRC_DIR!
|
||||
echo SRC_FILENAME=%SRC_FILENAME%
|
||||
call :dirname "%SRC_FILENAME%" SRC_DIR
|
||||
echo SRC_DIR=%SRC_DIR%
|
||||
set "SRC_NAME=%~n1"
|
||||
echo SRC_NAME=!SRC_NAME!
|
||||
echo SRC_NAME=%SRC_NAME%
|
||||
echo ================================================================================
|
||||
|
||||
:: Path to FFMPEG binary files
|
||||
set "PATH=!PATH!;!SCRIPTDIR!\..\..\build\bin\"
|
||||
set "PATH=%PATH%;%SCRIPTDIR%\..\..\build\bin\"
|
||||
|
||||
:: Detect compiler
|
||||
cl /? >NUL 2>NUL <NUL
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
PUSHD !CD!
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
PUSHD %CD%
|
||||
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat" (
|
||||
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat"
|
||||
goto check_msvc
|
||||
@ -61,7 +61,7 @@ if !ERRORLEVEL! NEQ 0 (
|
||||
:check_msvc
|
||||
POPD
|
||||
cl /? >NUL 2>NUL <NUL
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
set "MSG=Can't detect Microsoft Visial Studio C++ compiler (cl.exe). MSVS 2015/2017 are supported only from standard locations"
|
||||
goto die
|
||||
)
|
||||
@ -69,88 +69,85 @@ if !ERRORLEVEL! NEQ 0 (
|
||||
|
||||
:: Detect CMake
|
||||
cmake --version >NUL 2>NUL
|
||||
if !ERRORLEVEL! EQU 0 (
|
||||
set CMAKE_FOUND=1
|
||||
) else (
|
||||
if exist "C:\Program Files\CMake\bin" (
|
||||
set "PATH=!PATH!;C:\Program Files\CMake\bin"
|
||||
if %ERRORLEVEL% EQU 0 GOTO :CMAKE_FOUND
|
||||
|
||||
if NOT exist "C:\Program Files\CMake\bin" GOTO CMAKE_NOT_FOUND
|
||||
set "PATH=%PATH%;C:\Program Files\CMake\bin"
|
||||
cmake --version >NUL 2>NUL
|
||||
if !ERRORLEVEL! EQU 0 (
|
||||
set CMAKE_FOUND=1
|
||||
)
|
||||
)
|
||||
)
|
||||
if NOT DEFINED CMAKE_FOUND (
|
||||
if %ERRORLEVEL% EQU 0 GOTO :CMAKE_FOUND
|
||||
|
||||
:CMAKE_NOT_FOUND
|
||||
set "MSG=CMake is required to build OpenCV samples. Download it from here: https://cmake.org/download/ and install into 'C:\Program Files\CMake'"
|
||||
goto die
|
||||
) else (
|
||||
|
||||
:CMAKE_FOUND
|
||||
set CMAKE_FOUND=1
|
||||
call :execute cmake --version
|
||||
echo CMake is detected
|
||||
)
|
||||
|
||||
:: Detect available MSVS version
|
||||
if NOT DEFINED VisualStudioVersion (
|
||||
set "MSG=Can't determine MSVS version. 'VisualStudioVersion' is not defined"
|
||||
goto die
|
||||
)
|
||||
if "!VisualStudioVersion!" == "14.0" (
|
||||
if "%VisualStudioVersion%" == "14.0" (
|
||||
set CMAKE_GENERATOR="Visual Studio 14 Win64"
|
||||
set "PATH=!PATH!;!SCRIPTDIR!\..\..\build\x64\vc14\bin\"
|
||||
set "PATH=%PATH%;%SCRIPTDIR%\..\..\build\x64\vc14\bin\"
|
||||
) else (
|
||||
if "!VisualStudioVersion!" == "15.0" (
|
||||
if "%VisualStudioVersion%" == "15.0" (
|
||||
set CMAKE_GENERATOR="Visual Studio 15 Win64"
|
||||
set "PATH=!PATH!;!SCRIPTDIR!\..\..\build\x64\vc15\bin\"
|
||||
set "PATH=%PATH%;%SCRIPTDIR%\..\..\build\x64\vc15\bin\"
|
||||
) else (
|
||||
set "MSG=Unsupported MSVS version. VisualStudioVersion=!VisualStudioVersion!"
|
||||
set "MSG=Unsupported MSVS version. VisualStudioVersion=%VisualStudioVersion%"
|
||||
goto die
|
||||
)
|
||||
)
|
||||
|
||||
set "BUILD_DIR=!SRC_DIR!\build_!SRC_NAME!"
|
||||
set "BUILD_DIR=%SRC_DIR%\build_%SRC_NAME%"
|
||||
call :set_title Create build directory
|
||||
if NOT exist "!BUILD_DIR!" ( call :execute md "!BUILD_DIR!" )
|
||||
PUSHD "!BUILD_DIR!"
|
||||
if NOT exist "!BUILD_DIR!/sample" ( call :execute md "!BUILD_DIR!/sample" )
|
||||
call :execute copy /Y "!SCRIPTDIR!/CMakeLists.example.in" "!BUILD_DIR!/sample/CMakeLists.txt"
|
||||
if NOT exist "%BUILD_DIR%" ( call :execute md "%BUILD_DIR%" )
|
||||
PUSHD "%BUILD_DIR%"
|
||||
if NOT exist "%BUILD_DIR%/sample" ( call :execute md "%BUILD_DIR%/sample" )
|
||||
call :execute copy /Y "%SCRIPTDIR%/CMakeLists.example.in" "%BUILD_DIR%/sample/CMakeLists.txt"
|
||||
|
||||
call :set_title Configuring via CMake
|
||||
call :execute cmake -G!CMAKE_GENERATOR! "!BUILD_DIR!\sample" -DEXAMPLE_NAME=!SRC_NAME! "-DEXAMPLE_FILE=!SRC_FILENAME!" "-DOpenCV_DIR=!SCRIPTDIR!\..\..\build"
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
set "MSG=CMake configuration step failed: !BUILD_DIR!"
|
||||
call :execute cmake -G%CMAKE_GENERATOR% "%BUILD_DIR%\sample" -DEXAMPLE_NAME=%SRC_NAME% "-DEXAMPLE_FILE=%SRC_FILENAME%" "-DOpenCV_DIR=%SCRIPTDIR%\..\..\build"
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
set "MSG=CMake configuration step failed: %BUILD_DIR%"
|
||||
goto die
|
||||
)
|
||||
|
||||
call :set_title Build sample project via CMake
|
||||
call :execute cmake --build . --config Release
|
||||
if !ERRORLEVEL! NEQ 0 (
|
||||
set "MSG=Build step failed: !BUILD_DIR!"
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
set "MSG=Build step failed: %BUILD_DIR%"
|
||||
goto die
|
||||
)
|
||||
|
||||
call :set_title Launch !SRC_NAME!
|
||||
if NOT exist "!BUILD_DIR!\Release\!SRC_NAME!.exe" (
|
||||
echo. "ERROR: Can't find executable file (build seems broken): !SRC_NAME!.exe"
|
||||
call :set_title Launch %SRC_NAME%
|
||||
if NOT exist "%BUILD_DIR%\Release\%SRC_NAME%.exe" (
|
||||
echo. "ERROR: Can't find executable file (build seems broken): %SRC_NAME%.exe"
|
||||
) else (
|
||||
cd "!BUILD_DIR!\Release"
|
||||
call :execute "!SRC_NAME!.exe" --help
|
||||
cd "%BUILD_DIR%\Release"
|
||||
call :execute "%SRC_NAME%.exe" --help
|
||||
echo ================================================================================
|
||||
echo ** Type '!SRC_NAME!.exe' to run sample application
|
||||
echo ** Type '!SRC_NAME!.exe --help' to get list of available options (if available)
|
||||
echo ** Type 'start ..\!SRC_NAME!.sln' to launch MSVS IDE
|
||||
echo ** Type '%SRC_NAME%.exe' to run sample application
|
||||
echo ** Type '%SRC_NAME%.exe --help' to get list of available options (if available)
|
||||
echo ** Type 'start ..\%SRC_NAME%.sln' to launch MSVS IDE
|
||||
echo ** Type 'cmake --build .. --config Release' to rebuild sample
|
||||
echo ** Type 'exit' to exit from interactive shell and open the build directory
|
||||
echo ================================================================================
|
||||
)
|
||||
|
||||
call :set_title Hands-on: !SRC_NAME!
|
||||
cmd /k echo Current directory: !CD!
|
||||
call :set_title Hands-on: %SRC_NAME%
|
||||
cmd /k echo Current directory: %CD%
|
||||
|
||||
call :set_title Done: !SRC_NAME!
|
||||
call :set_title Done: %SRC_NAME%
|
||||
echo Opening build directory with project files...
|
||||
explorer "!BUILD_DIR!"
|
||||
explorer "%BUILD_DIR%"
|
||||
|
||||
POPD
|
||||
echo Done!
|
||||
echo Done%
|
||||
|
||||
pause
|
||||
exit /B 0
|
||||
@ -166,7 +163,7 @@ exit /B 0
|
||||
|
||||
:execute
|
||||
echo =================================================================================
|
||||
setlocal enableextensions disabledelayedexpansion
|
||||
setlocal
|
||||
echo %*
|
||||
call %*
|
||||
endlocal
|
||||
|
124
samples/_winpack_run_python_sample.cmd
Normal file
124
samples/_winpack_run_python_sample.cmd
Normal file
@ -0,0 +1,124 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL
|
||||
|
||||
SET SCRIPT_DIR=%~dp0
|
||||
IF NOT EXIST "%SCRIPT_DIR%\..\..\build\setup_vars_opencv4.cmd" (
|
||||
ECHO ERROR: OpenCV Winpack installation is required
|
||||
pause
|
||||
exit
|
||||
)
|
||||
|
||||
:: Detect Python binary
|
||||
python -V 2>nul
|
||||
IF %ERRORLEVEL% EQU 0 (
|
||||
SET PYTHON=python
|
||||
GOTO :PYTHON_FOUND
|
||||
)
|
||||
|
||||
CALL :QUERY_PYTHON 3.7
|
||||
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
|
||||
CALL :QUERY_PYTHON 3.6
|
||||
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
|
||||
CALL :QUERY_PYTHON 3.5
|
||||
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
|
||||
CALL :QUERY_PYTHON 3.4
|
||||
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
|
||||
CALL :QUERY_PYTHON 2.7
|
||||
IF %ERRORLEVEL% EQU 0 GOTO :PYTHON_FOUND
|
||||
GOTO :PYTHON_NOT_FOUND
|
||||
|
||||
:QUERY_PYTHON
|
||||
SETLOCAL
|
||||
SET PY_VERSION=%1
|
||||
SET PYTHON_DIR=
|
||||
CALL :regquery "HKCU\SOFTWARE\Python\PythonCore\%PY_VERSION%\InstallPath" PYTHON_DIR
|
||||
IF EXIST "%PYTHON_DIR%\python.exe" (
|
||||
SET "PYTHON=%PYTHON_DIR%\python.exe"
|
||||
GOTO :QUERY_PYTHON_FOUND
|
||||
)
|
||||
CALL :regquery "HKLM\SOFTWARE\Python\PythonCore\%PY_VERSION%\InstallPath" PYTHON_DIR
|
||||
IF EXIST "%PYTHON_DIR%\python.exe" (
|
||||
SET "PYTHON=%PYTHON_DIR%\python.exe"
|
||||
GOTO :QUERY_PYTHON_FOUND
|
||||
)
|
||||
|
||||
::echo Python %PY_VERSION% is not detected
|
||||
ENDLOCAL
|
||||
EXIT /B 1
|
||||
|
||||
:QUERY_PYTHON_FOUND
|
||||
ECHO Found Python %PY_VERSION% from Windows Registry: %PYTHON%
|
||||
ENDLOCAL & SET PYTHON=%PYTHON%
|
||||
EXIT /B 0
|
||||
|
||||
IF exist C:\Python27-x64\python.exe (
|
||||
SET PYTHON=C:\Python27-x64\python.exe
|
||||
GOTO :PYTHON_FOUND
|
||||
)
|
||||
IF exist C:\Python27\python.exe (
|
||||
SET PYTHON=C:\Python27\python.exe
|
||||
GOTO :PYTHON_FOUND
|
||||
)
|
||||
|
||||
:PYTHON_NOT_FOUND
|
||||
ECHO ERROR: Python not found
|
||||
IF NOT DEFINED OPENCV_BATCH_MODE ( pause )
|
||||
EXIT /B
|
||||
|
||||
:PYTHON_FOUND
|
||||
ECHO Using Python: %PYTHON%
|
||||
|
||||
:: Don't generate unnecessary .pyc cache files
|
||||
SET PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
IF [%1]==[] goto rundemo
|
||||
|
||||
set SRC_FILENAME=%~dpnx1
|
||||
echo SRC_FILENAME=%SRC_FILENAME%
|
||||
call :dirname "%SRC_FILENAME%" SRC_DIR
|
||||
call :dirname "%PYTHON%" PYTHON_DIR
|
||||
PUSHD %SRC_DIR%
|
||||
CALL "%SCRIPT_DIR%\..\..\build\setup_vars_opencv4.cmd"
|
||||
ECHO Run: %*
|
||||
%PYTHON% %*
|
||||
SET result=%errorlevel%
|
||||
IF %result% NEQ 0 (
|
||||
IF NOT DEFINED OPENCV_BATCH_MODE (
|
||||
SET "PATH=%PYTHON_DIR%;%PATH%"
|
||||
echo ================================================================================
|
||||
echo ** Type 'python sample_name.py' to run sample
|
||||
echo ** Type 'exit' to exit from interactive shell and open the build directory
|
||||
echo ================================================================================
|
||||
cmd /k echo Current directory: %CD%
|
||||
)
|
||||
)
|
||||
POPD
|
||||
EXIT /B %result%
|
||||
|
||||
:rundemo
|
||||
PUSHD "%SCRIPT_DIR%\python"
|
||||
CALL "%SCRIPT_DIR%\..\..\build\setup_vars_opencv4.cmd"
|
||||
%PYTHON% demo.py
|
||||
SET result=%errorlevel%
|
||||
IF %result% NEQ 0 (
|
||||
IF NOT DEFINED OPENCV_BATCH_MODE ( pause )
|
||||
)
|
||||
POPD
|
||||
EXIT /B %result%
|
||||
|
||||
|
||||
:dirname file resultVar
|
||||
setlocal
|
||||
set _dir=%~dp1
|
||||
set _dir=%_dir:~0,-1%
|
||||
endlocal & set %2=%_dir%
|
||||
EXIT /B 0
|
||||
|
||||
:regquery name resultVar
|
||||
SETLOCAL
|
||||
FOR /F "tokens=*" %%A IN ('REG QUERY "%1" /reg:64 /ve 2^>NUL ^| FIND "REG_SZ"') DO SET _val=%%A
|
||||
IF "x%_val%x"=="xx" EXIT /B 1
|
||||
SET _val=%_val:*REG_SZ=%
|
||||
FOR /F "tokens=*" %%A IN ("%_val%") DO SET _val=%%A
|
||||
ENDLOCAL & SET %2=%_val%
|
||||
EXIT /B 0
|
@ -41,7 +41,7 @@ int main(int argc, char** argv)
|
||||
if (video.size() == 1 && isdigit(video[0]))
|
||||
capture.open(parser.get<int>("@video"));
|
||||
else
|
||||
capture.open(video);
|
||||
capture.open(samples::findFileOrKeep(video)); // keep GStreamer pipelines
|
||||
int nframes = 0;
|
||||
if (capture.isOpened())
|
||||
{
|
||||
|
@ -38,7 +38,10 @@ int main(int argc, const char** argv)
|
||||
if (file.empty())
|
||||
cap.open(camera);
|
||||
else
|
||||
{
|
||||
file = samples::findFileOrKeep(file); // ignore gstreamer pipelines
|
||||
cap.open(file.c_str());
|
||||
}
|
||||
if (!cap.isOpened())
|
||||
{
|
||||
cout << "Can not open video stream: '" << (file.empty() ? "<camera>" : file) << "'" << endl;
|
||||
|
@ -285,12 +285,31 @@ static bool readStringList( const string& filename, vector<string>& l )
|
||||
FileStorage fs(filename, FileStorage::READ);
|
||||
if( !fs.isOpened() )
|
||||
return false;
|
||||
size_t dir_pos = filename.rfind('/');
|
||||
if (dir_pos == string::npos)
|
||||
dir_pos = filename.rfind('\\');
|
||||
FileNode n = fs.getFirstTopLevelNode();
|
||||
if( n.type() != FileNode::SEQ )
|
||||
return false;
|
||||
FileNodeIterator it = n.begin(), it_end = n.end();
|
||||
for( ; it != it_end; ++it )
|
||||
l.push_back((string)*it);
|
||||
{
|
||||
string fname = (string)*it;
|
||||
if (dir_pos != string::npos)
|
||||
{
|
||||
string fpath = samples::findFile(filename.substr(0, dir_pos + 1) + fname, false);
|
||||
if (fpath.empty())
|
||||
{
|
||||
fpath = samples::findFile(fname);
|
||||
}
|
||||
fname = fpath;
|
||||
}
|
||||
else
|
||||
{
|
||||
fname = samples::findFile(fname);
|
||||
}
|
||||
l.push_back(fname);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -427,10 +446,10 @@ int main( int argc, char** argv )
|
||||
|
||||
if( !inputFilename.empty() )
|
||||
{
|
||||
if( !videofile && readStringList(inputFilename, imageList) )
|
||||
if( !videofile && readStringList(samples::findFile(inputFilename), imageList) )
|
||||
mode = CAPTURING;
|
||||
else
|
||||
capture.open(inputFilename);
|
||||
capture.open(samples::findFileOrKeep(inputFilename));
|
||||
}
|
||||
else
|
||||
capture.open(cameraId);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user