feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake

1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
wangzhengyang
2022-05-10 09:54:44 +08:00
parent ecdd171c6f
commit 718c41634f
10018 changed files with 3593797 additions and 186748 deletions

View File

@ -0,0 +1,47 @@
# ----------------------------------------------------------------------------
# CMake file for python support
# ----------------------------------------------------------------------------
if(DEFINED OPENCV_INITIAL_PASS) # OpenCV build
if(ANDROID OR APPLE_FRAMEWORK OR WINRT)
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)
endif()
if(NOT DEFINED BUILD_opencv_python3)
set(__disable_python3 ON)
endif()
endif()
add_subdirectory(bindings)
add_subdirectory(test)
if(NOT OPENCV_SKIP_PYTHON_LOADER)
include("./python_loader.cmake")
message(STATUS "OpenCV Python: during development append to PYTHONPATH: ${CMAKE_BINARY_DIR}/python_loader")
endif()
if(__disable_python2)
ocv_module_disable_(python2)
endif()
if(__disable_python3)
ocv_module_disable_(python3)
endif()
if(__disable_python2 AND __disable_python3)
return()
endif()
add_subdirectory(python2)
add_subdirectory(python3)
else() # standalone build
cmake_minimum_required(VERSION 2.8.12)
project(OpenCVPython CXX C)
include("./standalone.cmake")
endif()

View File

@ -0,0 +1,132 @@
set(MODULE_NAME "python_bindings_generator")
set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
ocv_add_module(${MODULE_NAME} INTERNAL)
set(OPENCV_PYTHON_SIGNATURES_FILE "${CMAKE_CURRENT_BINARY_DIR}/pyopencv_signatures.json" CACHE INTERNAL "")
set(OPENCV_PYTHON_BINDINGS_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")
# This file is included from a subdirectory
set(PYTHON_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../")
# get list of modules to wrap
set(OPENCV_PYTHON_MODULES)
foreach(m ${OPENCV_MODULES_BUILD})
if (";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";python;" AND HAVE_${m})
list(APPEND OPENCV_PYTHON_MODULES ${m})
#message(STATUS "\t${m}")
endif()
endforeach()
set(opencv_hdrs "")
set(opencv_userdef_hdrs "")
foreach(m ${OPENCV_PYTHON_MODULES})
foreach (hdr ${OPENCV_MODULE_${m}_HEADERS})
ocv_is_subdir(is_sub "${OPENCV_MODULE_${m}_LOCATION}/include" "${hdr}")
if(is_sub)
list(APPEND opencv_hdrs "${hdr}")
endif()
endforeach()
# both wrapping and C++ implementation
file(GLOB hdr2 ${OPENCV_MODULE_${m}_LOCATION}/misc/python/python_*.hpp)
list(SORT hdr2)
list(APPEND opencv_hdrs ${hdr2})
list(APPEND opencv_userdef_hdrs ${hdr2})
file(GLOB hdr ${OPENCV_MODULE_${m}_LOCATION}/misc/python/shadow*.hpp)
list(SORT hdr)
list(APPEND opencv_hdrs ${hdr})
file(GLOB userdef_hdrs ${OPENCV_MODULE_${m}_LOCATION}/misc/python/pyopencv*.hpp)
list(SORT userdef_hdrs)
list(APPEND opencv_userdef_hdrs ${userdef_hdrs})
endforeach(m)
# header blacklist
ocv_list_filterout(opencv_hdrs "modules/.*\\\\.h$")
ocv_list_filterout(opencv_hdrs "modules/core/.*/cuda/")
ocv_list_filterout(opencv_hdrs "modules/core/.*/hal/")
ocv_list_filterout(opencv_hdrs "modules/core/.*/opencl/")
ocv_list_filterout(opencv_hdrs "modules/.+/utils/.*")
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/.*/legacy/.*")
ocv_list_filterout(opencv_hdrs "modules/.*/detection_based_tracker\\\\.hpp") # Conditional compilation
if(NOT HAVE_CUDA)
ocv_list_filterout(opencv_hdrs "modules/cuda.*")
ocv_list_filterout(opencv_hdrs "modules/cudev")
endif()
set(cv2_generated_files
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_enums.h"
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_funcs.h"
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_include.h"
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_modules.h"
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_modules_content.h"
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types_content.h"
"${OPENCV_PYTHON_SIGNATURES_FILE}"
)
string(REPLACE ";" "\n" opencv_hdrs_ "${opencv_hdrs}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs_}")
add_custom_command(
OUTPUT ${cv2_generated_files}
COMMAND "${PYTHON_DEFAULT_EXECUTABLE}" "${PYTHON_SOURCE_DIR}/src2/gen2.py" "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/headers.txt"
DEPENDS "${PYTHON_SOURCE_DIR}/src2/gen2.py"
"${PYTHON_SOURCE_DIR}/src2/hdr_parser.py"
# not a real build dependency (file(WRITE) result): ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
${opencv_hdrs}
COMMENT "Generate files for Python bindings and documentation"
)
add_custom_target(gen_opencv_python_source DEPENDS ${cv2_generated_files})
set(cv2_custom_hdr "${CMAKE_CURRENT_BINARY_DIR}/pyopencv_custom_headers.h")
set(cv2_custom_hdr_str "//user-defined headers\n")
foreach(uh ${opencv_userdef_hdrs})
set(cv2_custom_hdr_str "${cv2_custom_hdr_str}#include \"${uh}\"\n")
endforeach(uh)
if(EXISTS "${cv2_custom_hdr}")
file(READ "${cv2_custom_hdr}" __content)
else()
set(__content "")
endif()
if("${__content}" STREQUAL "${cv2_custom_hdr_str}")
# Up-to-date
else()
file(WRITE "${cv2_custom_hdr}" "${cv2_custom_hdr_str}")
endif()
unset(__content)
#
# Configuration for standalone build of Python bindings
#
set(PYTHON_CONFIG_SCRIPT "")
ocv_cmake_script_append_var(PYTHON_CONFIG_SCRIPT
CMAKE_BUILD_TYPE
BUILD_SHARED_LIBS
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CV_GCC CV_CLANG ENABLE_NOISY_WARNINGS
CMAKE_MODULE_LINKER_FLAGS
CMAKE_INSTALL_PREFIX
OPENCV_PYTHON_INSTALL_PATH
OpenCV_SOURCE_DIR
OPENCV_FORCE_PYTHON_LIBS
OPENCV_PYTHON_SKIP_LINKER_EXCLUDE_LIBS
OPENCV_PYTHON_BINDINGS_DIR
cv2_custom_hdr
cv2_generated_files
)
set(CMAKE_HELPER_SCRIPT "${CMAKE_BINARY_DIR}/opencv_python_config.cmake")
file(GENERATE OUTPUT "${CMAKE_HELPER_SCRIPT}" CONTENT "${PYTHON_CONFIG_SCRIPT}")

View File

@ -0,0 +1,267 @@
# This file is included from a subdirectory
set(PYTHON_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}")
function(ocv_add_python_files_from_path search_path)
file(GLOB_RECURSE extra_py_files
RELATIVE "${search_path}"
# Plain Python code
"${search_path}/*.py"
# Type annotations
"${search_path}/*.pyi"
)
message(DEBUG "Extra Py files for ${search_path}: ${extra_py_files}")
if(extra_py_files)
list(SORT extra_py_files)
foreach(filename ${extra_py_files})
get_filename_component(module "${filename}" DIRECTORY)
if(NOT ${module} IN_LIST extra_modules)
list(APPEND extra_modules ${module})
endif()
configure_file("${search_path}/${filename}" "${__loader_path}/cv2/${filename}" COPYONLY)
install(FILES "${search_path}/${filename}" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/cv2/${module}/" COMPONENT python)
endforeach()
message(STATUS "Found ${extra_modules} Python modules from ${search_path}")
else()
message(WARNING "Can't add Python files and modules from ${module_path}. There is no .py or .pyi files")
endif()
endfunction()
ocv_add_module(${MODULE_NAME} BINDINGS PRIVATE_REQUIRED opencv_python_bindings_generator)
include_directories(SYSTEM
"${${PYTHON}_INCLUDE_PATH}"
${${PYTHON}_NUMPY_INCLUDE_DIRS}
)
ocv_module_include_directories(
"${PYTHON_SOURCE_DIR}/src2"
"${OPENCV_PYTHON_BINDINGS_DIR}"
)
# try to use dynamic symbols linking with libpython.so
set(OPENCV_FORCE_PYTHON_LIBS OFF CACHE BOOL "")
string(REPLACE "-Wl,--no-undefined" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
if(NOT WIN32 AND NOT APPLE AND NOT OPENCV_PYTHON_SKIP_LINKER_EXCLUDE_LIBS)
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--exclude-libs=ALL")
endif()
ocv_add_library(${the_module} MODULE ${PYTHON_SOURCE_DIR}/src2/cv2.cpp ${cv2_generated_hdrs} ${opencv_userdef_hdrs} ${cv2_custom_hdr})
if(TARGET gen_opencv_python_source)
add_dependencies(${the_module} gen_opencv_python_source)
endif()
ocv_assert(${PYTHON}_VERSION_MAJOR)
ocv_assert(${PYTHON}_VERSION_MINOR)
if(${PYTHON}_LIMITED_API)
# support only python3.3+
ocv_assert(${PYTHON}_VERSION_MAJOR EQUAL 3 AND ${PYTHON}_VERSION_MINOR GREATER 2)
target_compile_definitions(${the_module} PRIVATE CVPY_DYNAMIC_INIT)
if(WIN32)
string(REPLACE
"python${${PYTHON}_VERSION_MAJOR}${${PYTHON}_VERSION_MINOR}.lib"
"python${${PYTHON}_VERSION_MAJOR}.lib"
${PYTHON}_LIBRARIES
"${${PYTHON}_LIBRARIES}")
endif()
endif()
if(APPLE)
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
elseif(WIN32 OR OPENCV_FORCE_PYTHON_LIBS)
if(${PYTHON}_DEBUG_LIBRARIES AND NOT ${PYTHON}_LIBRARIES MATCHES "optimized.*debug")
ocv_target_link_libraries(${the_module} PRIVATE debug ${${PYTHON}_DEBUG_LIBRARIES} optimized ${${PYTHON}_LIBRARIES})
else()
ocv_target_link_libraries(${the_module} PRIVATE ${${PYTHON}_LIBRARIES})
endif()
endif()
if(TARGET gen_opencv_python_source)
set(deps ${OPENCV_MODULE_${the_module}_DEPS})
list(REMOVE_ITEM deps opencv_python_bindings_generator) # don't add dummy module to target_link_libraries list
endif()
ocv_target_link_libraries(${the_module} PRIVATE ${deps})
if(DEFINED ${PYTHON}_CVPY_SUFFIX)
set(CVPY_SUFFIX "${${PYTHON}_CVPY_SUFFIX}")
else()
set(__python_ext_suffix_var "EXT_SUFFIX")
if("${${PYTHON}_VERSION_MAJOR}" STREQUAL "2")
set(__python_ext_suffix_var "SO")
endif()
execute_process(COMMAND ${${PYTHON}_EXECUTABLE} -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('${__python_ext_suffix_var}'))"
RESULT_VARIABLE PYTHON_CVPY_PROCESS
OUTPUT_VARIABLE CVPY_SUFFIX
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT PYTHON_CVPY_PROCESS EQUAL 0)
set(CVPY_SUFFIX ".so")
endif()
if(${PYTHON}_LIMITED_API)
if(WIN32)
string(REGEX REPLACE "\\.[^\\.]*\\." "." CVPY_SUFFIX "${CVPY_SUFFIX}")
else()
string(REGEX REPLACE "\\.[^\\.]*\\." ".abi${${PYTHON}_VERSION_MAJOR}." CVPY_SUFFIX "${CVPY_SUFFIX}")
endif()
endif()
endif()
ocv_update(OPENCV_PYTHON_EXTENSION_BUILD_PATH "${LIBRARY_OUTPUT_PATH}/${MODULE_INSTALL_SUBDIR}")
set_target_properties(${the_module} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${OPENCV_PYTHON_EXTENSION_BUILD_PATH}"
ARCHIVE_OUTPUT_NAME ${the_module} # prevent name conflict for python2/3 outputs
PREFIX ""
OUTPUT_NAME cv2
SUFFIX "${CVPY_SUFFIX}")
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${the_module} PROPERTIES FOLDER "bindings")
endif()
if(MSVC)
add_definitions(-DCVAPI_EXPORTS)
endif()
if((CV_GCC OR CV_CLANG) AND NOT ENABLE_NOISY_WARNINGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function")
endif()
if(MSVC AND NOT ENABLE_NOISY_WARNINGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4100") #unreferenced formal parameter
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4127") #conditional expression is constant
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4505") #unreferenced local function has been removed
string(REPLACE "/W4" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
if(MSVC)
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4996)
else()
ocv_warnings_disable(CMAKE_CXX_FLAGS
-Wdeprecated-declarations
-Woverloaded-virtual -Wunused-private-field
-Wundef # accurate guard via #pragma doesn't work (C++ preprocessor doesn't handle #pragma)
)
endif()
if(MSVC AND NOT BUILD_SHARED_LIBS)
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /DEBUG")
endif()
if(MSVC AND NOT ${PYTHON}_DEBUG_LIBRARIES)
set(PYTHON_INSTALL_CONFIGURATIONS CONFIGURATIONS Release)
else()
set(PYTHON_INSTALL_CONFIGURATIONS "")
endif()
if(WIN32)
set(PYTHON_INSTALL_ARCHIVE "")
else()
set(PYTHON_INSTALL_ARCHIVE ARCHIVE DESTINATION ${${PYTHON}_PACKAGES_PATH} COMPONENT python)
endif()
set(__python_loader_subdir "")
if(NOT OPENCV_SKIP_PYTHON_LOADER)
set(__python_loader_subdir "cv2/")
endif()
if(NOT " ${PYTHON}" STREQUAL " PYTHON"
AND NOT DEFINED OPENCV_PYTHON_INSTALL_PATH
)
if(DEFINED OPENCV_${PYTHON}_INSTALL_PATH)
set(OPENCV_PYTHON_INSTALL_PATH "${OPENCV_${PYTHON}_INSTALL_PATH}")
elseif(NOT OPENCV_SKIP_PYTHON_LOADER)
set(OPENCV_PYTHON_INSTALL_PATH "${${PYTHON}_PACKAGES_PATH}")
endif()
endif()
if(NOT OPENCV_SKIP_PYTHON_LOADER AND DEFINED OPENCV_PYTHON_INSTALL_PATH)
include("${CMAKE_CURRENT_LIST_DIR}/python_loader.cmake")
set(OPENCV_PYTHON_INSTALL_PATH_SETUPVARS "${OPENCV_PYTHON_INSTALL_PATH}" CACHE INTERNAL "")
endif()
if(OPENCV_SKIP_PYTHON_LOADER)
if(DEFINED OPENCV_${PYTHON}_INSTALL_PATH)
set(__python_binary_install_path "${OPENCV_${PYTHON}_INSTALL_PATH}")
elseif(DEFINED ${PYTHON}_PACKAGES_PATH)
set(__python_binary_install_path "${${PYTHON}_PACKAGES_PATH}")
else()
message(FATAL_ERROR "Specify 'OPENCV_${PYTHON}_INSTALL_PATH' variable")
endif()
else()
ocv_assert(DEFINED OPENCV_PYTHON_INSTALL_PATH)
if(${PYTHON}_LIMITED_API)
set(__python_binary_subdir "python-${${PYTHON}_VERSION_MAJOR}")
else()
set(__python_binary_subdir "python-${${PYTHON}_VERSION_MAJOR}.${${PYTHON}_VERSION_MINOR}")
endif()
set(__python_binary_install_path "${OPENCV_PYTHON_INSTALL_PATH}/${__python_loader_subdir}${__python_binary_subdir}")
endif()
install(TARGETS ${the_module}
${PYTHON_INSTALL_CONFIGURATIONS}
RUNTIME DESTINATION "${__python_binary_install_path}" COMPONENT python
LIBRARY DESTINATION "${__python_binary_install_path}" COMPONENT python
${PYTHON_INSTALL_ARCHIVE}
)
set(__INSTALL_PATH_${PYTHON} "${__python_binary_install_path}" CACHE INTERNAL "") # CMake status
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/")
set(OpenCV_PYTHON_LOADER_FULL_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_PYTHON_INSTALL_PATH}/cv2")
if(IS_ABSOLUTE "${OPENCV_PYTHON_INSTALL_PATH}")
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "'${OPENCV_PYTHON_INSTALL_PATH}/cv2'")
else()
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "LOADER_DIR")
endif()
if(DEFINED ${PYTHON}_VERSION_MINOR AND NOT ${PYTHON}_LIMITED_API)
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()
file(RELATIVE_PATH OpenCV_PYTHON_BINARY_RELATIVE_INSTALL_PATH "${OpenCV_PYTHON_LOADER_FULL_INSTALL_PATH}" "${CMAKE_INSTALL_PREFIX}/${__python_binary_install_path}")
set(CMAKE_PYTHON_EXTENSION_PATH "os.path.join(${CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE}, '${OpenCV_PYTHON_BINARY_RELATIVE_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)
# handle Python extra code
foreach(m ${OPENCV_MODULES_BUILD})
if (";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";python;" AND HAVE_${m}
AND EXISTS "${OPENCV_MODULE_${m}_LOCATION}/misc/python/package"
)
ocv_add_python_files_from_path("${OPENCV_MODULE_${m}_LOCATION}/misc/python/package")
endif()
endforeach(m)
if(NOT "${OCV_PYTHON_EXTRA_MODULES_PATH}" STREQUAL "")
foreach(extra_ocv_py_modules_path ${OCV_PYTHON_EXTRA_MODULES_PATH})
ocv_add_python_files_from_path(${extra_ocv_py_modules_path})
endforeach()
endif()
endif() # NOT OPENCV_SKIP_PYTHON_LOADER
unset(PYTHON_SRC_DIR)
unset(PYTHON_CVPY_PROCESS)
unset(CVPY_SUFFIX)
unset(PYTHON_INSTALL_CONFIGURATIONS)
unset(PYTHON_INSTALL_ARCHIVE)

View File

@ -0,0 +1,180 @@
'''
OpenCV Python binary extension loader
'''
import os
import importlib
import sys
__all__ = []
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 __load_extra_py_code_for_module(base, name, enable_debug_print=False):
module_name = "{}.{}".format(__name__, name)
export_module_name = "{}.{}".format(base, name)
native_module = sys.modules.pop(module_name, None)
try:
py_module = importlib.import_module(module_name)
except ImportError as err:
if enable_debug_print:
print("Can't load Python code for module:", module_name,
". Reason:", err)
# Extension doesn't contain extra py code
return False
if not hasattr(base, name):
setattr(sys.modules[base], name, py_module)
sys.modules[export_module_name] = py_module
# If it is C extension module it is already loaded by cv2 package
if native_module:
setattr(py_module, "_native", native_module)
for k, v in filter(lambda kv: not hasattr(py_module, kv[0]),
native_module.__dict__.items()):
if enable_debug_print: print(' symbol: {} = {}'.format(k, v))
setattr(py_module, k, v)
return True
def __collect_extra_submodules(enable_debug_print=False):
def modules_filter(module):
return all((
# module is not internal
not module.startswith("_"),
# it is not a file
os.path.isdir(os.path.join(_extra_submodules_init_path, module))
))
if sys.version_info[0] < 3:
if enable_debug_print:
print("Extra submodules is loaded only for Python 3")
return []
__INIT_FILE_PATH = os.path.abspath(__file__)
_extra_submodules_init_path = os.path.dirname(__INIT_FILE_PATH)
return filter(modules_filter, os.listdir(_extra_submodules_init_path))
def bootstrap():
import sys
import copy
save_sys_path = copy.copy(sys.path)
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(os.path.realpath(__file__)))
PYTHON_EXTENSIONS_PATHS = []
BINARIES_PATHS = []
g_vars = globals()
l_vars = locals()
if sys.version_info[:2] < (3, 0):
from . 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'])))
applySysPathWorkaround = False
if hasattr(sys, 'OpenCV_REPLACE_SYS_PATH_0'):
applySysPathWorkaround = True
else:
try:
BASE_DIR = os.path.dirname(LOADER_DIR)
if sys.path[0] == BASE_DIR or os.path.realpath(sys.path[0]) == BASE_DIR:
applySysPathWorkaround = True
except:
if DEBUG: print('OpenCV loader: exception during checking workaround for sys.path[0]')
pass # applySysPathWorkaround is False
for p in reversed(l_vars['PYTHON_EXTENSIONS_PATHS']):
sys.path.insert(1 if not applySysPathWorkaround else 0, p)
if os.name == 'nt':
if sys.version_info[:2] >= (3, 8): # https://github.com/python/cpython/pull/12302
for p in l_vars['BINARIES_PATHS']:
try:
os.add_dll_directory(p)
except Exception as e:
if DEBUG: print('Failed os.add_dll_directory(): '+ str(e))
pass
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("Relink everything from native cv2 module to cv2 package")
py_module = sys.modules.pop("cv2")
native_module = importlib.import_module("cv2")
sys.modules["cv2"] = py_module
setattr(py_module, "_native", native_module)
for item_name, item in filter(lambda kv: kv[0] not in ("__file__", "__loader__", "__spec__",
"__name__", "__package__"),
native_module.__dict__.items()):
if item_name not in g_vars:
g_vars[item_name] = item
sys.path = save_sys_path # multiprocessing should start from bootstrap code (https://github.com/opencv/opencv/issues/18502)
try:
del sys.OpenCV_LOADER
except Exception as e:
if DEBUG:
print("Exception during delete OpenCV_LOADER:", e)
if DEBUG: print('OpenCV loader: binary extension... OK')
for submodule in __collect_extra_submodules(DEBUG):
if __load_extra_py_code_for_module("cv2", submodule, DEBUG):
if DEBUG: print("Extra Python code for", submodule, "is loaded")
if DEBUG: print('OpenCV loader: DONE')
bootstrap()

View 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)

View 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)

View File

@ -0,0 +1 @@
from .version import get_ocv_version

View File

@ -0,0 +1,5 @@
import cv2
def get_ocv_version():
return getattr(cv2, "__version__", "unavailable")

View File

@ -0,0 +1,59 @@
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.5.4') # 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='Apache 2.0',
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 :: Apache 2.0 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 :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'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()

View File

@ -0,0 +1,3 @@
PYTHON_EXTENSIONS_PATHS = [
@CMAKE_PYTHON_EXTENSION_PATH@
] + PYTHON_EXTENSIONS_PATHS

View File

@ -0,0 +1,5 @@
import os
BINARIES_PATHS = [
@CMAKE_PYTHON_BINARIES_PATH@
] + BINARIES_PATHS

View File

@ -0,0 +1,15 @@
if(NOT PYTHON2_INCLUDE_PATH OR NOT PYTHON2_NUMPY_INCLUDE_DIRS)
ocv_module_disable(python2)
endif()
set(the_description "The python2 bindings")
set(MODULE_NAME python2)
# Buildbot requires Python 2 to be in root lib dir
set(MODULE_INSTALL_SUBDIR "")
set(PYTHON PYTHON2)
include(../common.cmake)
unset(MODULE_NAME)
unset(MODULE_INSTALL_SUBDIR)

View File

@ -0,0 +1,37 @@
if(NOT PYTHON3_INCLUDE_PATH OR NOT PYTHON3_NUMPY_INCLUDE_DIRS)
ocv_module_disable(python3)
endif()
# Problem in numpy >=1.15 <1.17
if(PYTHON3_LIMITED_API
AND NOT PYTHON3_NUMPY_VERSION VERSION_LESS "1.15"
AND PYTHON3_NUMPY_VERSION VERSION_LESS "1.17"
)
message(WARNING "Current NUMPY version (${PYTHON3_NUMPY_VERSION}) is not compatible with LIMITED_API.")
set(PYTHON3_LIMITED_API OFF)
endif()
set(the_description "The python3 bindings")
set(MODULE_NAME python3)
set(MODULE_INSTALL_SUBDIR python3)
set(_ocv_extra_modules_path ${CMAKE_CURRENT_LIST_DIR}/../package/extra_modules)
set(_old_ocv_python_extra_modules_path ${OCV_PYTHON_EXTRA_MODULES_PATH})
if("${OCV_PYTHON_EXTRA_MODULES_PATH}" STREQUAL "")
set(OCV_PYTHON_EXTRA_MODULES_PATH ${_ocv_extra_modules_path})
else()
list(APPEND OCV_PYTHON_EXTRA_MODULES_PATH ${_ocv_extra_modules_path})
endif()
unset(_ocv_extra_modules_path)
set(PYTHON PYTHON3)
include(../common.cmake)
set(OCV_PYTHON_EXTRA_MODULES_PATH ${_old_ocv_python_extra_modules_path})
unset(_old_ocv_python_extra_modules_path)
unset(MODULE_NAME)
unset(MODULE_INSTALL_SUBDIR)

View File

@ -0,0 +1,72 @@
ocv_assert(NOT OPENCV_SKIP_PYTHON_LOADER)
set(PYTHON_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}")
if(OpenCV_FOUND)
set(__loader_path "${OpenCV_BINARY_DIR}/python_loader")
message(STATUS "OpenCV Python: during development append to PYTHONPATH: ${__loader_path}")
else()
set(__loader_path "${CMAKE_BINARY_DIR}/python_loader")
endif()
set(__python_loader_install_tmp_path "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/python_loader/")
if(DEFINED OPENCV_PYTHON_INSTALL_PATH)
if(IS_ABSOLUTE "${OPENCV_PYTHON_INSTALL_PATH}")
set(OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/")
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "'${CMAKE_INSTALL_PREFIX}'")
else()
file(RELATIVE_PATH OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE "${CMAKE_INSTALL_PREFIX}/${OPENCV_PYTHON_INSTALL_PATH}/cv2" ${CMAKE_INSTALL_PREFIX})
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "os.path.join(LOADER_DIR, '${OpenCV_PYTHON_INSTALL_PATH_RELATIVE_CONFIGCMAKE}')")
endif()
else()
set(CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE "os.path.join(LOADER_DIR, 'not_installed')")
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)
# avoid using of file(COPY) to rerun CMake on changes
configure_file("${PYTHON_SOURCE_DIR}/package/${fname}" "${__loader_path}/${fname}" COPYONLY)
if(fname STREQUAL "setup.py")
if(OPENCV_PYTHON_SETUP_PY_INSTALL_PATH)
install(FILES "${PYTHON_SOURCE_DIR}/package/${fname}" DESTINATION "${OPENCV_PYTHON_SETUP_PY_INSTALL_PATH}" COMPONENT python)
endif()
elseif(DEFINED OPENCV_PYTHON_INSTALL_PATH)
install(FILES "${PYTHON_SOURCE_DIR}/package/${fname}" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/${__dir}" COMPONENT python)
endif()
endforeach()
if(NOT OpenCV_FOUND) # Ignore "standalone" builds of Python bindings
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)
# install
if(DEFINED OPENCV_PYTHON_INSTALL_PATH)
if(WIN32)
list(APPEND CMAKE_PYTHON_BINARIES_INSTALL_PATH "os.path.join(${CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE}, '${OPENCV_BIN_INSTALL_PATH}')")
else()
list(APPEND CMAKE_PYTHON_BINARIES_INSTALL_PATH "os.path.join(${CMAKE_PYTHON_EXTENSION_INSTALL_PATH_BASE}, '${OPENCV_LIB_INSTALL_PATH}')")
endif()
set(CMAKE_PYTHON_BINARIES_PATH "${CMAKE_PYTHON_BINARIES_INSTALL_PATH}")
if (WIN32 AND HAVE_CUDA)
if (DEFINED CUDA_TOOLKIT_ROOT_DIR)
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDA_TOOLKIT_ROOT_DIR}'), 'bin')")
endif()
endif()
string(REPLACE ";" ",\n " CMAKE_PYTHON_BINARIES_PATH "${CMAKE_PYTHON_BINARIES_PATH}")
configure_file("${PYTHON_SOURCE_DIR}/package/template/config.py.in" "${__python_loader_install_tmp_path}/cv2/config.py" @ONLY)
install(FILES "${__python_loader_install_tmp_path}/cv2/config.py" DESTINATION "${OPENCV_PYTHON_INSTALL_PATH}/cv2/" COMPONENT python)
endif()
endif()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,319 @@
/*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, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage 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*/
// Defines for Python 2/3 compatibility.
#ifndef __PYCOMPAT_HPP__
#define __PYCOMPAT_HPP__
#if PY_MAJOR_VERSION >= 3
// Python3 treats all ints as longs, PyInt_X functions have been removed.
#define PyInt_Check PyLong_Check
#define PyInt_CheckExact PyLong_CheckExact
#define PyInt_AsLong PyLong_AsLong
#define PyInt_AS_LONG PyLong_AS_LONG
#define PyInt_FromLong PyLong_FromLong
#define PyNumber_Int PyNumber_Long
#define PyString_FromString PyUnicode_FromString
#define PyString_FromStringAndSize PyUnicode_FromStringAndSize
#endif // PY_MAJOR >=3
static inline bool getUnicodeString(PyObject * obj, std::string &str)
{
bool res = false;
if (PyUnicode_Check(obj))
{
PyObject * bytes = PyUnicode_AsUTF8String(obj);
if (PyBytes_Check(bytes))
{
const char * raw = PyBytes_AsString(bytes);
if (raw)
{
str = std::string(raw);
res = true;
}
}
Py_XDECREF(bytes);
}
#if PY_MAJOR_VERSION < 3
else if (PyString_Check(obj))
{
const char * raw = PyString_AsString(obj);
if (raw)
{
str = std::string(raw);
res = true;
}
}
#endif
return res;
}
//==================================================================================================
#define CV_PY_FN_WITH_KW_(fn, flags) (PyCFunction)(void*)(PyCFunctionWithKeywords)(fn), (flags) | METH_VARARGS | METH_KEYWORDS
#define CV_PY_FN_NOARGS_(fn, flags) (PyCFunction)(fn), (flags) | METH_NOARGS
#define CV_PY_FN_WITH_KW(fn) CV_PY_FN_WITH_KW_(fn, 0)
#define CV_PY_FN_NOARGS(fn) CV_PY_FN_NOARGS_(fn, 0)
#define CV_PY_TO_CLASS(TYPE) \
template<> \
bool pyopencv_to(PyObject* dst, TYPE& src, const ArgInfo& info) \
{ \
if (!dst || dst == Py_None) \
return true; \
Ptr<TYPE> ptr; \
\
if (!pyopencv_to(dst, ptr, info)) return false; \
src = *ptr; \
return true; \
}
#define CV_PY_FROM_CLASS(TYPE) \
template<> \
PyObject* pyopencv_from(const TYPE& src) \
{ \
Ptr<TYPE> ptr(new TYPE()); \
\
*ptr = src; \
return pyopencv_from(ptr); \
}
#define CV_PY_TO_CLASS_PTR(TYPE) \
template<> \
bool pyopencv_to(PyObject* dst, TYPE*& src, const ArgInfo& info) \
{ \
if (!dst || dst == Py_None) \
return true; \
Ptr<TYPE> ptr; \
\
if (!pyopencv_to(dst, ptr, info)) return false; \
src = ptr; \
return true; \
}
#define CV_PY_FROM_CLASS_PTR(TYPE) \
static PyObject* pyopencv_from(TYPE*& src) \
{ \
return pyopencv_from(Ptr<TYPE>(src)); \
}
#define CV_PY_TO_ENUM(TYPE) \
template<> \
bool pyopencv_to(PyObject* dst, TYPE& src, const ArgInfo& info) \
{ \
if (!dst || dst == Py_None) \
return true; \
int underlying = 0; \
\
if (!pyopencv_to(dst, underlying, info)) return false; \
src = static_cast<TYPE>(underlying); \
return true; \
}
#define CV_PY_FROM_ENUM(TYPE) \
template<> \
PyObject* pyopencv_from(const TYPE& src) \
{ \
return pyopencv_from(static_cast<int>(src)); \
}
//==================================================================================================
#if PY_MAJOR_VERSION >= 3
#define CVPY_TYPE_HEAD PyVarObject_HEAD_INIT(&PyType_Type, 0)
#define CVPY_TYPE_INCREF(T) Py_INCREF(T)
#else
#define CVPY_TYPE_HEAD PyObject_HEAD_INIT(&PyType_Type) 0,
#define CVPY_TYPE_INCREF(T) _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA (T)->ob_refcnt++
#endif
#define CVPY_TYPE_DECLARE(WNAME, NAME, STORAGE, SNAME) \
struct pyopencv_##NAME##_t \
{ \
PyObject_HEAD \
STORAGE v; \
}; \
static PyTypeObject pyopencv_##NAME##_TypeXXX = \
{ \
CVPY_TYPE_HEAD \
MODULESTR"."#WNAME, \
sizeof(pyopencv_##NAME##_t), \
}; \
static PyTypeObject * pyopencv_##NAME##_TypePtr = &pyopencv_##NAME##_TypeXXX; \
static bool pyopencv_##NAME##_getp(PyObject * self, STORAGE * & dst) \
{ \
if (PyObject_TypeCheck(self, pyopencv_##NAME##_TypePtr)) \
{ \
dst = &(((pyopencv_##NAME##_t*)self)->v); \
return true; \
} \
return false; \
} \
static PyObject * pyopencv_##NAME##_Instance(const STORAGE &r) \
{ \
pyopencv_##NAME##_t *m = PyObject_NEW(pyopencv_##NAME##_t, pyopencv_##NAME##_TypePtr); \
new (&(m->v)) STORAGE(r); \
return (PyObject*)m; \
} \
static void pyopencv_##NAME##_dealloc(PyObject* self) \
{ \
((pyopencv_##NAME##_t*)self)->v.STORAGE::~SNAME(); \
PyObject_Del(self); \
} \
static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
{ \
char str[1000]; \
sprintf(str, "<"#WNAME" %p>", self); \
return PyString_FromString(str); \
}
#define CVPY_TYPE_INIT_STATIC(WNAME, NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
{ \
pyopencv_##NAME##_TypePtr->tp_base = pyopencv_##BASE##_TypePtr; \
pyopencv_##NAME##_TypePtr->tp_dealloc = pyopencv_##NAME##_dealloc; \
pyopencv_##NAME##_TypePtr->tp_repr = pyopencv_##NAME##_repr; \
pyopencv_##NAME##_TypePtr->tp_getset = pyopencv_##NAME##_getseters; \
pyopencv_##NAME##_TypePtr->tp_init = (initproc) CONSTRUCTOR; \
pyopencv_##NAME##_TypePtr->tp_methods = pyopencv_##NAME##_methods; \
pyopencv_##NAME##_TypePtr->tp_alloc = PyType_GenericAlloc; \
pyopencv_##NAME##_TypePtr->tp_new = PyType_GenericNew; \
pyopencv_##NAME##_TypePtr->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; \
if (PyType_Ready(pyopencv_##NAME##_TypePtr) != 0) \
{ \
ERROR_HANDLER; \
} \
CVPY_TYPE_INCREF(pyopencv_##NAME##_TypePtr); \
PyModule_AddObject(m, #WNAME, (PyObject *)pyopencv_##NAME##_TypePtr); \
}
//==================================================================================================
#define CVPY_TYPE_DECLARE_DYNAMIC(WNAME, NAME, STORAGE, SNAME) \
struct pyopencv_##NAME##_t \
{ \
PyObject_HEAD \
STORAGE v; \
}; \
static PyObject * pyopencv_##NAME##_TypePtr = 0; \
static bool pyopencv_##NAME##_getp(PyObject * self, STORAGE * & dst) \
{ \
if (PyObject_TypeCheck(self, (PyTypeObject*)pyopencv_##NAME##_TypePtr)) \
{ \
dst = &(((pyopencv_##NAME##_t*)self)->v); \
return true; \
} \
return false; \
} \
static PyObject * pyopencv_##NAME##_Instance(const STORAGE &r) \
{ \
pyopencv_##NAME##_t *m = PyObject_New(pyopencv_##NAME##_t, (PyTypeObject*)pyopencv_##NAME##_TypePtr); \
new (&(m->v)) STORAGE(r); \
return (PyObject*)m; \
} \
static void pyopencv_##NAME##_dealloc(PyObject* self) \
{ \
((pyopencv_##NAME##_t*)self)->v.STORAGE::~SNAME(); \
PyObject_Del(self); \
} \
static PyObject* pyopencv_##NAME##_repr(PyObject* self) \
{ \
char str[1000]; \
sprintf(str, "<"#WNAME" %p>", self); \
return PyString_FromString(str); \
} \
static PyType_Slot pyopencv_##NAME##_Slots[] = \
{ \
{Py_tp_dealloc, 0}, \
{Py_tp_repr, 0}, \
{Py_tp_getset, 0}, \
{Py_tp_init, 0}, \
{Py_tp_methods, 0}, \
{Py_tp_alloc, 0}, \
{Py_tp_new, 0}, \
{0, 0} \
}; \
static PyType_Spec pyopencv_##NAME##_Spec = \
{ \
MODULESTR"."#WNAME, \
sizeof(pyopencv_##NAME##_t), \
0, \
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, \
pyopencv_##NAME##_Slots \
};
#define CVPY_TYPE_INIT_DYNAMIC(WNAME, NAME, ERROR_HANDLER, BASE, CONSTRUCTOR) \
{ \
pyopencv_##NAME##_Slots[0].pfunc /*tp_dealloc*/ = (void*)pyopencv_##NAME##_dealloc; \
pyopencv_##NAME##_Slots[1].pfunc /*tp_repr*/ = (void*)pyopencv_##NAME##_repr; \
pyopencv_##NAME##_Slots[2].pfunc /*tp_getset*/ = (void*)pyopencv_##NAME##_getseters; \
pyopencv_##NAME##_Slots[3].pfunc /*tp_init*/ = (void*) CONSTRUCTOR; \
pyopencv_##NAME##_Slots[4].pfunc /*tp_methods*/ = pyopencv_##NAME##_methods; \
pyopencv_##NAME##_Slots[5].pfunc /*tp_alloc*/ = (void*)PyType_GenericAlloc; \
pyopencv_##NAME##_Slots[6].pfunc /*tp_new*/ = (void*)PyType_GenericNew; \
PyObject * bases = 0; \
if (pyopencv_##BASE##_TypePtr) \
bases = PyTuple_Pack(1, pyopencv_##BASE##_TypePtr); \
pyopencv_##NAME##_TypePtr = PyType_FromSpecWithBases(&pyopencv_##NAME##_Spec, bases); \
if (!pyopencv_##NAME##_TypePtr) \
{ \
printf("Failed to init: " #WNAME ", base (" #BASE ")" "\n"); \
ERROR_HANDLER; \
} \
PyModule_AddObject(m, #NAME, (PyObject *)pyopencv_##NAME##_TypePtr); \
}
// Debug module load:
//
// else \
// { \
// printf("Init: " #NAME ", base (" #BASE ") -> %p" "\n", pyopencv_##NAME##_TypePtr); \
// } \
#endif // END HEADER GUARD

View File

@ -0,0 +1,62 @@
if(NOT DEFINED OpenCV_BINARY_DIR)
message(FATAL_ERROR "Define OpenCV_BINARY_DIR")
endif()
include("${OpenCV_BINARY_DIR}/opencv_python_config.cmake")
if(NOT DEFINED OpenCV_SOURCE_DIR)
message(FATAL_ERROR "Missing OpenCV_SOURCE_DIR")
endif()
if(DEFINED OPENCV_PYTHON_STANDALONE_INSTALL_PATH)
set(OPENCV_PYTHON_INSTALL_PATH "${OPENCV_PYTHON_STANDALONE_INSTALL_PATH}")
elseif(NOT OPENCV_PYTHON_INSTALL_PATH)
message(FATAL_ERROR "Missing OPENCV_PYTHON_STANDALONE_INSTALL_PATH / OPENCV_PYTHON_INSTALL_PATH")
endif()
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVUtils.cmake")
set(OPENCV_PYTHON_SKIP_DETECTION ON)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectPython.cmake")
find_python("${OPENCV_PYTHON_VERSION}" "${OPENCV_PYTHON_VERSION}" PYTHON_LIBRARY PYTHON_INCLUDE_DIR
PYTHONINTERP_FOUND PYTHON_EXECUTABLE PYTHON_VERSION_STRING
PYTHON_VERSION_MAJOR PYTHON_VERSION_MINOR PYTHONLIBS_FOUND
PYTHONLIBS_VERSION_STRING PYTHON_LIBRARIES PYTHON_LIBRARY
PYTHON_DEBUG_LIBRARIES PYTHON_LIBRARY_DEBUG PYTHON_INCLUDE_PATH
PYTHON_INCLUDE_DIR PYTHON_INCLUDE_DIR2 PYTHON_PACKAGES_PATH
PYTHON_NUMPY_INCLUDE_DIRS PYTHON_NUMPY_VERSION)
if(NOT PYTHON_EXECUTABLE OR NOT PYTHON_INCLUDE_DIR)
message(FATAL_ERROR "Can't find Python development files")
endif()
if(NOT PYTHON_NUMPY_INCLUDE_DIRS)
message(FATAL_ERROR "Can't find Python 'numpy' development files")
endif()
status("-----------------------------------------------------------------")
status(" Python:")
status(" Interpreter:" "${PYTHON_EXECUTABLE} (ver ${PYTHON_VERSION_STRING})")
status(" Libraries:" "${PYTHON_LIBRARIES} (ver ${PYTHONLIBS_VERSION_STRING})")
status(" numpy:" "${PYTHON_NUMPY_INCLUDE_DIRS} (ver ${PYTHON_NUMPY_VERSION})")
status("")
status(" Install to:" "${CMAKE_INSTALL_PREFIX}")
status("-----------------------------------------------------------------")
set(OpenCV_DIR "${OpenCV_BINARY_DIR}")
find_package(OpenCV REQUIRED)
set(PYTHON PYTHON)
macro(ocv_add_module module_name)
set(the_module opencv_${module_name})
project(${the_module} CXX)
endmacro()
macro(ocv_module_include_directories module)
include_directories(${ARGN})
endmacro()
set(MODULE_NAME python)
set(MODULE_INSTALL_SUBDIR "")
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")
set(deps ${OpenCV_LIBRARIES})
include("${CMAKE_CURRENT_LIST_DIR}/common.cmake") # generate python target
# done, cleanup
unset(OPENCV_BUILD_INFO_STR CACHE) # remove from cache

View File

@ -0,0 +1,32 @@
set(MODULE_NAME "python_tests")
set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
ocv_add_module(${MODULE_NAME} INTERNAL)
set(OPENCV_PYTHON_TESTS_CONFIG_FILE_DIR "${OpenCV_BINARY_DIR}" CACHE INTERNAL "")
set(OPENCV_PYTHON_TESTS_CONFIG_FILE "${OPENCV_PYTHON_TESTS_CONFIG_FILE_DIR}/opencv_python_tests.cfg" CACHE INTERNAL "")
# get list of modules to wrap
set(OPENCV_PYTHON_MODULES)
foreach(m ${OPENCV_MODULES_BUILD})
if(";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";python.*;" AND HAVE_${m})
list(APPEND OPENCV_PYTHON_MODULES ${m})
#message(STATUS "\t${m}")
endif()
endforeach()
file(RELATIVE_PATH __loc_relative "${OPENCV_PYTHON_TESTS_CONFIG_FILE_DIR}" "${CMAKE_CURRENT_LIST_DIR}")
set(opencv_tests_locations "${__loc_relative}")
foreach(m ${OPENCV_PYTHON_MODULES})
set(__loc "${OPENCV_MODULE_${m}_LOCATION}/misc/python/test")
if(EXISTS "${__loc}")
file(RELATIVE_PATH __loc_relative "${OPENCV_PYTHON_TESTS_CONFIG_FILE_DIR}" "${__loc}")
list(APPEND opencv_tests_locations "${__loc_relative}")
endif()
endforeach(m)
string(REPLACE ";" "\n" opencv_tests_locations_ "${opencv_tests_locations}")
ocv_update_file("${OPENCV_PYTHON_TESTS_CONFIG_FILE}" "${opencv_tests_locations_}")
#
# TODO: Install rules (with test data?)
#

View File

@ -0,0 +1,60 @@
#!/usr/bin/env python
'''
Location of tests:
- <opencv_src>/modules/python/test
- <opencv_src>/modules/<module>/misc/python/test/
'''
from __future__ import print_function
import sys
sys.dont_write_bytecode = True # Don't generate .pyc files / __pycache__ directories
import os
import unittest
# Python 3 moved urlopen to urllib.requests
try:
from urllib.request import urlopen
except ImportError:
from urllib import urlopen
from tests_common import NewOpenCVTests
basedir = os.path.abspath(os.path.dirname(__file__))
def load_tests(loader, tests, pattern):
cwd = os.getcwd()
config_file = 'opencv_python_tests.cfg'
locations = [cwd, basedir]
if os.path.exists(config_file):
with open(config_file, 'r') as f:
locations += [str(s).strip() for s in f.readlines()]
else:
print('WARNING: OpenCV tests config file ({}) is missing, running subset of tests'.format(config_file))
tests_pattern = os.environ.get('OPENCV_PYTEST_FILTER', 'test_*') + '.py'
if tests_pattern != 'test_*.py':
print('Tests filter: {}'.format(tests_pattern))
processed = set()
for l in locations:
if not os.path.isabs(l):
l = os.path.normpath(os.path.join(cwd, l))
if l in processed:
continue
processed.add(l)
print('Discovering python tests from: {}'.format(l))
sys_path_modify = l not in sys.path
if sys_path_modify:
sys.path.append(l) # Hack python loader
discovered_tests = loader.discover(l, pattern=tests_pattern, top_level_dir=l)
print(' found {} tests'.format(discovered_tests.countTestCases()))
tests.addTests(loader.discover(l, pattern=tests_pattern))
if sys_path_modify:
sys.path.remove(l)
return tests
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
"""Algorithm serialization test."""
import tempfile
import os
import cv2 as cv
from tests_common import NewOpenCVTests
class algorithm_rw_test(NewOpenCVTests):
def test_algorithm_rw(self):
fd, fname = tempfile.mkstemp(prefix="opencv_python_algorithm_", suffix=".yml")
os.close(fd)
# some arbitrary non-default parameters
gold = cv.AKAZE_create(descriptor_size=1, descriptor_channels=2, nOctaves=3, threshold=4.0)
gold.write(cv.FileStorage(fname, cv.FILE_STORAGE_WRITE), "AKAZE")
fs = cv.FileStorage(fname, cv.FILE_STORAGE_READ)
algorithm = cv.AKAZE_create()
algorithm.read(fs.getNode("AKAZE"))
self.assertEqual(algorithm.getDescriptorSize(), 1)
self.assertEqual(algorithm.getDescriptorChannels(), 2)
self.assertEqual(algorithm.getNOctaves(), 3)
self.assertEqual(algorithm.getThreshold(), 4.0)
os.remove(fname)

View File

@ -0,0 +1,33 @@
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class AsyncTest(NewOpenCVTests):
def test_async_simple(self):
m = np.array([[1,2],[3,4],[5,6]])
async_result = cv.utils.testAsyncArray(m)
self.assertTrue(async_result.valid())
ret, result = async_result.get(timeoutNs=10**6) # 1ms
self.assertTrue(ret)
self.assertFalse(async_result.valid())
self.assertEqual(cv.norm(m, result, cv.NORM_INF), 0)
def test_async_exception(self):
async_result = cv.utils.testAsyncException()
self.assertTrue(async_result.valid())
try:
_ret, _result = async_result.get(timeoutNs=10**6) # 1ms
self.fail("Exception expected")
except cv.error as e:
self.assertEqual(cv.Error.StsOk, e.code)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,96 @@
#!/usr/bin/env python
'''
Camshift tracker
================
This is a demo that shows mean-shift based tracking
You select a color objects such as your face and it tracks it.
This reads from video camera (0 by default, or the camera number the user enters)
http://www.robinhewitt.com/research/track/camshift.html
'''
# Python 2/3 compatibility
from __future__ import print_function
import sys
PY3 = sys.version_info[0] == 3
if PY3:
xrange = range
import numpy as np
import cv2 as cv
from tst_scene_render import TestSceneRender
from tests_common import NewOpenCVTests, intersectionRate
class camshift_test(NewOpenCVTests):
framesNum = 300
frame = None
selection = None
drag_start = None
show_backproj = False
track_window = None
render = None
errors = 0
def prepareRender(self):
self.render = TestSceneRender(self.get_sample('samples/data/pca_test1.jpg'), deformation = True)
def runTracker(self):
framesCounter = 0
self.selection = True
xmin, ymin, xmax, ymax = self.render.getCurrentRect()
self.track_window = (xmin, ymin, xmax - xmin, ymax - ymin)
while True:
framesCounter += 1
self.frame = self.render.getNextFrame()
hsv = cv.cvtColor(self.frame, cv.COLOR_BGR2HSV)
mask = cv.inRange(hsv, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
if self.selection:
x0, y0, x1, y1 = self.render.getCurrentRect() + 50
x0 -= 100
y0 -= 100
hsv_roi = hsv[y0:y1, x0:x1]
mask_roi = mask[y0:y1, x0:x1]
hist = cv.calcHist( [hsv_roi], [0], mask_roi, [16], [0, 180] )
cv.normalize(hist, hist, 0, 255, cv.NORM_MINMAX)
self.hist = hist.reshape(-1)
self.selection = False
if self.track_window and self.track_window[2] > 0 and self.track_window[3] > 0:
self.selection = None
prob = cv.calcBackProject([hsv], [0], self.hist, [0, 180], 1)
prob &= mask
term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )
_track_box, self.track_window = cv.CamShift(prob, self.track_window, term_crit)
trackingRect = np.array(self.track_window)
trackingRect[2] += trackingRect[0]
trackingRect[3] += trackingRect[1]
if intersectionRate(self.render.getCurrentRect(), trackingRect) < 0.4:
self.errors += 1
if framesCounter > self.framesNum:
break
self.assertLess(float(self.errors) / self.framesNum, 0.4)
def test_camshift(self):
self.prepareRender()
self.runTracker()
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
'''
Test for copyto with mask
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
import sys
from tests_common import NewOpenCVTests
class copytomask_test(NewOpenCVTests):
def test_copytomask(self):
img = self.get_sample('python/images/baboon.png', cv.IMREAD_COLOR)
eps = 0.
#Create mask using inRange
valeurBGRinf = np.array([0,0,100])
valeurBGRSup = np.array([70, 70,255])
maskRed = cv.inRange(img, valeurBGRinf, valeurBGRSup)
#New binding
dstcv = np.ndarray(np.array((2, 2, 1))*img.shape, dtype=img.dtype)
dstcv.fill(255)
cv.copyTo(img, maskRed, dstcv[:img.shape[0],:img.shape[1],:])
#using numpy
dstnp = np.ndarray(np.array((2, 2, 1))*img.shape, dtype=img.dtype)
dstnp.fill(255)
mask2=maskRed.astype(bool)
_, mask_b = np.broadcast_arrays(img, mask2[..., None])
np.copyto(dstnp[:img.shape[0],:img.shape[1],:], img, where=mask_b)
self.assertEqual(cv.norm(dstnp ,dstcv), eps)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,49 @@
#!/usr/bin/env python
'''
CUDA-accelerated Computer Vision functions
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
import os
from tests_common import NewOpenCVTests, unittest
class cuda_test(NewOpenCVTests):
def setUp(self):
super(cuda_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
def test_cuda_upload_download(self):
npMat = (np.random.random((128, 128, 3)) * 255).astype(np.uint8)
cuMat = cv.cuda_GpuMat()
cuMat.upload(npMat)
self.assertTrue(np.allclose(cuMat.download(), npMat))
def test_cuda_upload_download_stream(self):
stream = cv.cuda_Stream()
npMat = (np.random.random((128, 128, 3)) * 255).astype(np.uint8)
cuMat = cv.cuda_GpuMat(128,128, cv.CV_8UC3)
cuMat.upload(npMat, stream)
npMat2 = cuMat.download(stream=stream)
stream.waitForCompletion()
self.assertTrue(np.allclose(npMat2, npMat))
def test_cuda_interop(self):
npMat = (np.random.random((128, 128, 3)) * 255).astype(np.uint8)
cuMat = cv.cuda_GpuMat()
cuMat.upload(npMat)
self.assertTrue(cuMat.cudaPtr() != 0)
stream = cv.cuda_Stream()
self.assertTrue(stream.cudaPtr() != 0)
asyncstream = cv.cuda_Stream(1) # cudaStreamNonBlocking
self.assertTrue(asyncstream.cudaPtr() != 0)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,50 @@
#!/usr/bin/env python
'''
Test for disctrete fourier transform (dft)
'''
# Python 2/3 compatibility
from __future__ import print_function
import cv2 as cv
import numpy as np
import sys
from tests_common import NewOpenCVTests
class dft_test(NewOpenCVTests):
def test_dft(self):
img = self.get_sample('samples/data/rubberwhale1.png', 0)
eps = 0.001
#test direct transform
refDft = np.fft.fft2(img)
refDftShift = np.fft.fftshift(refDft)
refMagnitide = np.log(1.0 + np.abs(refDftShift))
testDft = cv.dft(np.float32(img),flags = cv.DFT_COMPLEX_OUTPUT)
testDftShift = np.fft.fftshift(testDft)
testMagnitude = np.log(1.0 + cv.magnitude(testDftShift[:,:,0], testDftShift[:,:,1]))
refMagnitide = cv.normalize(refMagnitide, 0.0, 1.0, cv.NORM_MINMAX)
testMagnitude = cv.normalize(testMagnitude, 0.0, 1.0, cv.NORM_MINMAX)
self.assertLess(cv.norm(refMagnitide - testMagnitude), eps)
#test inverse transform
img_back = np.fft.ifft2(refDft)
img_back = np.abs(img_back)
img_backTest = cv.idft(testDft)
img_backTest = cv.magnitude(img_backTest[:,:,0], img_backTest[:,:,1])
img_backTest = cv.normalize(img_backTest, 0.0, 1.0, cv.NORM_MINMAX)
img_back = cv.normalize(img_back, 0.0, 1.0, cv.NORM_MINMAX)
self.assertLess(cv.norm(img_back - img_backTest), eps)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class Features2D_Tests(NewOpenCVTests):
def test_issue_13406(self):
self.assertEqual(True, hasattr(cv, 'drawKeypoints'))
self.assertEqual(True, hasattr(cv, 'DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS'))
self.assertEqual(True, hasattr(cv, 'DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS'))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,206 @@
#!/usr/bin/env python
"""Algorithm serialization test."""
from __future__ import print_function
import base64
import json
import tempfile
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests
class MyData:
def __init__(self):
self.A = 97
self.X = np.pi
self.name = 'mydata1234'
def write(self, fs, name):
fs.startWriteStruct(name, cv.FileNode_MAP|cv.FileNode_FLOW)
fs.write('A', self.A)
fs.write('X', self.X)
fs.write('name', self.name)
fs.endWriteStruct()
def read(self, node):
if (not node.empty()):
self.A = int(node.getNode('A').real())
self.X = node.getNode('X').real()
self.name = node.getNode('name').string()
else:
self.A = self.X = 0
self.name = ''
class filestorage_io_test(NewOpenCVTests):
strings_data = ['image1.jpg', 'Awesomeness', '../data/baboon.jpg']
R0 = np.eye(3,3)
T0 = np.zeros((3,1))
def write_data(self, fname):
fs = cv.FileStorage(fname, cv.FileStorage_WRITE)
R = self.R0
T = self.T0
m = MyData()
fs.write('iterationNr', 100)
fs.startWriteStruct('strings', cv.FileNode_SEQ)
for elem in self.strings_data:
fs.write('', elem)
fs.endWriteStruct()
fs.startWriteStruct('Mapping', cv.FileNode_MAP)
fs.write('One', 1)
fs.write('Two', 2)
fs.endWriteStruct()
fs.write('R_MAT', R)
fs.write('T_MAT', T)
m.write(fs, 'MyData')
fs.release()
def read_data_and_check(self, fname):
fs = cv.FileStorage(fname, cv.FileStorage_READ)
n = fs.getNode('iterationNr')
itNr = int(n.real())
self.assertEqual(itNr, 100)
n = fs.getNode('strings')
self.assertTrue(n.isSeq())
self.assertEqual(n.size(), len(self.strings_data))
for i in range(n.size()):
self.assertEqual(n.at(i).string(), self.strings_data[i])
n = fs.getNode('Mapping')
self.assertEqual(int(n.getNode('Two').real()), 2)
self.assertEqual(int(n.getNode('One').real()), 1)
R = fs.getNode('R_MAT').mat()
T = fs.getNode('T_MAT').mat()
self.assertEqual(cv.norm(R, self.R0, cv.NORM_INF), 0)
self.assertEqual(cv.norm(T, self.T0, cv.NORM_INF), 0)
m0 = MyData()
m = MyData()
m.read(fs.getNode('MyData'))
self.assertEqual(m.A, m0.A)
self.assertEqual(m.X, m0.X)
self.assertEqual(m.name, m0.name)
n = fs.getNode('NonExisting')
self.assertTrue(n.isNone())
fs.release()
def run_fs_test(self, ext):
fd, fname = tempfile.mkstemp(prefix="opencv_python_sample_filestorage", suffix=ext)
os.close(fd)
self.write_data(fname)
self.read_data_and_check(fname)
os.remove(fname)
def test_xml(self):
self.run_fs_test(".xml")
def test_yml(self):
self.run_fs_test(".yml")
def test_json(self):
self.run_fs_test(".json")
def test_base64(self):
fd, fname = tempfile.mkstemp(prefix="opencv_python_sample_filestorage_base64", suffix=".json")
os.close(fd)
np.random.seed(42)
self.write_base64_json(fname)
os.remove(fname)
@staticmethod
def get_normal_2d_mat():
rows = 10
cols = 20
cn = 3
image = np.zeros((rows, cols, cn), np.uint8)
image[:] = (1, 2, 127)
for i in range(rows):
for j in range(cols):
image[i, j, 1] = (i + j) % 256
return image
@staticmethod
def get_normal_nd_mat():
shape = (2, 2, 1, 2)
cn = 4
image = np.zeros(shape + (cn,), np.float64)
image[:] = (0.888, 0.111, 0.666, 0.444)
return image
@staticmethod
def get_empty_2d_mat():
shape = (0, 0)
cn = 1
image = np.zeros(shape + (cn,), np.uint8)
return image
@staticmethod
def get_random_mat():
rows = 8
cols = 16
cn = 1
image = np.random.rand(rows, cols, cn)
return image
@staticmethod
def decode(data):
# strip $base64$
encoded = data[8:]
if len(encoded) == 0:
return b''
# strip info about datatype and padding
return base64.b64decode(encoded)[24:]
def write_base64_json(self, fname):
fs = cv.FileStorage(fname, cv.FileStorage_WRITE_BASE64)
mats = {'normal_2d_mat': self.get_normal_2d_mat(),
'normal_nd_mat': self.get_normal_nd_mat(),
'empty_2d_mat': self.get_empty_2d_mat(),
'random_mat': self.get_random_mat()}
for name, mat in mats.items():
fs.write(name, mat)
fs.release()
data = {}
with open(fname) as file:
data = json.load(file)
for name, mat in mats.items():
buffer = b''
if mat.size != 0:
if hasattr(mat, 'tobytes'):
buffer = mat.tobytes()
else:
buffer = mat.tostring()
self.assertEqual(buffer, self.decode(data[name]['data']))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,70 @@
#!/usr/bin/env python
'''
Robust line fitting.
==================
Example of using cv.fitLine function for fitting line
to points in presence of outliers.
Switch through different M-estimator functions and see,
how well the robust functions fit the line even
in case of ~50% of outliers.
'''
# Python 2/3 compatibility
from __future__ import print_function
import sys
PY3 = sys.version_info[0] == 3
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
w, h = 512, 256
def toint(p):
return tuple(map(int, p))
def sample_line(p1, p2, n, noise=0.0):
np.random.seed(10)
p1 = np.float32(p1)
t = np.random.rand(n,1)
return p1 + (p2-p1)*t + np.random.normal(size=(n, 2))*noise
dist_func_names = ['DIST_L2', 'DIST_L1', 'DIST_L12', 'DIST_FAIR', 'DIST_WELSCH', 'DIST_HUBER']
class fitline_test(NewOpenCVTests):
def test_fitline(self):
noise = 5
n = 200
r = 5 / 100.0
outn = int(n*r)
p0, p1 = (90, 80), (w-90, h-80)
line_points = sample_line(p0, p1, n-outn, noise)
outliers = np.random.rand(outn, 2) * (w, h)
points = np.vstack([line_points, outliers])
lines = []
for name in dist_func_names:
func = getattr(cv, name)
vx, vy, cx, cy = cv.fitLine(np.float32(points), func, 0, 0.01, 0.01)
line = [float(vx), float(vy), float(cx), float(cy)]
lines.append(line)
eps = 0.05
refVec = (np.float32(p1) - p0) / cv.norm(np.float32(p1) - p0)
for i in range(len(lines)):
self.assertLessEqual(cv.norm(refVec - lines[i][0:2], cv.NORM_L2), eps)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,41 @@
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
import os
import datetime
from tests_common import NewOpenCVTests
class get_cache_dir_test(NewOpenCVTests):
def test_get_cache_dir(self):
#New binding
path = cv.utils.fs.getCacheDirectoryForDownloads()
self.assertTrue(os.path.exists(path))
self.assertTrue(os.path.isdir(path))
def get_cache_dir_imread_interop(self, ext):
path = cv.utils.fs.getCacheDirectoryForDownloads()
gold_image = np.ones((16, 16, 3), np.uint8)
read_from_file = np.zeros((16, 16, 3), np.uint8)
test_file_name = os.path.join(path, "test." + ext)
try:
cv.imwrite(test_file_name, gold_image)
read_from_file = cv.imread(test_file_name)
finally:
os.remove(test_file_name)
self.assertEqual(cv.norm(gold_image, read_from_file), 0)
def test_get_cache_dir_imread_interop_png(self):
self.get_cache_dir_imread_interop("png")
def test_get_cache_dir_imread_interop_jpeg(self):
self.get_cache_dir_imread_interop("jpg")
def test_get_cache_dir_imread_interop_tiff(self):
self.get_cache_dir_imread_interop("tif")
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,64 @@
#!/usr/bin/env python
# Python 2/3 compatibility
from __future__ import print_function
import sys
PY3 = sys.version_info[0] == 3
if PY3:
xrange = range
import numpy as np
from numpy import random
import cv2 as cv
def make_gaussians(cluster_n, img_size):
points = []
ref_distrs = []
for _ in xrange(cluster_n):
mean = (0.1 + 0.8*random.rand(2)) * img_size
a = (random.rand(2, 2)-0.5)*img_size*0.1
cov = np.dot(a.T, a) + img_size*0.05*np.eye(2)
n = 100 + random.randint(900)
pts = random.multivariate_normal(mean, cov, n)
points.append( pts )
ref_distrs.append( (mean, cov) )
points = np.float32( np.vstack(points) )
return points, ref_distrs
from tests_common import NewOpenCVTests
class gaussian_mix_test(NewOpenCVTests):
def test_gaussian_mix(self):
np.random.seed(10)
cluster_n = 5
img_size = 512
points, ref_distrs = make_gaussians(cluster_n, img_size)
em = cv.ml.EM_create()
em.setClustersNumber(cluster_n)
em.setCovarianceMatrixType(cv.ml.EM_COV_MAT_GENERIC)
em.trainEM(points)
means = em.getMeans()
covs = em.getCovs() # Known bug: https://github.com/opencv/opencv/pull/4232
#found_distrs = zip(means, covs)
matches_count = 0
meanEps = 0.05
covEps = 0.1
for i in range(cluster_n):
for j in range(cluster_n):
if (cv.norm(means[i] - ref_distrs[j][0], cv.NORM_L2) / cv.norm(ref_distrs[j][0], cv.NORM_L2) < meanEps and
cv.norm(covs[i] - ref_distrs[j][1], cv.NORM_L2) / cv.norm(ref_distrs[j][1], cv.NORM_L2) < covEps):
matches_count += 1
self.assertEqual(matches_count, cluster_n)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,71 @@
#!/usr/bin/env python
'''
===============================================================================
Interactive Image Segmentation using GrabCut algorithm.
===============================================================================
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
import sys
from tests_common import NewOpenCVTests
class grabcut_test(NewOpenCVTests):
def verify(self, mask, exp):
maxDiffRatio = 0.02
expArea = np.count_nonzero(exp)
nonIntersectArea = np.count_nonzero(mask != exp)
curRatio = float(nonIntersectArea) / expArea
return curRatio < maxDiffRatio
def scaleMask(self, mask):
return np.where((mask==cv.GC_FGD) + (mask==cv.GC_PR_FGD),255,0).astype('uint8')
def test_grabcut(self):
img = self.get_sample('cv/shared/airplane.png')
mask_prob = self.get_sample("cv/grabcut/mask_probpy.png", 0)
exp_mask1 = self.get_sample("cv/grabcut/exp_mask1py.png", 0)
exp_mask2 = self.get_sample("cv/grabcut/exp_mask2py.png", 0)
if img is None:
self.assertTrue(False, 'Missing test data')
rect = (24, 126, 459, 168)
mask = np.zeros(img.shape[:2], dtype = np.uint8)
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
cv.grabCut(img, mask, rect, bgdModel, fgdModel, 0, cv.GC_INIT_WITH_RECT)
cv.grabCut(img, mask, rect, bgdModel, fgdModel, 2, cv.GC_EVAL)
if mask_prob is None:
mask_prob = mask.copy()
cv.imwrite(self.extraTestDataPath + '/cv/grabcut/mask_probpy.png', mask_prob)
if exp_mask1 is None:
exp_mask1 = self.scaleMask(mask)
cv.imwrite(self.extraTestDataPath + '/cv/grabcut/exp_mask1py.png', exp_mask1)
self.assertEqual(self.verify(self.scaleMask(mask), exp_mask1), True)
mask = mask_prob
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
cv.grabCut(img, mask, rect, bgdModel, fgdModel, 0, cv.GC_INIT_WITH_MASK)
cv.grabCut(img, mask, rect, bgdModel, fgdModel, 1, cv.GC_EVAL)
if exp_mask2 is None:
exp_mask2 = self.scaleMask(mask)
cv.imwrite(self.extraTestDataPath + '/cv/grabcut/exp_mask2py.png', exp_mask2)
self.assertEqual(self.verify(self.scaleMask(mask), exp_mask2), True)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,131 @@
#!/usr/bin/python
'''
This example illustrates how to use cv.HoughCircles() function.
'''
# Python 2/3 compatibility
from __future__ import print_function
import cv2 as cv
import numpy as np
import sys
from numpy import pi, sin, cos
from tests_common import NewOpenCVTests
def circleApproximation(circle):
nPoints = 30
dPhi = 2*pi / nPoints
contour = []
for i in range(nPoints):
contour.append(([circle[0] + circle[2]*cos(i*dPhi),
circle[1] + circle[2]*sin(i*dPhi)]))
return np.array(contour).astype(int)
def convContoursIntersectiponRate(c1, c2):
s1 = cv.contourArea(c1)
s2 = cv.contourArea(c2)
s, _ = cv.intersectConvexConvex(c1, c2)
return 2*s/(s1+s2)
class houghcircles_test(NewOpenCVTests):
def test_houghcircles(self):
fn = "samples/data/board.jpg"
src = self.get_sample(fn, 1)
img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
img = cv.medianBlur(img, 5)
circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 10, np.array([]), 100, 30, 1, 30)[0]
testCircles = [[38, 181, 17.6],
[99.7, 166, 13.12],
[142.7, 160, 13.52],
[223.6, 110, 8.62],
[79.1, 206.7, 8.62],
[47.5, 351.6, 11.64],
[189.5, 354.4, 11.64],
[189.8, 298.9, 10.64],
[189.5, 252.4, 14.62],
[252.5, 393.4, 15.62],
[602.9, 467.5, 11.42],
[222, 210.4, 9.12],
[263.1, 216.7, 9.12],
[359.8, 222.6, 9.12],
[518.9, 120.9, 9.12],
[413.8, 113.4, 9.12],
[489, 127.2, 9.12],
[448.4, 121.3, 9.12],
[384.6, 128.9, 8.62]]
matches_counter = 0
for i in range(len(testCircles)):
for j in range(len(circles)):
tstCircle = circleApproximation(testCircles[i])
circle = circleApproximation(circles[j])
if convContoursIntersectiponRate(tstCircle, circle) > 0.6:
matches_counter += 1
self.assertGreater(float(matches_counter) / len(testCircles), .5)
self.assertLess(float(len(circles) - matches_counter) / len(circles), .75)
def test_houghcircles_alt(self):
fn = "samples/data/board.jpg"
src = self.get_sample(fn, 1)
img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
img = cv.medianBlur(img, 5)
circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT_ALT, 1, 10, np.array([]), 300, 0.9, 1, 30)
self.assertEqual(circles.shape, (1, 18, 3))
circles = circles[0]
testCircles = [[38, 181, 17.6],
[99.7, 166, 13.12],
[142.7, 160, 13.52],
[223.6, 110, 8.62],
[79.1, 206.7, 8.62],
[47.5, 351.6, 11.64],
[189.5, 354.4, 11.64],
[189.8, 298.9, 10.64],
[189.5, 252.4, 14.62],
[252.5, 393.4, 15.62],
[602.9, 467.5, 11.42],
[222, 210.4, 9.12],
[263.1, 216.7, 9.12],
[359.8, 222.6, 9.12],
[518.9, 120.9, 9.12],
[413.8, 113.4, 9.12],
[489, 127.2, 9.12],
[448.4, 121.3, 9.12],
[384.6, 128.9, 8.62]]
matches_counter = 0
for i in range(len(testCircles)):
for j in range(len(circles)):
tstCircle = circleApproximation(testCircles[i])
circle = circleApproximation(circles[j])
if convContoursIntersectiponRate(tstCircle, circle) > 0.6:
matches_counter += 1
self.assertGreater(float(matches_counter) / len(testCircles), .5)
self.assertLess(float(len(circles) - matches_counter) / len(circles), .75)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,72 @@
#!/usr/bin/python
'''
This example illustrates how to use Hough Transform to find lines
'''
# Python 2/3 compatibility
from __future__ import print_function
import cv2 as cv
import numpy as np
import sys
import math
from tests_common import NewOpenCVTests
def linesDiff(line1, line2):
norm1 = cv.norm(line1 - line2, cv.NORM_L2)
line3 = line1[2:4] + line1[0:2]
norm2 = cv.norm(line3 - line2, cv.NORM_L2)
return min(norm1, norm2)
class houghlines_test(NewOpenCVTests):
def test_houghlines(self):
fn = "/samples/data/pic1.png"
src = self.get_sample(fn)
dst = cv.Canny(src, 50, 200)
lines = cv.HoughLinesP(dst, 1, math.pi/180.0, 40, np.array([]), 50, 10)[:,0,:]
eps = 5
testLines = [
#rect1
[ 232, 25, 43, 25],
[ 43, 129, 232, 129],
[ 43, 129, 43, 25],
[232, 129, 232, 25],
#rect2
[251, 86, 314, 183],
[252, 86, 323, 40],
[315, 183, 386, 137],
[324, 40, 386, 136],
#triangle
[245, 205, 377, 205],
[244, 206, 305, 278],
[306, 279, 377, 205],
#rect3
[153, 177, 196, 177],
[153, 277, 153, 179],
[153, 277, 196, 277],
[196, 177, 196, 277]]
matches_counter = 0
for i in range(len(testLines)):
for j in range(len(lines)):
if linesDiff(testLines[i], lines[j]) < eps:
matches_counter += 1
self.assertGreater(float(matches_counter) / len(testLines), .7)
lines_acc = cv.HoughLinesWithAccumulator(dst, rho=1, theta=np.pi / 180, threshold=150, srn=0, stn=0)
self.assertEqual(lines_acc[0,0,2], 192.0)
self.assertEqual(lines_acc[1,0,2], 187.0)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,74 @@
#!/usr/bin/env python
'''
K-means clusterization test
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
from numpy import random
import sys
PY3 = sys.version_info[0] == 3
if PY3:
xrange = range
from tests_common import NewOpenCVTests
def make_gaussians(cluster_n, img_size):
points = []
ref_distrs = []
sizes = []
for _ in xrange(cluster_n):
mean = (0.1 + 0.8*random.rand(2)) * img_size
a = (random.rand(2, 2)-0.5)*img_size*0.1
cov = np.dot(a.T, a) + img_size*0.05*np.eye(2)
n = 100 + random.randint(900)
pts = random.multivariate_normal(mean, cov, n)
points.append( pts )
ref_distrs.append( (mean, cov) )
sizes.append(n)
points = np.float32( np.vstack(points) )
return points, ref_distrs, sizes
def getMainLabelConfidence(labels, nLabels):
n = len(labels)
labelsDict = dict.fromkeys(range(nLabels), 0)
labelsConfDict = dict.fromkeys(range(nLabels))
for i in range(n):
labelsDict[labels[i][0]] += 1
for i in range(nLabels):
labelsConfDict[i] = float(labelsDict[i]) / n
return max(labelsConfDict.values())
class kmeans_test(NewOpenCVTests):
def test_kmeans(self):
np.random.seed(10)
cluster_n = 5
img_size = 512
points, _, clusterSizes = make_gaussians(cluster_n, img_size)
term_crit = (cv.TERM_CRITERIA_EPS, 30, 0.1)
_ret, labels, centers = cv.kmeans(points, cluster_n, None, term_crit, 10, 0)
self.assertEqual(len(centers), cluster_n)
offset = 0
for i in range(cluster_n):
confidence = getMainLabelConfidence(labels[offset : (offset + clusterSizes[i])], cluster_n)
offset += clusterSizes[i]
self.assertGreater(confidence, 0.9)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,94 @@
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class Hackathon244Tests(NewOpenCVTests):
def test_int_array(self):
a = np.array([-1, 2, -3, 4, -5])
absa0 = np.abs(a)
self.assertTrue(cv.norm(a, cv.NORM_L1) == 15)
absa1 = cv.absdiff(a, 0)
self.assertEqual(cv.norm(absa1, absa0, cv.NORM_INF), 0)
def test_imencode(self):
a = np.zeros((480, 640), dtype=np.uint8)
flag, ajpg = cv.imencode("img_q90.jpg", a, [cv.IMWRITE_JPEG_QUALITY, 90])
self.assertEqual(flag, True)
self.assertEqual(ajpg.dtype, np.uint8)
self.assertTrue(isinstance(ajpg, np.ndarray), "imencode returned buffer of wrong type: {}".format(type(ajpg)))
self.assertEqual(len(ajpg.shape), 1, "imencode returned buffer with wrong shape: {}".format(ajpg.shape))
self.assertGreaterEqual(len(ajpg), 1, "imencode length of the returned buffer should be at least 1")
self.assertLessEqual(
len(ajpg), a.size,
"imencode length of the returned buffer shouldn't exceed number of elements in original image"
)
def test_projectPoints(self):
objpt = np.float64([[1,2,3]])
imgpt0, jac0 = cv.projectPoints(objpt, np.zeros(3), np.zeros(3), np.eye(3), np.float64([]))
imgpt1, jac1 = cv.projectPoints(objpt, np.zeros(3), np.zeros(3), np.eye(3), None)
self.assertEqual(imgpt0.shape, (objpt.shape[0], 1, 2))
self.assertEqual(imgpt1.shape, imgpt0.shape)
self.assertEqual(jac0.shape, jac1.shape)
self.assertEqual(jac0.shape[0], 2*objpt.shape[0])
def test_estimateAffine3D(self):
pattern_size = (11, 8)
pattern_points = np.zeros((np.prod(pattern_size), 3), np.float32)
pattern_points[:,:2] = np.indices(pattern_size).T.reshape(-1, 2)
pattern_points *= 10
(retval, out, inliers) = cv.estimateAffine3D(pattern_points, pattern_points)
self.assertEqual(retval, 1)
if cv.norm(out[2,:]) < 1e-3:
out[2,2]=1
self.assertLess(cv.norm(out, np.float64([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]])), 1e-3)
self.assertEqual(cv.countNonZero(inliers), pattern_size[0]*pattern_size[1])
def test_fast(self):
fd = cv.FastFeatureDetector_create(30, True)
img = self.get_sample("samples/data/right02.jpg", 0)
img = cv.medianBlur(img, 3)
keypoints = fd.detect(img)
self.assertTrue(600 <= len(keypoints) <= 700)
for kpt in keypoints:
self.assertNotEqual(kpt.response, 0)
def check_close_angles(self, a, b, angle_delta):
self.assertTrue(abs(a - b) <= angle_delta or
abs(360 - abs(a - b)) <= angle_delta)
def check_close_pairs(self, a, b, delta):
self.assertLessEqual(abs(a[0] - b[0]), delta)
self.assertLessEqual(abs(a[1] - b[1]), delta)
def check_close_boxes(self, a, b, delta, angle_delta):
self.check_close_pairs(a[0], b[0], delta)
self.check_close_pairs(a[1], b[1], delta)
self.check_close_angles(a[2], b[2], angle_delta)
def test_geometry(self):
npt = 100
np.random.seed(244)
a = np.random.randn(npt,2).astype('float32')*50 + 150
be = cv.fitEllipse(a)
br = cv.minAreaRect(a)
mc, mr = cv.minEnclosingCircle(a)
be0 = ((150.2511749267578, 150.77322387695312), (158.024658203125, 197.57696533203125), 37.57804489135742)
br0 = ((161.2974090576172, 154.41793823242188), (207.7177734375, 199.2301483154297), 80.83544921875)
mc0, mr0 = (160.41790771484375, 144.55152893066406), 136.713500977
self.check_close_boxes(be, be0, 5, 15)
self.check_close_boxes(br, br0, 5, 15)
self.check_close_pairs(mc, mc0, 5)
self.assertLessEqual(abs(mr - mr0), 5)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,131 @@
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
import cv2 as cv
import os
import sys
import unittest
from tests_common import NewOpenCVTests
try:
if sys.version_info[:2] < (3, 0):
raise unittest.SkipTest('Python 2.x is not supported')
class MatTest(NewOpenCVTests):
def test_mat_construct(self):
data = np.random.random([10, 10, 3])
#print(np.ndarray.__dictoffset__) # 0
#print(cv.Mat.__dictoffset__) # 88 (> 0)
#print(cv.Mat) # <class cv2.Mat>
#print(cv.Mat.__base__) # <class 'numpy.ndarray'>
mat_data0 = cv.Mat(data)
assert isinstance(mat_data0, cv.Mat)
assert isinstance(mat_data0, np.ndarray)
self.assertEqual(mat_data0.wrap_channels, False)
res0 = cv.utils.dumpInputArray(mat_data0)
self.assertEqual(res0, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=300 dims(-1)=3 size(-1)=[10 10 3] type(-1)=CV_64FC1")
mat_data1 = cv.Mat(data, wrap_channels=True)
assert isinstance(mat_data1, cv.Mat)
assert isinstance(mat_data1, np.ndarray)
self.assertEqual(mat_data1.wrap_channels, True)
res1 = cv.utils.dumpInputArray(mat_data1)
self.assertEqual(res1, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=100 dims(-1)=2 size(-1)=10x10 type(-1)=CV_64FC3")
mat_data2 = cv.Mat(mat_data1)
assert isinstance(mat_data2, cv.Mat)
assert isinstance(mat_data2, np.ndarray)
self.assertEqual(mat_data2.wrap_channels, True) # fail if __array_finalize__ doesn't work
res2 = cv.utils.dumpInputArray(mat_data2)
self.assertEqual(res2, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=100 dims(-1)=2 size(-1)=10x10 type(-1)=CV_64FC3")
def test_mat_construct_4d(self):
data = np.random.random([5, 10, 10, 3])
mat_data0 = cv.Mat(data)
assert isinstance(mat_data0, cv.Mat)
assert isinstance(mat_data0, np.ndarray)
self.assertEqual(mat_data0.wrap_channels, False)
res0 = cv.utils.dumpInputArray(mat_data0)
self.assertEqual(res0, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=1500 dims(-1)=4 size(-1)=[5 10 10 3] type(-1)=CV_64FC1")
mat_data1 = cv.Mat(data, wrap_channels=True)
assert isinstance(mat_data1, cv.Mat)
assert isinstance(mat_data1, np.ndarray)
self.assertEqual(mat_data1.wrap_channels, True)
res1 = cv.utils.dumpInputArray(mat_data1)
self.assertEqual(res1, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=500 dims(-1)=3 size(-1)=[5 10 10] type(-1)=CV_64FC3")
mat_data2 = cv.Mat(mat_data1)
assert isinstance(mat_data2, cv.Mat)
assert isinstance(mat_data2, np.ndarray)
self.assertEqual(mat_data2.wrap_channels, True) # __array_finalize__ doesn't work
res2 = cv.utils.dumpInputArray(mat_data2)
self.assertEqual(res2, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=500 dims(-1)=3 size(-1)=[5 10 10] type(-1)=CV_64FC3")
def test_mat_wrap_channels_fail(self):
data = np.random.random([2, 3, 4, 520])
mat_data0 = cv.Mat(data)
assert isinstance(mat_data0, cv.Mat)
assert isinstance(mat_data0, np.ndarray)
self.assertEqual(mat_data0.wrap_channels, False)
res0 = cv.utils.dumpInputArray(mat_data0)
self.assertEqual(res0, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=12480 dims(-1)=4 size(-1)=[2 3 4 520] type(-1)=CV_64FC1")
with self.assertRaises(cv.error):
mat_data1 = cv.Mat(data, wrap_channels=True) # argument unable to wrap channels, too high (520 > CV_CN_MAX=512)
res1 = cv.utils.dumpInputArray(mat_data1)
print(mat_data1.__dict__)
print(res1)
def test_ufuncs(self):
data = np.arange(10)
mat_data = cv.Mat(data)
mat_data2 = 2 * mat_data
self.assertEqual(type(mat_data2), cv.Mat)
np.testing.assert_equal(2 * data, 2 * mat_data)
def test_comparison(self):
# Undefined behavior, do NOT use that.
# Behavior may be changed in the future
data = np.ones((10, 10, 3))
mat_wrapped = cv.Mat(data, wrap_channels=True)
mat_simple = cv.Mat(data)
np.testing.assert_equal(mat_wrapped, mat_simple) # ???: wrap_channels is not checked for now
np.testing.assert_equal(data, mat_simple)
np.testing.assert_equal(data, mat_wrapped)
#self.assertEqual(mat_wrapped, mat_simple) # ???
#self.assertTrue(mat_wrapped == mat_simple) # ???
#self.assertTrue((mat_wrapped == mat_simple).all())
except unittest.SkipTest as e:
message = str(e)
class TestSkip(unittest.TestCase):
def setUp(self):
self.skipTest('Skip tests: ' + message)
def test_skip():
pass
pass
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,638 @@
#!/usr/bin/env python
from __future__ import print_function
import ctypes
from functools import partial
from collections import namedtuple
import sys
if sys.version_info[0] < 3:
from collections import Sequence
else:
from collections.abc import Sequence
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests, unittest
def is_numeric(dtype):
return np.issubdtype(dtype, np.integer) or np.issubdtype(dtype, np.floating)
def get_limits(dtype):
if not is_numeric(dtype):
return None, None
if np.issubdtype(dtype, np.integer):
info = np.iinfo(dtype)
else:
info = np.finfo(dtype)
return info.min, info.max
def get_conversion_error_msg(value, expected, actual):
return 'Conversion "{}" of type "{}" failed\nExpected: "{}" vs Actual "{}"'.format(
value, type(value).__name__, expected, actual
)
def get_no_exception_msg(value):
return 'Exception is not risen for {} of type {}'.format(value, type(value).__name__)
class Bindings(NewOpenCVTests):
def test_inheritance(self):
bm = cv.StereoBM_create()
bm.getPreFilterCap() # from StereoBM
bm.getBlockSize() # from SteroMatcher
boost = cv.ml.Boost_create()
boost.getBoostType() # from ml::Boost
boost.getMaxDepth() # from ml::DTrees
boost.isClassifier() # from ml::StatModel
def test_raiseGeneralException(self):
with self.assertRaises((cv.error,),
msg='C++ exception is not propagated to Python in the right way') as cm:
cv.utils.testRaiseGeneralException()
self.assertEqual(str(cm.exception), 'exception text')
def test_redirectError(self):
try:
cv.imshow("", None) # This causes an assert
self.assertEqual("Dead code", 0)
except cv.error as _e:
pass
handler_called = [False]
def test_error_handler(status, func_name, err_msg, file_name, line):
handler_called[0] = True
cv.redirectError(test_error_handler)
try:
cv.imshow("", None) # This causes an assert
self.assertEqual("Dead code", 0)
except cv.error as _e:
self.assertEqual(handler_called[0], True)
pass
cv.redirectError(None)
try:
cv.imshow("", None) # This causes an assert
self.assertEqual("Dead code", 0)
except cv.error as _e:
pass
def test_overload_resolution_can_choose_correct_overload(self):
val = 123
point = (51, 165)
self.assertEqual(cv.utils.testOverloadResolution(val, point),
'overload (int={}, point=(x={}, y={}))'.format(val, *point),
"Can't select first overload if all arguments are provided as positional")
self.assertEqual(cv.utils.testOverloadResolution(val, point=point),
'overload (int={}, point=(x={}, y={}))'.format(val, *point),
"Can't select first overload if one of the arguments are provided as keyword")
self.assertEqual(cv.utils.testOverloadResolution(val),
'overload (int={}, point=(x=42, y=24))'.format(val),
"Can't select first overload if one of the arguments has default value")
rect = (1, 5, 10, 23)
self.assertEqual(cv.utils.testOverloadResolution(rect),
'overload (rect=(x={}, y={}, w={}, h={}))'.format(*rect),
"Can't select second overload if all arguments are provided")
def test_overload_resolution_fails(self):
def test_overload_resolution(msg, *args, **kwargs):
no_exception_msg = 'Overload resolution failed without any exception for: "{}"'.format(msg)
wrong_exception_msg = 'Overload resolution failed with wrong exception type for: "{}"'.format(msg)
with self.assertRaises((cv.error, Exception), msg=no_exception_msg) as cm:
res = cv.utils.testOverloadResolution(*args, **kwargs)
self.fail("Unexpected result for {}: '{}'".format(msg, res))
self.assertEqual(type(cm.exception), cv.error, wrong_exception_msg)
test_overload_resolution('wrong second arg type (keyword arg)', 5, point=(1, 2, 3))
test_overload_resolution('wrong second arg type', 5, 2)
test_overload_resolution('wrong first arg', 3.4, (12, 21))
test_overload_resolution('wrong first arg, no second arg', 4.5)
test_overload_resolution('wrong args number for first overload', 3, (12, 21), 123)
test_overload_resolution('wrong args number for second overload', (3, 12, 12, 1), (12, 21))
# One of the common problems
test_overload_resolution('rect with float coordinates', (4.5, 4, 2, 1))
test_overload_resolution('rect with wrong number of coordinates', (4, 4, 1))
class Arguments(NewOpenCVTests):
def _try_to_convert(self, conversion, value):
try:
result = conversion(value).lower()
except Exception as e:
self.fail(
'{} "{}" is risen for conversion {} of type {}'.format(
type(e).__name__, e, value, type(value).__name__
)
)
else:
return result
def test_InputArray(self):
res1 = cv.utils.dumpInputArray(None)
# self.assertEqual(res1, "InputArray: noArray()") # not supported
self.assertEqual(res1, "InputArray: empty()=true kind=0x00010000 flags=0x01010000 total(-1)=0 dims(-1)=0 size(-1)=0x0 type(-1)=CV_8UC1")
res2_1 = cv.utils.dumpInputArray((1, 2))
self.assertEqual(res2_1, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=2 dims(-1)=2 size(-1)=1x2 type(-1)=CV_64FC1")
res2_2 = cv.utils.dumpInputArray(1.5) # Scalar(1.5, 1.5, 1.5, 1.5)
self.assertEqual(res2_2, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=4 dims(-1)=2 size(-1)=1x4 type(-1)=CV_64FC1")
a = np.array([[1, 2], [3, 4], [5, 6]])
res3 = cv.utils.dumpInputArray(a) # 32SC1
self.assertEqual(res3, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=6 dims(-1)=2 size(-1)=2x3 type(-1)=CV_32SC1")
a = np.array([[[1, 2], [3, 4], [5, 6]]], dtype='f')
res4 = cv.utils.dumpInputArray(a) # 32FC2
self.assertEqual(res4, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=3 dims(-1)=2 size(-1)=3x1 type(-1)=CV_32FC2")
a = np.array([[[1, 2]], [[3, 4]], [[5, 6]]], dtype=float)
res5 = cv.utils.dumpInputArray(a) # 64FC2
self.assertEqual(res5, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=3 dims(-1)=2 size(-1)=1x3 type(-1)=CV_64FC2")
a = np.zeros((2,3,4), dtype='f')
res6 = cv.utils.dumpInputArray(a)
self.assertEqual(res6, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=6 dims(-1)=2 size(-1)=3x2 type(-1)=CV_32FC4")
a = np.zeros((2,3,4,5), dtype='f')
res7 = cv.utils.dumpInputArray(a)
self.assertEqual(res7, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=120 dims(-1)=4 size(-1)=[2 3 4 5] type(-1)=CV_32FC1")
def test_InputArrayOfArrays(self):
res1 = cv.utils.dumpInputArrayOfArrays(None)
# self.assertEqual(res1, "InputArray: noArray()") # not supported
self.assertEqual(res1, "InputArrayOfArrays: empty()=true kind=0x00050000 flags=0x01050000 total(-1)=0 dims(-1)=1 size(-1)=0x0")
res2_1 = cv.utils.dumpInputArrayOfArrays((1, 2)) # { Scalar:all(1), Scalar::all(2) }
self.assertEqual(res2_1, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_64FC1 dims(0)=2 size(0)=1x4")
res2_2 = cv.utils.dumpInputArrayOfArrays([1.5])
self.assertEqual(res2_2, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=1 dims(-1)=1 size(-1)=1x1 type(0)=CV_64FC1 dims(0)=2 size(0)=1x4")
a = np.array([[1, 2], [3, 4], [5, 6]])
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
res3 = cv.utils.dumpInputArrayOfArrays([a, b])
self.assertEqual(res3, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_32SC1 dims(0)=2 size(0)=2x3")
c = np.array([[[1, 2], [3, 4], [5, 6]]], dtype='f')
res4 = cv.utils.dumpInputArrayOfArrays([c, a, b])
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")
a = np.zeros((2,3,4), dtype='f')
res5 = cv.utils.dumpInputArrayOfArrays([a, b])
self.assertEqual(res5, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_32FC4 dims(0)=2 size(0)=3x2")
# TODO: fix conversion error
#a = np.zeros((2,3,4,5), dtype='f')
#res6 = cv.utils.dumpInputArray([a, b])
#self.assertEqual(res6, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_32FC1 dims(0)=4 size(0)=[2 3 4 5]")
def test_parse_to_bool_convertible(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpBool)
for convertible_true in (True, 1, 64, np.bool(1), np.int8(123), np.int16(11), np.int32(2),
np.int64(1), np.bool_(3), np.bool8(12)):
actual = try_to_convert(convertible_true)
self.assertEqual('bool: true', actual,
msg=get_conversion_error_msg(convertible_true, 'bool: true', actual))
for convertible_false in (False, 0, np.uint8(0), np.bool_(0), np.int_(0)):
actual = try_to_convert(convertible_false)
self.assertEqual('bool: false', actual,
msg=get_conversion_error_msg(convertible_false, 'bool: false', actual))
def test_parse_to_bool_not_convertible(self):
for not_convertible in (1.2, np.float(2.3), 's', 'str', (1, 2), [1, 2], complex(1, 1),
complex(imag=2), complex(1.1), np.array([1, 0], dtype=np.bool)):
with self.assertRaises((TypeError, OverflowError),
msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpBool(not_convertible)
def test_parse_to_bool_convertible_extra(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpBool)
_, max_size_t = get_limits(ctypes.c_size_t)
for convertible_true in (-1, max_size_t):
actual = try_to_convert(convertible_true)
self.assertEqual('bool: true', actual,
msg=get_conversion_error_msg(convertible_true, 'bool: true', actual))
def test_parse_to_bool_not_convertible_extra(self):
for not_convertible in (np.array([False]), np.array([True], dtype=np.bool)):
with self.assertRaises((TypeError, OverflowError),
msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpBool(not_convertible)
def test_parse_to_int_convertible(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpInt)
min_int, max_int = get_limits(ctypes.c_int)
for convertible in (-10, -1, 2, int(43.2), np.uint8(15), np.int8(33), np.int16(-13),
np.int32(4), np.int64(345), (23), min_int, max_int, np.int_(33)):
expected = 'int: {0:d}'.format(convertible)
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_int_not_convertible(self):
min_int, max_int = get_limits(ctypes.c_int)
for not_convertible in (1.2, np.float(4), float(3), np.double(45), 's', 'str',
np.array([1, 2]), (1,), [1, 2], min_int - 1, max_int + 1,
complex(1, 1), complex(imag=2), complex(1.1)):
with self.assertRaises((TypeError, OverflowError, ValueError),
msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpInt(not_convertible)
def test_parse_to_int_not_convertible_extra(self):
for not_convertible in (np.bool_(True), True, False, np.float32(2.3),
np.array([3, ], dtype=int), np.array([-2, ], dtype=np.int32),
np.array([1, ], dtype=np.int), np.array([11, ], dtype=np.uint8)):
with self.assertRaises((TypeError, OverflowError),
msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpInt(not_convertible)
def test_parse_to_size_t_convertible(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpSizeT)
_, max_uint = get_limits(ctypes.c_uint)
for convertible in (2, max_uint, (12), np.uint8(34), np.int8(12), np.int16(23),
np.int32(123), np.int64(344), np.uint64(3), np.uint16(2), np.uint32(5),
np.uint(44)):
expected = 'size_t: {0:d}'.format(convertible).lower()
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_size_t_not_convertible(self):
min_long, _ = get_limits(ctypes.c_long)
for not_convertible in (1.2, True, False, np.bool_(True), np.float(4), float(3),
np.double(45), 's', 'str', np.array([1, 2]), (1,), [1, 2],
np.float64(6), complex(1, 1), complex(imag=2), complex(1.1),
-1, min_long, np.int8(-35)):
with self.assertRaises((TypeError, OverflowError),
msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpSizeT(not_convertible)
def test_parse_to_size_t_convertible_extra(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpSizeT)
_, max_size_t = get_limits(ctypes.c_size_t)
for convertible in (max_size_t,):
expected = 'size_t: {0:d}'.format(convertible).lower()
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_size_t_not_convertible_extra(self):
for not_convertible in (np.bool_(True), True, False, np.array([123, ], dtype=np.uint8),):
with self.assertRaises((TypeError, OverflowError),
msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpSizeT(not_convertible)
def test_parse_to_float_convertible(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpFloat)
min_float, max_float = get_limits(ctypes.c_float)
for convertible in (2, -13, 1.24, float(32), np.float(32.45), np.double(12.23),
np.float32(-12.3), np.float64(3.22), np.float_(-1.5), min_float,
max_float, np.inf, -np.inf, float('Inf'), -float('Inf'),
np.double(np.inf), np.double(-np.inf), np.double(float('Inf')),
np.double(-float('Inf'))):
expected = 'Float: {0:.2f}'.format(convertible).lower()
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
# Workaround for Windows NaN tests due to Visual C runtime
# special floating point values (indefinite NaN)
for nan in (float('NaN'), np.nan, np.float32(np.nan), np.double(np.nan),
np.double(float('NaN'))):
actual = try_to_convert(nan)
self.assertIn('nan', actual, msg="Can't convert nan of type {} to float. "
"Actual: {}".format(type(nan).__name__, actual))
min_double, max_double = get_limits(ctypes.c_double)
for inf in (min_float * 10, max_float * 10, min_double, max_double):
expected = 'float: {}inf'.format('-' if inf < 0 else '')
actual = try_to_convert(inf)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(inf, expected, actual))
def test_parse_to_float_not_convertible(self):
for not_convertible in ('s', 'str', (12,), [1, 2], np.array([1, 2], dtype=np.float),
np.array([1, 2], dtype=np.double), complex(1, 1), complex(imag=2),
complex(1.1)):
with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpFloat(not_convertible)
def test_parse_to_float_not_convertible_extra(self):
for not_convertible in (np.bool_(False), True, False, np.array([123, ], dtype=int),
np.array([1., ]), np.array([False]),
np.array([True], dtype=np.bool)):
with self.assertRaises((TypeError, OverflowError),
msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpFloat(not_convertible)
def test_parse_to_double_convertible(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpDouble)
min_float, max_float = get_limits(ctypes.c_float)
min_double, max_double = get_limits(ctypes.c_double)
for convertible in (2, -13, 1.24, np.float(32.45), float(2), np.double(12.23),
np.float32(-12.3), np.float64(3.22), np.float_(-1.5), min_float,
max_float, min_double, max_double, np.inf, -np.inf, float('Inf'),
-float('Inf'), np.double(np.inf), np.double(-np.inf),
np.double(float('Inf')), np.double(-float('Inf'))):
expected = 'Double: {0:.2f}'.format(convertible).lower()
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
# Workaround for Windows NaN tests due to Visual C runtime
# special floating point values (indefinite NaN)
for nan in (float('NaN'), np.nan, np.double(np.nan),
np.double(float('NaN'))):
actual = try_to_convert(nan)
self.assertIn('nan', actual, msg="Can't convert nan of type {} to double. "
"Actual: {}".format(type(nan).__name__, actual))
def test_parse_to_double_not_convertible(self):
for not_convertible in ('s', 'str', (12,), [1, 2], np.array([1, 2], dtype=np.float),
np.array([1, 2], dtype=np.double), complex(1, 1), complex(imag=2),
complex(1.1)):
with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpDouble(not_convertible)
def test_parse_to_double_not_convertible_extra(self):
for not_convertible in (np.bool_(False), True, False, np.array([123, ], dtype=int),
np.array([1., ]), np.array([False]),
np.array([12.4], dtype=np.double), np.array([True], dtype=np.bool)):
with self.assertRaises((TypeError, OverflowError),
msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpDouble(not_convertible)
def test_parse_to_cstring_convertible(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpCString)
for convertible in ('', 's', 'str', str(123), ('char'), np.str('test1'), np.str_('test2')):
expected = 'string: ' + convertible
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_cstring_not_convertible(self):
for not_convertible in ((12,), ('t', 'e', 's', 't'), np.array(['123', ]),
np.array(['t', 'e', 's', 't']), 1, -1.4, True, False, None):
with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpCString(not_convertible)
def test_parse_to_string_convertible(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpString)
for convertible in (None, '', 's', 'str', str(123), np.str('test1'), np.str_('test2')):
expected = 'string: ' + (convertible if convertible else '')
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_string_not_convertible(self):
for not_convertible in ((12,), ('t', 'e', 's', 't'), np.array(['123', ]),
np.array(['t', 'e', 's', 't']), 1, True, False):
with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpString(not_convertible)
def test_parse_to_rect_convertible(self):
Rect = namedtuple('Rect', ('x', 'y', 'w', 'h'))
try_to_convert = partial(self._try_to_convert, cv.utils.dumpRect)
for convertible in ((1, 2, 4, 5), [5, 3, 10, 20], np.array([10, 20, 23, 10]),
Rect(10, 30, 40, 55), tuple(np.array([40, 20, 24, 20])),
list(np.array([20, 40, 30, 35]))):
expected = 'rect: (x={}, y={}, w={}, h={})'.format(*convertible)
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_rect_not_convertible(self):
for not_convertible in (np.empty(shape=(4, 1)), (), [], np.array([]), (12, ),
[3, 4, 5, 10, 123], {1: 2, 3:4, 5:10, 6:30},
'1234', np.array([1, 2, 3, 4], dtype=np.float32),
np.array([[1, 2], [3, 4], [5, 6], [6, 8]]), (1, 2, 5, 1.5)):
with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpRect(not_convertible)
def test_parse_to_rotated_rect_convertible(self):
RotatedRect = namedtuple('RotatedRect', ('center', 'size', 'angle'))
try_to_convert = partial(self._try_to_convert, cv.utils.dumpRotatedRect)
for convertible in (((2.5, 2.5), (10., 20.), 12.5), [[1.5, 10.5], (12.5, 51.5), 10],
RotatedRect((10, 40), np.array([10.5, 20.5]), 5),
np.array([[10, 6], [50, 50], 5.5], dtype=object)):
center, size, angle = convertible
expected = 'rotated_rect: (c_x={:.6f}, c_y={:.6f}, w={:.6f},' \
' h={:.6f}, a={:.6f})'.format(center[0], center[1],
size[0], size[1], angle)
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_rotated_rect_not_convertible(self):
for not_convertible in ([], (), np.array([]), (123, (45, 34), 1), {1: 2, 3: 4}, 123,
np.array([[123, 123, 14], [1, 3], 56], dtype=object), '123'):
with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpRotatedRect(not_convertible)
def test_parse_to_term_criteria_convertible(self):
TermCriteria = namedtuple('TermCriteria', ('type', 'max_count', 'epsilon'))
try_to_convert = partial(self._try_to_convert, cv.utils.dumpTermCriteria)
for convertible in ((1, 10, 1e-3), [2, 30, 1e-1], np.array([10, 20, 0.5], dtype=object),
TermCriteria(0, 5, 0.1)):
expected = 'term_criteria: (type={}, max_count={}, epsilon={:.6f}'.format(*convertible)
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_term_criteria_not_convertible(self):
for not_convertible in ([], (), np.array([]), [1, 4], (10,), (1.5, 34, 0.1),
{1: 5, 3: 5, 10: 10}, '145'):
with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpTermCriteria(not_convertible)
def test_parse_to_range_convertible_to_all(self):
try_to_convert = partial(self._try_to_convert, cv.utils.dumpRange)
for convertible in ((), [], np.array([])):
expected = 'range: all'
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_range_convertible(self):
Range = namedtuple('Range', ('start', 'end'))
try_to_convert = partial(self._try_to_convert, cv.utils.dumpRange)
for convertible in ((10, 20), [-1, 3], np.array([10, 24]), Range(-4, 6)):
expected = 'range: (s={}, e={})'.format(*convertible)
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_to_range_not_convertible(self):
for not_convertible in ((1, ), [40, ], np.array([1, 4, 6]), {'a': 1, 'b': 40},
(1.5, 13.5), [3, 6.7], np.array([6.3, 2.1]), '14, 4'):
with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpRange(not_convertible)
def test_reserved_keywords_are_transformed(self):
default_lambda_value = 2
default_from_value = 3
format_str = "arg={}, lambda={}, from={}"
self.assertEqual(
cv.utils.testReservedKeywordConversion(20), format_str.format(20, default_lambda_value, default_from_value)
)
self.assertEqual(
cv.utils.testReservedKeywordConversion(10, lambda_=10), format_str.format(10, 10, default_from_value)
)
self.assertEqual(
cv.utils.testReservedKeywordConversion(10, from_=10), format_str.format(10, default_lambda_value, 10)
)
self.assertEqual(
cv.utils.testReservedKeywordConversion(20, lambda_=-4, from_=12), format_str.format(20, -4, 12)
)
def test_parse_vector_int_convertible(self):
np.random.seed(123098765)
try_to_convert = partial(self._try_to_convert, cv.utils.dumpVectorOfInt)
arr = np.random.randint(-20, 20, 40).astype(np.int32).reshape(10, 2, 2)
int_min, int_max = get_limits(ctypes.c_int)
for convertible in ((int_min, 1, 2, 3, int_max), [40, 50], tuple(),
np.array([int_min, -10, 24, int_max], dtype=np.int32),
np.array([10, 230, 12], dtype=np.uint8), arr[:, 0, 1],):
expected = "[" + ", ".join(map(str, convertible)) + "]"
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_vector_int_not_convertible(self):
np.random.seed(123098765)
arr = np.random.randint(-20, 20, 40).astype(np.float).reshape(10, 2, 2)
int_min, int_max = get_limits(ctypes.c_int)
test_dict = {1: 2, 3: 10, 10: 20}
for not_convertible in ((int_min, 1, 2.5, 3, int_max), [True, 50], 'test', test_dict,
reversed([1, 2, 3]),
np.array([int_min, -10, 24, [1, 2]], dtype=np.object),
np.array([[1, 2], [3, 4]]), arr[:, 0, 1],):
with self.assertRaises(TypeError, msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpVectorOfInt(not_convertible)
def test_parse_vector_double_convertible(self):
np.random.seed(1230965)
try_to_convert = partial(self._try_to_convert, cv.utils.dumpVectorOfDouble)
arr = np.random.randint(-20, 20, 40).astype(np.int32).reshape(10, 2, 2)
for convertible in ((1, 2.12, 3.5), [40, 50], tuple(),
np.array([-10, 24], dtype=np.int32),
np.array([-12.5, 1.4], dtype=np.double),
np.array([10, 230, 12], dtype=np.float), arr[:, 0, 1], ):
expected = "[" + ", ".join(map(lambda v: "{:.2f}".format(v), convertible)) + "]"
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_vector_double_not_convertible(self):
test_dict = {1: 2, 3: 10, 10: 20}
for not_convertible in (('t', 'e', 's', 't'), [True, 50.55], 'test', test_dict,
np.array([-10.1, 24.5, [1, 2]], dtype=np.object),
np.array([[1, 2], [3, 4]]),):
with self.assertRaises(TypeError, msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpVectorOfDouble(not_convertible)
def test_parse_vector_rect_convertible(self):
np.random.seed(1238765)
try_to_convert = partial(self._try_to_convert, cv.utils.dumpVectorOfRect)
arr_of_rect_int32 = np.random.randint(5, 20, 4 * 3).astype(np.int32).reshape(3, 4)
arr_of_rect_cast = np.random.randint(10, 40, 4 * 5).astype(np.uint8).reshape(5, 4)
for convertible in (((1, 2, 3, 4), (10, -20, 30, 10)), arr_of_rect_int32, arr_of_rect_cast,
arr_of_rect_int32.astype(np.int8), [[5, 3, 1, 4]],
((np.int8(4), np.uint8(10), np.int(32), np.int16(55)),)):
expected = "[" + ", ".join(map(lambda v: "[x={}, y={}, w={}, h={}]".format(*v), convertible)) + "]"
actual = try_to_convert(convertible)
self.assertEqual(expected, actual,
msg=get_conversion_error_msg(convertible, expected, actual))
def test_parse_vector_rect_not_convertible(self):
np.random.seed(1238765)
arr = np.random.randint(5, 20, 4 * 3).astype(np.float).reshape(3, 4)
for not_convertible in (((1, 2, 3, 4), (10.5, -20, 30.1, 10)), arr,
[[5, 3, 1, 4], []],
((np.float(4), np.uint8(10), np.int(32), np.int16(55)),)):
with self.assertRaises(TypeError, msg=get_no_exception_msg(not_convertible)):
_ = cv.utils.dumpVectorOfRect(not_convertible)
def test_vector_general_return(self):
expected_number_of_mats = 5
expected_shape = (10, 10, 3)
expected_type = np.uint8
mats = cv.utils.generateVectorOfMat(5, 10, 10, cv.CV_8UC3)
self.assertTrue(isinstance(mats, tuple),
"Vector of Mats objects should be returned as tuple. Got: {}".format(type(mats)))
self.assertEqual(len(mats), expected_number_of_mats, "Returned array has wrong length")
for mat in mats:
self.assertEqual(mat.shape, expected_shape, "Returned Mat has wrong shape")
self.assertEqual(mat.dtype, expected_type, "Returned Mat has wrong elements type")
empty_mats = cv.utils.generateVectorOfMat(0, 10, 10, cv.CV_32FC1)
self.assertTrue(isinstance(empty_mats, tuple),
"Empty vector should be returned as empty tuple. Got: {}".format(type(mats)))
self.assertEqual(len(empty_mats), 0, "Vector of size 0 should be returned as tuple of length 0")
def test_vector_fast_return(self):
expected_shape = (5, 4)
rects = cv.utils.generateVectorOfRect(expected_shape[0])
self.assertTrue(isinstance(rects, np.ndarray),
"Vector of rectangles should be returned as numpy array. Got: {}".format(type(rects)))
self.assertEqual(rects.dtype, np.int32, "Vector of rectangles has wrong elements type")
self.assertEqual(rects.shape, expected_shape, "Vector of rectangles has wrong shape")
empty_rects = cv.utils.generateVectorOfRect(0)
self.assertTrue(isinstance(empty_rects, tuple),
"Empty vector should be returned as empty tuple. Got: {}".format(type(empty_rects)))
self.assertEqual(len(empty_rects), 0, "Vector of size 0 should be returned as tuple of length 0")
expected_shape = (10,)
ints = cv.utils.generateVectorOfInt(expected_shape[0])
self.assertTrue(isinstance(ints, np.ndarray),
"Vector of integers should be returned as numpy array. Got: {}".format(type(ints)))
self.assertEqual(ints.dtype, np.int32, "Vector of integers has wrong elements type")
self.assertEqual(ints.shape, expected_shape, "Vector of integers has wrong shape.")
class CanUsePurePythonModuleFunction(NewOpenCVTests):
def test_can_get_ocv_version(self):
import sys
if sys.version_info[0] < 3:
raise unittest.SkipTest('Python 2.x is not supported')
self.assertEqual(cv.misc.get_ocv_version(), cv.__version__,
"Can't get package version using Python misc module")
def test_native_method_can_be_patched(self):
import sys
if sys.version_info[0] < 3:
raise unittest.SkipTest('Python 2.x is not supported')
res = cv.utils.testOverwriteNativeMethod(10)
self.assertTrue(isinstance(res, Sequence),
msg="Overwritten method should return sequence. "
"Got: {} of type {}".format(res, type(res)))
self.assertSequenceEqual(res, (11, 10),
msg="Failed to overwrite native method")
res = cv.utils._native.testOverwriteNativeMethod(123)
self.assertEqual(res, 123, msg="Failed to call native method implementation")
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()

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python
'''
Morphology operations.
'''
# Python 2/3 compatibility
from __future__ import print_function
import sys
PY3 = sys.version_info[0] == 3
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class morphology_test(NewOpenCVTests):
def test_morphology(self):
fn = 'samples/data/rubberwhale1.png'
img = self.get_sample(fn)
modes = ['erode/dilate', 'open/close', 'blackhat/tophat', 'gradient']
str_modes = ['ellipse', 'rect', 'cross']
referenceHashes = { modes[0]: '071a526425b79e45b4d0d71ef51b0562', modes[1] : '071a526425b79e45b4d0d71ef51b0562',
modes[2] : '427e89f581b7df1b60a831b1ed4c8618', modes[3] : '0dd8ad251088a63d0dd022bcdc57361c'}
def update(cur_mode):
cur_str_mode = str_modes[0]
sz = 10
iters = 1
opers = cur_mode.split('/')
if len(opers) > 1:
sz = sz - 10
op = opers[sz > 0]
sz = abs(sz)
else:
op = opers[0]
sz = sz*2+1
str_name = 'MORPH_' + cur_str_mode.upper()
oper_name = 'MORPH_' + op.upper()
st = cv.getStructuringElement(getattr(cv, str_name), (sz, sz))
return cv.morphologyEx(img, getattr(cv, oper_name), st, iterations=iters)
for mode in modes:
res = update(mode)
self.assertEqual(self.hashimg(res), referenceHashes[mode])
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
'''
MSER detector test
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class mser_test(NewOpenCVTests):
def test_mser(self):
img = self.get_sample('cv/mser/puzzle.png', 0)
smallImg = [
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
]
thresharr = [ 0, 70, 120, 180, 255 ]
kDelta = 5
mserExtractor = cv.MSER_create()
mserExtractor.setDelta(kDelta)
np.random.seed(10)
for _i in range(100):
use_big_image = int(np.random.rand(1,1)*7) != 0
invert = int(np.random.rand(1,1)*2) != 0
binarize = int(np.random.rand(1,1)*5) != 0 if use_big_image else False
blur = int(np.random.rand(1,1)*2) != 0
thresh = thresharr[int(np.random.rand(1,1)*5)]
src0 = img if use_big_image else np.array(smallImg).astype('uint8')
src = src0.copy()
kMinArea = 256 if use_big_image else 10
kMaxArea = int(src.shape[0]*src.shape[1]/4)
mserExtractor.setMinArea(kMinArea)
mserExtractor.setMaxArea(kMaxArea)
if invert:
cv.bitwise_not(src, src)
if binarize:
_, src = cv.threshold(src, thresh, 255, cv.THRESH_BINARY)
if blur:
src = cv.GaussianBlur(src, (5, 5), 1.5, 1.5)
minRegs = 7 if use_big_image else 2
maxRegs = 1000 if use_big_image else 20
if binarize and (thresh == 0 or thresh == 255):
minRegs = maxRegs = 0
msers, boxes = mserExtractor.detectRegions(src)
nmsers = len(msers)
self.assertEqual(nmsers, len(boxes))
self.assertLessEqual(minRegs, nmsers)
self.assertGreaterEqual(maxRegs, nmsers)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,173 @@
#!/usr/bin/env python
from itertools import product
from functools import reduce
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
def norm_inf(x, y=None):
def norm(vec):
return np.linalg.norm(vec.flatten(), np.inf)
x = x.astype(np.float64)
return norm(x) if y is None else norm(x - y.astype(np.float64))
def norm_l1(x, y=None):
def norm(vec):
return np.linalg.norm(vec.flatten(), 1)
x = x.astype(np.float64)
return norm(x) if y is None else norm(x - y.astype(np.float64))
def norm_l2(x, y=None):
def norm(vec):
return np.linalg.norm(vec.flatten())
x = x.astype(np.float64)
return norm(x) if y is None else norm(x - y.astype(np.float64))
def norm_l2sqr(x, y=None):
def norm(vec):
return np.square(vec).sum()
x = x.astype(np.float64)
return norm(x) if y is None else norm(x - y.astype(np.float64))
def norm_hamming(x, y=None):
def norm(vec):
return sum(bin(i).count('1') for i in vec.flatten())
return norm(x) if y is None else norm(np.bitwise_xor(x, y))
def norm_hamming2(x, y=None):
def norm(vec):
def element_norm(element):
binary_str = bin(element).split('b')[-1]
if len(binary_str) % 2 == 1:
binary_str = '0' + binary_str
gen = filter(lambda p: p != '00',
(binary_str[i:i+2]
for i in range(0, len(binary_str), 2)))
return sum(1 for _ in gen)
return sum(element_norm(element) for element in vec.flatten())
return norm(x) if y is None else norm(np.bitwise_xor(x, y))
norm_type_under_test = {
cv.NORM_INF: norm_inf,
cv.NORM_L1: norm_l1,
cv.NORM_L2: norm_l2,
cv.NORM_L2SQR: norm_l2sqr,
cv.NORM_HAMMING: norm_hamming,
cv.NORM_HAMMING2: norm_hamming2
}
norm_name = {
cv.NORM_INF: 'inf',
cv.NORM_L1: 'L1',
cv.NORM_L2: 'L2',
cv.NORM_L2SQR: 'L2SQR',
cv.NORM_HAMMING: 'Hamming',
cv.NORM_HAMMING2: 'Hamming2'
}
def get_element_types(norm_type):
if norm_type in (cv.NORM_HAMMING, cv.NORM_HAMMING2):
return (np.uint8,)
else:
return (np.uint8, np.int8, np.uint16, np.int16, np.int32, np.float32,
np.float64)
def generate_vector(shape, dtype):
if np.issubdtype(dtype, np.integer):
return np.random.randint(0, 100, shape).astype(dtype)
else:
return np.random.normal(10., 12.5, shape).astype(dtype)
shapes = (1, 2, 3, 5, 7, 16, (1, 1), (2, 2), (3, 5), (1, 7))
class norm_test(NewOpenCVTests):
def test_norm_for_one_array(self):
np.random.seed(123)
for norm_type, norm in norm_type_under_test.items():
element_types = get_element_types(norm_type)
for shape, element_type in product(shapes, element_types):
array = generate_vector(shape, element_type)
expected = norm(array)
actual = cv.norm(array, norm_type)
self.assertAlmostEqual(
expected, actual, places=2,
msg='Array {0} of {1} and norm {2}'.format(
array, element_type.__name__, norm_name[norm_type]
)
)
def test_norm_for_two_arrays(self):
np.random.seed(456)
for norm_type, norm in norm_type_under_test.items():
element_types = get_element_types(norm_type)
for shape, element_type in product(shapes, element_types):
first = generate_vector(shape, element_type)
second = generate_vector(shape, element_type)
expected = norm(first, second)
actual = cv.norm(first, second, norm_type)
self.assertAlmostEqual(
expected, actual, places=2,
msg='Arrays {0} {1} of type {2} and norm {3}'.format(
first, second, element_type.__name__,
norm_name[norm_type]
)
)
def test_norm_fails_for_wrong_type(self):
for norm_type in (cv.NORM_HAMMING, cv.NORM_HAMMING2):
with self.assertRaises(Exception,
msg='Type is not checked {0}'.format(
norm_name[norm_type]
)):
cv.norm(np.array([1, 2], dtype=np.int32), norm_type)
def test_norm_fails_for_array_and_scalar(self):
for norm_type in norm_type_under_test:
with self.assertRaises(Exception,
msg='Exception is not thrown for {0}'.format(
norm_name[norm_type]
)):
cv.norm(np.array([1, 2], dtype=np.uint8), 123, norm_type)
def test_norm_fails_for_scalar_and_array(self):
for norm_type in norm_type_under_test:
with self.assertRaises(Exception,
msg='Exception is not thrown for {0}'.format(
norm_name[norm_type]
)):
cv.norm(4, np.array([1, 2], dtype=np.uint8), norm_type)
def test_norm_fails_for_array_and_norm_type_as_scalar(self):
for norm_type in norm_type_under_test:
with self.assertRaises(Exception,
msg='Exception is not thrown for {0}'.format(
norm_name[norm_type]
)):
cv.norm(np.array([3, 4, 5], dtype=np.uint8),
norm_type, normType=norm_type)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,44 @@
#!/usr/bin/env python
""""Core serialization tests."""
import tempfile
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests
class persistence_test(NewOpenCVTests):
def test_yml_rw(self):
fd, fname = tempfile.mkstemp(prefix="opencv_python_persistence_", suffix=".yml")
os.close(fd)
# Writing ...
expected = np.array([[[0, 1, 2, 3, 4]]])
expected_str = ("Hello", "World", "!")
fs = cv.FileStorage(fname, cv.FILE_STORAGE_WRITE)
fs.write("test", expected)
fs.write("strings", expected_str)
fs.release()
# Reading ...
fs = cv.FileStorage(fname, cv.FILE_STORAGE_READ)
root = fs.getFirstTopLevelNode()
self.assertEqual(root.name(), "test")
test = fs.getNode("test")
self.assertEqual(test.empty(), False)
self.assertEqual(test.name(), "test")
self.assertEqual(test.type(), cv.FILE_NODE_MAP)
self.assertEqual(test.isMap(), True)
actual = test.mat()
self.assertEqual(actual.shape, expected.shape)
self.assertEqual(np.array_equal(expected, actual), True)
strings = fs.getNode("strings")
self.assertEqual(strings.isSeq(), True)
self.assertEqual(strings.size(), len(expected_str))
self.assertEqual(all(strings.at(i).isString() for i in range(strings.size())), True)
self.assertSequenceEqual([strings.at(i).string() for i in range(strings.size())], expected_str)
fs.release()
os.remove(fname)

View File

@ -0,0 +1,99 @@
#!/usr/bin/env python
'''
Simple "Square Detector" program.
Loads several images sequentially and tries to find squares in each image.
'''
# Python 2/3 compatibility
import sys
PY3 = sys.version_info[0] == 3
if PY3:
xrange = range
import numpy as np
import cv2 as cv
def angle_cos(p0, p1, p2):
d1, d2 = (p0-p1).astype('float'), (p2-p1).astype('float')
return abs( np.dot(d1, d2) / np.sqrt( np.dot(d1, d1)*np.dot(d2, d2) ) )
def find_squares(img):
img = cv.GaussianBlur(img, (5, 5), 0)
squares = []
for gray in cv.split(img):
for thrs in xrange(0, 255, 26):
if thrs == 0:
bin = cv.Canny(gray, 0, 50, apertureSize=5)
bin = cv.dilate(bin, None)
else:
_retval, bin = cv.threshold(gray, thrs, 255, cv.THRESH_BINARY)
contours, _hierarchy = cv.findContours(bin, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
for cnt in contours:
cnt_len = cv.arcLength(cnt, True)
cnt = cv.approxPolyDP(cnt, 0.02*cnt_len, True)
if len(cnt) == 4 and cv.contourArea(cnt) > 1000 and cv.isContourConvex(cnt):
cnt = cnt.reshape(-1, 2)
max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in xrange(4)])
if max_cos < 0.1 and filterSquares(squares, cnt):
squares.append(cnt)
return squares
def intersectionRate(s1, s2):
area, _intersection = cv.intersectConvexConvex(np.array(s1), np.array(s2))
return 2 * area / (cv.contourArea(np.array(s1)) + cv.contourArea(np.array(s2)))
def filterSquares(squares, square):
for i in range(len(squares)):
if intersectionRate(squares[i], square) > 0.95:
return False
return True
from tests_common import NewOpenCVTests
class squares_test(NewOpenCVTests):
def test_squares(self):
img = self.get_sample('samples/data/pic1.png')
squares = find_squares(img)
testSquares = [
[[43, 25],
[43, 129],
[232, 129],
[232, 25]],
[[252, 87],
[324, 40],
[387, 137],
[315, 184]],
[[154, 178],
[196, 180],
[198, 278],
[154, 278]],
[[0, 0],
[400, 0],
[400, 300],
[0, 300]]
]
matches_counter = 0
for i in range(len(squares)):
for j in range(len(testSquares)):
if intersectionRate(squares[i], testSquares[j]) > 0.9:
matches_counter += 1
self.assertGreater(matches_counter / len(testSquares), 0.9)
self.assertLess( (len(squares) - matches_counter) / len(squares), 0.2)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,47 @@
#!/usr/bin/env python
'''
Texture flow direction estimation.
Sample shows how cv.cornerEigenValsAndVecs function can be used
to estimate image texture flow direction.
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
import sys
from tests_common import NewOpenCVTests
class texture_flow_test(NewOpenCVTests):
def test_texture_flow(self):
img = self.get_sample('samples/data/chessboard.png')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
h, w = img.shape[:2]
eigen = cv.cornerEigenValsAndVecs(gray, 5, 3)
eigen = eigen.reshape(h, w, 3, 2) # [[e1, e2], v1, v2]
flow = eigen[:,:,2]
d = 300
eps = d / 30
points = np.dstack( np.mgrid[d/2:w:d, d/2:h:d] ).reshape(-1, 2)
textureVectors = []
for x, y in np.int32(points):
textureVectors.append(np.int32(flow[y, x]*d))
for i in range(len(textureVectors)):
self.assertTrue(cv.norm(textureVectors[i], cv.NORM_L2) < eps
or abs(cv.norm(textureVectors[i], cv.NORM_L2) - d) < eps)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,120 @@
#!/usr/bin/env python
from __future__ import print_function
import numpy as np
import cv2 as cv
import os
from tests_common import NewOpenCVTests
def load_exposure_seq(path):
images = []
times = []
with open(os.path.join(path, 'list.txt'), 'r') as list_file:
for line in list_file.readlines():
name, time = line.split()
images.append(cv.imread(os.path.join(path, name)))
times.append(1. / float(time))
return images, times
class UMat(NewOpenCVTests):
def test_umat_construct(self):
data = np.random.random([512, 512])
# UMat constructors
data_um = cv.UMat(data) # from ndarray
data_sub_um = cv.UMat(data_um, (128, 256), (128, 256)) # from UMat
data_dst_um = cv.UMat(128, 128, cv.CV_64F) # from size/type
# test continuous and submatrix flags
assert data_um.isContinuous() and not data_um.isSubmatrix()
assert not data_sub_um.isContinuous() and data_sub_um.isSubmatrix()
# test operation on submatrix
cv.multiply(data_sub_um, 2., dst=data_dst_um)
assert np.allclose(2. * data[128:256, 128:256], data_dst_um.get())
def test_umat_handle(self):
a_um = cv.UMat(256, 256, cv.CV_32F)
_ctx_handle = cv.UMat.context() # obtain context handle
_queue_handle = cv.UMat.queue() # obtain queue handle
_a_handle = a_um.handle(cv.ACCESS_READ) # obtain buffer handle
_offset = a_um.offset # obtain buffer offset
def test_umat_matching(self):
img1 = self.get_sample("samples/data/right01.jpg")
img2 = self.get_sample("samples/data/right02.jpg")
orb = cv.ORB_create()
img1, img2 = cv.UMat(img1), cv.UMat(img2)
ps1, descs_umat1 = orb.detectAndCompute(img1, None)
ps2, descs_umat2 = orb.detectAndCompute(img2, None)
self.assertIsInstance(descs_umat1, cv.UMat)
self.assertIsInstance(descs_umat2, cv.UMat)
self.assertGreater(len(ps1), 0)
self.assertGreater(len(ps2), 0)
bf = cv.BFMatcher(cv.NORM_HAMMING, crossCheck=True)
res_umats = bf.match(descs_umat1, descs_umat2)
res = bf.match(descs_umat1.get(), descs_umat2.get())
self.assertGreater(len(res), 0)
self.assertEqual(len(res_umats), len(res))
def test_umat_optical_flow(self):
img1 = self.get_sample("samples/data/right01.jpg", cv.IMREAD_GRAYSCALE)
img2 = self.get_sample("samples/data/right02.jpg", cv.IMREAD_GRAYSCALE)
# Note, that if you want to see performance boost by OCL implementation - you need enough data
# For example you can increase maxCorners param to 10000 and increase img1 and img2 in such way:
# img = np.hstack([np.vstack([img] * 6)] * 6)
feature_params = dict(maxCorners=239,
qualityLevel=0.3,
minDistance=7,
blockSize=7)
p0 = cv.goodFeaturesToTrack(img1, mask=None, **feature_params)
p0_umat = cv.goodFeaturesToTrack(cv.UMat(img1), mask=None, **feature_params)
self.assertEqual(p0_umat.get().shape, p0.shape)
p0 = np.array(sorted(p0, key=lambda p: tuple(p[0])))
p0_umat = cv.UMat(np.array(sorted(p0_umat.get(), key=lambda p: tuple(p[0]))))
self.assertTrue(np.allclose(p0_umat.get(), p0))
_p1_mask_err = cv.calcOpticalFlowPyrLK(img1, img2, p0, None)
_p1_mask_err_umat0 = list(map(lambda umat: umat.get(), cv.calcOpticalFlowPyrLK(img1, img2, p0_umat, None)))
_p1_mask_err_umat1 = list(map(lambda umat: umat.get(), cv.calcOpticalFlowPyrLK(cv.UMat(img1), img2, p0_umat, None)))
_p1_mask_err_umat2 = list(map(lambda umat: umat.get(), cv.calcOpticalFlowPyrLK(img1, cv.UMat(img2), p0_umat, None)))
for _p1_mask_err_umat in [_p1_mask_err_umat0, _p1_mask_err_umat1, _p1_mask_err_umat2]:
for data, data_umat in zip(_p1_mask_err, _p1_mask_err_umat):
self.assertEqual(data.shape, data_umat.shape)
self.assertEqual(data.dtype, data_umat.dtype)
for _p1_mask_err_umat in [_p1_mask_err_umat1, _p1_mask_err_umat2]:
for data_umat0, data_umat in zip(_p1_mask_err_umat0[:2], _p1_mask_err_umat[:2]):
self.assertTrue(np.allclose(data_umat0, data_umat))
def test_umat_merge_mertens(self):
if self.extraTestDataPath is None:
self.fail('Test data is not available')
test_data_path = os.path.join(self.extraTestDataPath, 'cv', 'hdr')
images, _ = load_exposure_seq(os.path.join(test_data_path, 'exposures'))
merge = cv.createMergeMertens()
mat_result = merge.process(images)
umat_images = [cv.UMat(img) for img in images]
umat_result = merge.process(umat_images)
self.assertTrue(np.allclose(umat_result.get(), mat_result))
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,36 @@
#!/usr/bin/env python
'''
Watershed segmentation test
'''
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
import cv2 as cv
from tests_common import NewOpenCVTests
class watershed_test(NewOpenCVTests):
def test_watershed(self):
img = self.get_sample('cv/inpaint/orig.png')
markers = self.get_sample('cv/watershed/wshed_exp.png', 0)
refSegments = self.get_sample('cv/watershed/wshed_segments.png')
if img is None or markers is None:
self.assertEqual(0, 1, 'Missing test data')
colors = np.int32( list(np.ndindex(3, 3, 3)) ) * 122
cv.watershed(img, np.int32(markers))
segments = colors[np.maximum(markers, 0)]
if refSegments is None:
refSegments = segments.copy()
cv.imwrite(self.extraTestDataPath + '/cv/watershed/wshed_segments.png', refSegments)
self.assertLess(cv.norm(segments - refSegments, cv.NORM_L1) / 255.0, 50)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()

View File

@ -0,0 +1,108 @@
#!/usr/bin/env python
from __future__ import print_function
import os
import sys
import unittest
import hashlib
import random
import argparse
import numpy as np
#sys.OpenCV_LOADER_DEBUG = True
import cv2 as cv
# Python 3 moved urlopen to urllib.requests
try:
from urllib.request import urlopen
except ImportError:
from urllib import urlopen
class NewOpenCVTests(unittest.TestCase):
# path to local repository folder containing 'samples' folder
repoPath = None
extraTestDataPath = None
# github repository url
repoUrl = 'https://raw.github.com/opencv/opencv/master'
def find_file(self, filename, searchPaths=[], required=True):
searchPaths = searchPaths if searchPaths else [self.repoPath, self.extraTestDataPath]
for path in searchPaths:
if path is not None:
candidate = path + '/' + filename
if os.path.isfile(candidate):
return candidate
if required:
self.fail('File ' + filename + ' not found')
return None
def get_sample(self, filename, iscolor = None):
if iscolor is None:
iscolor = cv.IMREAD_COLOR
if not filename in self.image_cache:
filepath = self.find_file(filename)
with open(filepath, 'rb') as f:
filedata = f.read()
self.image_cache[filename] = cv.imdecode(np.fromstring(filedata, dtype=np.uint8), iscolor)
return self.image_cache[filename]
def setUp(self):
cv.setRNGSeed(10)
self.image_cache = {}
def hashimg(self, im):
""" Compute a hash for an image, useful for image comparisons """
return hashlib.md5(im.tostring()).hexdigest()
if sys.version_info[:2] == (2, 6):
def assertLess(self, a, b, msg=None):
if not a < b:
self.fail('%s not less than %s' % (repr(a), repr(b)))
def assertLessEqual(self, a, b, msg=None):
if not a <= b:
self.fail('%s not less than or equal to %s' % (repr(a), repr(b)))
def assertGreater(self, a, b, msg=None):
if not a > b:
self.fail('%s not greater than %s' % (repr(a), repr(b)))
@staticmethod
def bootstrap():
parser = argparse.ArgumentParser(description='run OpenCV python tests')
parser.add_argument('--repo', help='use sample image files from local git repository (path to folder), '
'if not set, samples will be downloaded from github.com')
parser.add_argument('--data', help='<not used> use data files from local folder (path to folder), '
'if not set, data files will be downloaded from docs.opencv.org')
args, other = parser.parse_known_args()
print("Testing OpenCV", cv.__version__)
print("Local repo path:", args.repo)
NewOpenCVTests.repoPath = args.repo
try:
NewOpenCVTests.extraTestDataPath = os.environ['OPENCV_TEST_DATA_PATH']
except KeyError:
print('Missing opencv extra repository. Some of tests may fail.')
random.seed(0)
unit_argv = [sys.argv[0]] + other
unittest.main(argv=unit_argv)
def intersectionRate(s1, s2):
x1, y1, x2, y2 = s1
s1 = np.array([[x1, y1], [x2,y1], [x2, y2], [x1, y2]])
x1, y1, x2, y2 = s2
s2 = np.array([[x1, y1], [x2,y1], [x2, y2], [x1, y2]])
area, _intersection = cv.intersectConvexConvex(s1, s2)
return 2 * area / (cv.contourArea(s1) + cv.contourArea(s2))
def isPointInRect(p, rect):
if rect[0] <= p[0] and rect[1] <=p[1] and p[0] <= rect[2] and p[1] <= rect[3]:
return True
else:
return False

View File

@ -0,0 +1,119 @@
#!/usr/bin/env python
# Python 2/3 compatibility
from __future__ import print_function
import numpy as np
from numpy import pi, sin, cos
import cv2 as cv
defaultSize = 512
class TestSceneRender():
def __init__(self, bgImg = None, fgImg = None, deformation = False, noise = 0.0, speed = 0.25, **params):
self.time = 0.0
self.timeStep = 1.0 / 30.0
self.foreground = fgImg
self.deformation = deformation
self.noise = noise
self.speed = speed
if bgImg is not None:
self.sceneBg = bgImg.copy()
else:
self.sceneBg = np.zeros(defaultSize, defaultSize, np.uint8)
self.w = self.sceneBg.shape[0]
self.h = self.sceneBg.shape[1]
if fgImg is not None:
self.foreground = fgImg.copy()
self.center = self.currentCenter = (int(self.w/2 - fgImg.shape[0]/2), int(self.h/2 - fgImg.shape[1]/2))
self.xAmpl = self.sceneBg.shape[0] - (self.center[0] + fgImg.shape[0])
self.yAmpl = self.sceneBg.shape[1] - (self.center[1] + fgImg.shape[1])
self.initialRect = np.array([ (self.h/2, self.w/2), (self.h/2, self.w/2 + self.w/10),
(self.h/2 + self.h/10, self.w/2 + self.w/10), (self.h/2 + self.h/10, self.w/2)]).astype(int)
self.currentRect = self.initialRect
np.random.seed(10)
def getXOffset(self, time):
return int(self.xAmpl*cos(time*self.speed))
def getYOffset(self, time):
return int(self.yAmpl*sin(time*self.speed))
def setInitialRect(self, rect):
self.initialRect = rect
def getRectInTime(self, time):
if self.foreground is not None:
tmp = np.array(self.center) + np.array((self.getXOffset(time), self.getYOffset(time)))
x0, y0 = tmp
x1, y1 = tmp + self.foreground.shape[0:2]
return np.array([y0, x0, y1, x1])
else:
x0, y0 = self.initialRect[0] + np.array((self.getXOffset(time), self.getYOffset(time)))
x1, y1 = self.initialRect[2] + np.array((self.getXOffset(time), self.getYOffset(time)))
return np.array([y0, x0, y1, x1])
def getCurrentRect(self):
if self.foreground is not None:
x0 = self.currentCenter[0]
y0 = self.currentCenter[1]
x1 = self.currentCenter[0] + self.foreground.shape[0]
y1 = self.currentCenter[1] + self.foreground.shape[1]
return np.array([y0, x0, y1, x1])
else:
x0, y0 = self.currentRect[0]
x1, y1 = self.currentRect[2]
return np.array([x0, y0, x1, y1])
def getNextFrame(self):
img = self.sceneBg.copy()
if self.foreground is not None:
self.currentCenter = (self.center[0] + self.getXOffset(self.time), self.center[1] + self.getYOffset(self.time))
img[self.currentCenter[0]:self.currentCenter[0]+self.foreground.shape[0],
self.currentCenter[1]:self.currentCenter[1]+self.foreground.shape[1]] = self.foreground
else:
self.currentRect = self.initialRect + np.int( 30*cos(self.time) + 50*sin(self.time/3))
if self.deformation:
self.currentRect[1:3] += int(self.h/20*cos(self.time))
cv.fillConvexPoly(img, self.currentRect, (0, 0, 255))
self.time += self.timeStep
if self.noise:
noise = np.zeros(self.sceneBg.shape, np.int8)
cv.randn(noise, np.zeros(3), np.ones(3)*255*self.noise)
img = cv.add(img, noise, dtype=cv.CV_8UC3)
return img
def resetTime(self):
self.time = 0.0
if __name__ == '__main__':
backGr = cv.imread('../../../samples/data/lena.jpg')
render = TestSceneRender(backGr, noise = 0.5)
while True:
img = render.getNextFrame()
cv.imshow('img', img)
ch = cv.waitKey(3)
if ch == 27:
break
cv.destroyAllWindows()