mirror of https://github.com/opencv/opencv.git
commit
22dbcf98c5
237 changed files with 2986 additions and 1656 deletions
@ -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 |
||||
|
||||
IF NOT [%1] == [] ( |
||||
%* |
||||
EXIT /B !errorlevel! |
||||
:RUN_COMMAND |
||||
SET RUN_INTERACTIVE=1 |
||||
echo %CMDCMDLINE% | find /i "%~0" >nul |
||||
IF NOT errorlevel 1 set RUN_INTERACTIVE=0 |
||||
|
||||
%* |
||||
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 |
||||
|
@ -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
|
@ -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
|
@ -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. */ |
@ -0,0 +1,4 @@ |
||||
__pycache__ |
||||
*.pyc |
||||
*.egg-info |
||||
*dist |
@ -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() |
@ -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) |
@ -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) |
@ -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() |
@ -0,0 +1,3 @@ |
||||
PYTHON_EXTENSIONS_PATHS = [ |
||||
@CMAKE_PYTHON_EXTENSION_PATH@ |
||||
] + PYTHON_EXTENSIONS_PATHS |
@ -0,0 +1,3 @@ |
||||
BINARIES_PATHS = [ |
||||
@CMAKE_PYTHON_BINARIES_PATH@ |
||||
] + BINARIES_PATHS |
@ -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() |
@ -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 |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue