Merge remote-tracking branch 'github/master' into pullreq/140319-PyrLKOpticalFlow

Conflicts:
	modules/video/src/opencl/pyrlk.cl
This commit is contained in:
krodyush 2014-04-04 11:26:08 +04:00
commit 4ca695cab0
163 changed files with 3042 additions and 2253 deletions

View File

@ -9,7 +9,7 @@
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
import re import re
from _compat import text_type, string_types, int_types, \ from ._compat import text_type, string_types, int_types, \
unichr, PY2 unichr, PY2
@ -227,7 +227,7 @@ class _MarkupEscapeHelper(object):
try: try:
from _speedups import escape, escape_silent, soft_unicode from _speedups import escape, escape_silent, soft_unicode
except ImportError: except ImportError:
from _native import escape, escape_silent, soft_unicode from ._native import escape, escape_silent, soft_unicode
if not PY2: if not PY2:
soft_str = soft_unicode soft_str = soft_unicode

View File

@ -8,7 +8,7 @@
:copyright: (c) 2010 by Armin Ronacher. :copyright: (c) 2010 by Armin Ronacher.
:license: BSD, see LICENSE for more details. :license: BSD, see LICENSE for more details.
""" """
from _compat import text_type from ._compat import text_type
def escape(s): def escape(s):

View File

@ -517,4 +517,4 @@ class Joiner(object):
# Imported here because that's where it was in the past # Imported here because that's where it was in the past
from markupsafe import Markup, escape, soft_unicode from .markupsafe import Markup, escape, soft_unicode

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -438,7 +438,6 @@ include(cmake/OpenCVFindLibsGUI.cmake)
include(cmake/OpenCVFindLibsVideo.cmake) include(cmake/OpenCVFindLibsVideo.cmake)
include(cmake/OpenCVFindLibsPerf.cmake) include(cmake/OpenCVFindLibsPerf.cmake)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# Detect other 3rd-party libraries/tools # Detect other 3rd-party libraries/tools
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------

View File

@ -217,3 +217,42 @@ else()
unset(CUDA_ARCH_BIN CACHE) unset(CUDA_ARCH_BIN CACHE)
unset(CUDA_ARCH_PTX CACHE) unset(CUDA_ARCH_PTX CACHE)
endif() endif()
if(HAVE_CUDA)
set(CUDA_LIBS_PATH "")
foreach(p ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
get_filename_component(_tmp ${p} PATH)
list(APPEND CUDA_LIBS_PATH ${_tmp})
endforeach()
if(HAVE_CUBLAS)
foreach(p ${CUDA_cublas_LIBRARY})
get_filename_component(_tmp ${p} PATH)
list(APPEND CUDA_LIBS_PATH ${_tmp})
endforeach()
endif()
if(HAVE_CUFFT)
foreach(p ${CUDA_cufft_LIBRARY})
get_filename_component(_tmp ${p} PATH)
list(APPEND CUDA_LIBS_PATH ${_tmp})
endforeach()
endif()
list(REMOVE_DUPLICATES CUDA_LIBS_PATH)
link_directories(${CUDA_LIBS_PATH})
set(CUDA_LIBRARIES_ABS ${CUDA_LIBRARIES})
ocv_convert_to_lib_name(CUDA_LIBRARIES ${CUDA_LIBRARIES})
set(CUDA_npp_LIBRARY_ABS ${CUDA_npp_LIBRARY})
ocv_convert_to_lib_name(CUDA_npp_LIBRARY ${CUDA_npp_LIBRARY})
if(HAVE_CUBLAS)
set(CUDA_cublas_LIBRARY_ABS ${CUDA_cublas_LIBRARY})
ocv_convert_to_lib_name(CUDA_cublas_LIBRARY ${CUDA_cublas_LIBRARY})
endif()
if(HAVE_CUFFT)
set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
endif()
endif()

View File

@ -27,7 +27,8 @@
# The verbose template for OpenCV module: # The verbose template for OpenCV module:
# #
# ocv_add_module(modname <dependencies>) # ocv_add_module(modname <dependencies>)
# ocv_glob_module_sources() or glob them manually and ocv_set_module_sources(...) # ocv_glob_module_sources(([EXCLUDE_CUDA] <extra sources&headers>)
# or glob them manually and ocv_set_module_sources(...)
# ocv_module_include_directories(<extra include directories>) # ocv_module_include_directories(<extra include directories>)
# ocv_create_module() # ocv_create_module()
# <add extra link dependencies, compiler options, etc> # <add extra link dependencies, compiler options, etc>
@ -478,9 +479,15 @@ endmacro()
# finds and sets headers and sources for the standard OpenCV module # finds and sets headers and sources for the standard OpenCV module
# Usage: # Usage:
# ocv_glob_module_sources(<extra sources&headers in the same format as used in ocv_set_module_sources>) # ocv_glob_module_sources([EXCLUDE_CUDA] <extra sources&headers in the same format as used in ocv_set_module_sources>)
macro(ocv_glob_module_sources) macro(ocv_glob_module_sources)
file(GLOB_RECURSE lib_srcs "src/*.cpp") set(_argn ${ARGN})
list(FIND _argn "EXCLUDE_CUDA" exclude_cuda)
if(NOT exclude_cuda EQUAL -1)
list(REMOVE_AT _argn ${exclude_cuda})
endif()
file(GLOB_RECURSE lib_srcs "src/*.cpp")
file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h") file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h")
file(GLOB lib_hdrs "include/opencv2/*.hpp" "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h") file(GLOB lib_hdrs "include/opencv2/*.hpp" "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h") file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h")
@ -492,15 +499,21 @@ macro(ocv_glob_module_sources)
ocv_source_group("Src" DIRBASE "${CMAKE_CURRENT_SOURCE_DIR}/src" FILES ${lib_srcs} ${lib_int_hdrs}) ocv_source_group("Src" DIRBASE "${CMAKE_CURRENT_SOURCE_DIR}/src" FILES ${lib_srcs} ${lib_int_hdrs})
ocv_source_group("Include" DIRBASE "${CMAKE_CURRENT_SOURCE_DIR}/include" FILES ${lib_hdrs} ${lib_hdrs_detail}) ocv_source_group("Include" DIRBASE "${CMAKE_CURRENT_SOURCE_DIR}/include" FILES ${lib_hdrs} ${lib_hdrs_detail})
file(GLOB lib_cuda_srcs "src/cuda/*.cu") if (exclude_cuda EQUAL -1)
set(cuda_objs "") file(GLOB lib_cuda_srcs "src/cuda/*.cu")
set(lib_cuda_hdrs "") set(cuda_objs "")
if(HAVE_CUDA AND lib_cuda_srcs) set(lib_cuda_hdrs "")
ocv_include_directories(${CUDA_INCLUDE_DIRS}) if(HAVE_CUDA)
file(GLOB lib_cuda_hdrs "src/cuda/*.hpp") ocv_include_directories(${CUDA_INCLUDE_DIRS})
file(GLOB lib_cuda_hdrs "src/cuda/*.hpp")
ocv_cuda_compile(cuda_objs ${lib_cuda_srcs} ${lib_cuda_hdrs}) ocv_cuda_compile(cuda_objs ${lib_cuda_srcs} ${lib_cuda_hdrs})
source_group("Src\\Cuda" FILES ${lib_cuda_srcs} ${lib_cuda_hdrs}) source_group("Src\\Cuda" FILES ${lib_cuda_srcs} ${lib_cuda_hdrs})
endif()
else()
set(cuda_objs "")
set(lib_cuda_srcs "")
set(lib_cuda_hdrs "")
endif() endif()
file(GLOB cl_kernels "src/opencl/*.cl") file(GLOB cl_kernels "src/opencl/*.cl")
@ -516,8 +529,8 @@ macro(ocv_glob_module_sources)
list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp") list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
endif() endif()
ocv_set_module_sources(${ARGN} HEADERS ${lib_hdrs} ${lib_hdrs_detail} ocv_set_module_sources(${_argn} HEADERS ${lib_hdrs} ${lib_hdrs_detail}
SOURCES ${lib_srcs} ${lib_int_hdrs} ${cuda_objs} ${lib_cuda_srcs} ${lib_cuda_hdrs}) SOURCES ${lib_srcs} ${lib_int_hdrs} ${cuda_objs} ${lib_cuda_srcs} ${lib_cuda_hdrs})
endmacro() endmacro()
# creates OpenCV module in current folder # creates OpenCV module in current folder
@ -622,11 +635,20 @@ endmacro()
# short command for adding simple OpenCV module # short command for adding simple OpenCV module
# see ocv_add_module for argument details # see ocv_add_module for argument details
# Usage: # Usage:
# ocv_define_module(module_name [INTERNAL] [REQUIRED] [<list of dependencies>] [OPTIONAL <list of optional dependencies>]) # ocv_define_module(module_name [INTERNAL] [EXCLUDE_CUDA] [REQUIRED] [<list of dependencies>] [OPTIONAL <list of optional dependencies>])
macro(ocv_define_module module_name) macro(ocv_define_module module_name)
ocv_add_module(${module_name} ${ARGN}) set(_argn ${ARGN})
set(exclude_cuda "")
foreach(arg ${_argn})
if("${arg}" STREQUAL "EXCLUDE_CUDA")
set(exclude_cuda "${arg}")
list(REMOVE_ITEM _argn ${arg})
endif()
endforeach()
ocv_add_module(${module_name} ${_argn})
ocv_module_include_directories() ocv_module_include_directories()
ocv_glob_module_sources() ocv_glob_module_sources(${exclude_cuda})
ocv_create_module() ocv_create_module()
ocv_add_precompiled_headers(${the_module}) ocv_add_precompiled_headers(${the_module})

View File

@ -19,8 +19,8 @@
# This file will define the following variables: # This file will define the following variables:
# - OpenCV_LIBS : The list of all imported targets for OpenCV modules. # - OpenCV_LIBS : The list of all imported targets for OpenCV modules.
# - OpenCV_INCLUDE_DIRS : The OpenCV include directories. # - OpenCV_INCLUDE_DIRS : The OpenCV include directories.
# - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability # - OpenCV_COMPUTE_CAPABILITIES : The version of compute capability.
# - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API # - OpenCV_ANDROID_NATIVE_API_LEVEL : Minimum required level of Android API.
# - OpenCV_VERSION : The version of this OpenCV build: "@OPENCV_VERSION_PLAIN@" # - OpenCV_VERSION : The version of this OpenCV build: "@OPENCV_VERSION_PLAIN@"
# - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION: "@OPENCV_VERSION_MAJOR@" # - OpenCV_VERSION_MAJOR : Major version part of OpenCV_VERSION: "@OPENCV_VERSION_MAJOR@"
# - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION: "@OPENCV_VERSION_MINOR@" # - OpenCV_VERSION_MINOR : Minor version part of OpenCV_VERSION: "@OPENCV_VERSION_MINOR@"
@ -28,25 +28,29 @@
# - OpenCV_VERSION_STATUS : Development status of this build: "@OPENCV_VERSION_STATUS@" # - OpenCV_VERSION_STATUS : Development status of this build: "@OPENCV_VERSION_STATUS@"
# #
# Advanced variables: # Advanced variables:
# - OpenCV_SHARED # - OpenCV_SHARED : Use OpenCV as shared library
# - OpenCV_CONFIG_PATH # - OpenCV_CONFIG_PATH : Path to this OpenCVConfig.cmake
# - OpenCV_INSTALL_PATH (not set on Windows) # - OpenCV_INSTALL_PATH : OpenCV location (not set on Windows)
# - OpenCV_LIB_COMPONENTS # - OpenCV_LIB_COMPONENTS : Present OpenCV modules list
# - OpenCV_USE_MANGLED_PATHS # - OpenCV_USE_MANGLED_PATHS : Mangled OpenCV path flag
# - OpenCV_HAVE_ANDROID_CAMERA # - OpenCV_MODULES_SUFFIX : The suffix for OpenCVModules-XXX.cmake file
# - OpenCV_HAVE_ANDROID_CAMERA : Presence of Android native camera wrappers
# #
# Deprecated variables: # Deprecated variables:
# - OpenCV_VERSION_TWEAK : Always "0" # - OpenCV_VERSION_TWEAK : Always "0"
# #
# =================================================================================== # ===================================================================================
set(modules_file_suffix "") if(NOT DEFINED OpenCV_MODULES_SUFFIX)
if(ANDROID) if(ANDROID)
string(REPLACE - _ modules_file_suffix "_${ANDROID_NDK_ABI_NAME}") string(REPLACE - _ OpenCV_MODULES_SUFFIX "_${ANDROID_NDK_ABI_NAME}")
else()
set(OpenCV_MODULES_SUFFIX "")
endif()
endif() endif()
if(NOT TARGET opencv_core) if(NOT TARGET opencv_core)
include(${CMAKE_CURRENT_LIST_DIR}/OpenCVModules${modules_file_suffix}.cmake) include(${CMAKE_CURRENT_LIST_DIR}/OpenCVModules${OpenCV_MODULES_SUFFIX}.cmake)
endif() endif()
# TODO All things below should be reviewed. What is about of moving this code into related modules (special vars/hooks/files) # TODO All things below should be reviewed. What is about of moving this code into related modules (special vars/hooks/files)
@ -209,7 +213,7 @@ foreach(__opttype OPT DBG)
SET(OpenCV_EXTRA_LIBS_${__opttype} "") SET(OpenCV_EXTRA_LIBS_${__opttype} "")
# CUDA # CUDA
if(OpenCV_CUDA_VERSION AND (CMAKE_CROSSCOMPILING OR (WIN32 AND NOT OpenCV_SHARED))) if(OpenCV_CUDA_VERSION)
if(NOT CUDA_FOUND) if(NOT CUDA_FOUND)
find_package(CUDA ${OpenCV_CUDA_VERSION} EXACT REQUIRED) find_package(CUDA ${OpenCV_CUDA_VERSION} EXACT REQUIRED)
else() else()
@ -218,32 +222,41 @@ foreach(__opttype OPT DBG)
endif() endif()
endif() endif()
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_LIBRARIES}) set(OpenCV_CUDA_LIBS_ABSPATH ${CUDA_LIBRARIES})
if(${CUDA_VERSION} VERSION_LESS "5.5") if(${CUDA_VERSION} VERSION_LESS "5.5")
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_npp_LIBRARY}) list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_npp_LIBRARY})
else() else()
find_cuda_helper_libs(nppc) find_cuda_helper_libs(nppc)
find_cuda_helper_libs(nppi) find_cuda_helper_libs(nppi)
find_cuda_helper_libs(npps) find_cuda_helper_libs(npps)
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_nppc_LIBRARY} ${CUDA_nppi_LIBRARY} ${CUDA_npps_LIBRARY}) list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nppc_LIBRARY} ${CUDA_nppi_LIBRARY} ${CUDA_npps_LIBRARY})
endif() endif()
if(OpenCV_USE_CUBLAS) if(OpenCV_USE_CUBLAS)
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_CUBLAS_LIBRARIES}) list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_CUBLAS_LIBRARIES})
endif() endif()
if(OpenCV_USE_CUFFT) if(OpenCV_USE_CUFFT)
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_CUFFT_LIBRARIES}) list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_CUFFT_LIBRARIES})
endif() endif()
if(OpenCV_USE_NVCUVID) if(OpenCV_USE_NVCUVID)
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_nvcuvid_LIBRARIES}) list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nvcuvid_LIBRARIES})
endif() endif()
if(WIN32) if(WIN32)
list(APPEND OpenCV_EXTRA_LIBS_${__opttype} ${CUDA_nvcuvenc_LIBRARIES}) list(APPEND OpenCV_CUDA_LIBS_ABSPATH ${CUDA_nvcuvenc_LIBRARIES})
endif() endif()
set(OpenCV_CUDA_LIBS_RELPATH "")
foreach(l ${OpenCV_CUDA_LIBS_ABSPATH})
get_filename_component(_tmp ${l} PATH)
list(APPEND OpenCV_CUDA_LIBS_RELPATH ${_tmp})
endforeach()
list(REMOVE_DUPLICATES OpenCV_CUDA_LIBS_RELPATH)
link_directories(${OpenCV_CUDA_LIBS_RELPATH})
endif() endif()
endforeach() endforeach()

View File

@ -304,11 +304,11 @@ extlinks = {
'oldbasicstructures' : ('http://docs.opencv.org/modules/core/doc/old_basic_structures.html#%s', None), 'oldbasicstructures' : ('http://docs.opencv.org/modules/core/doc/old_basic_structures.html#%s', None),
'readwriteimagevideo' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None), 'readwriteimagevideo' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None),
'operationsonarrays' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#%s', None), 'operationsonarrays' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#%s', None),
'utilitysystemfunctions':('http://docs.opencv.org/modules/core/doc/utility_and_system_functions_and_macros.html#%s', None), 'utilitysystemfunctions' : ('http://docs.opencv.org/modules/core/doc/utility_and_system_functions_and_macros.html#%s', None),
'imgprocfilter':('http://docs.opencv.org/modules/imgproc/doc/filtering.html#%s', None), 'imgprocfilter' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html#%s', None),
'svms':('http://docs.opencv.org/modules/ml/doc/support_vector_machines.html#%s', None), 'svms' : ('http://docs.opencv.org/modules/ml/doc/support_vector_machines.html#%s', None),
'drawingfunc':('http://docs.opencv.org/modules/core/doc/drawing_functions.html#%s', None), 'drawingfunc' : ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#%s', None),
'xmlymlpers':('http://docs.opencv.org/modules/core/doc/xml_yaml_persistence.html#%s', None), 'xmlymlpers' : ('http://docs.opencv.org/modules/core/doc/xml_yaml_persistence.html#%s', None),
'hgvideo' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None), 'hgvideo' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#%s', None),
'gpuinit' : ('http://docs.opencv.org/modules/gpu/doc/initalization_and_information.html#%s', None), 'gpuinit' : ('http://docs.opencv.org/modules/gpu/doc/initalization_and_information.html#%s', None),
'gpudatastructure' : ('http://docs.opencv.org/modules/gpu/doc/data_structures.html#%s', None), 'gpudatastructure' : ('http://docs.opencv.org/modules/gpu/doc/data_structures.html#%s', None),
@ -316,56 +316,58 @@ extlinks = {
'gpuperelement' : ('http://docs.opencv.org/modules/gpu/doc/per_element_operations.html#%s', None), 'gpuperelement' : ('http://docs.opencv.org/modules/gpu/doc/per_element_operations.html#%s', None),
'gpuimgproc' : ('http://docs.opencv.org/modules/gpu/doc/image_processing.html#%s', None), 'gpuimgproc' : ('http://docs.opencv.org/modules/gpu/doc/image_processing.html#%s', None),
'gpumatrixreduct' : ('http://docs.opencv.org/modules/gpu/doc/matrix_reductions.html#%s', None), 'gpumatrixreduct' : ('http://docs.opencv.org/modules/gpu/doc/matrix_reductions.html#%s', None),
'filtering':('http://docs.opencv.org/modules/imgproc/doc/filtering.html#%s', None), 'filtering' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html#%s', None),
'flann' : ('http://docs.opencv.org/modules/flann/doc/flann_fast_approximate_nearest_neighbor_search.html#%s', None ), 'flann' : ('http://docs.opencv.org/modules/flann/doc/flann_fast_approximate_nearest_neighbor_search.html#%s', None ),
'calib3d' : ('http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#%s', None ), 'calib3d' : ('http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#%s', None ),
'feature2d' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html#%s', None ), 'feature2d' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html#%s', None ),
'imgproc_geometric' : ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html#%s', None ), 'imgproc_geometric' : ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html#%s', None ),
'miscellaneous_transformations' : ('http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#%s', None),
'user_interface' : ('http://docs.opencv.org/modules/highgui/doc/user_interface.html#%s', None),
# 'opencv_group' : ('http://answers.opencv.org/%s', None), # 'opencv_group' : ('http://answers.opencv.org/%s', None),
'opencv_qa' : ('http://answers.opencv.org/%s', None), 'opencv_qa' : ('http://answers.opencv.org/%s', None),
'how_to_contribute' : ('http://code.opencv.org/projects/opencv/wiki/How_to_contribute/%s', None), 'how_to_contribute' : ('http://code.opencv.org/projects/opencv/wiki/How_to_contribute/%s', None),
'cvt_color': ('http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=cvtcolor#cvtcolor%s', None), 'cvt_color' : ('http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=cvtcolor#cvtcolor%s', None),
'imread': ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#imread%s', None), 'imread' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#imread%s', None),
'imwrite': ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imwrite#imwrite%s', None), 'imwrite' : ('http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imwrite#imwrite%s', None),
'imshow': ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=imshow#imshow%s', None), 'imshow' : ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=imshow#imshow%s', None),
'named_window': ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=namedwindow#namedwindow%s', None), 'named_window' : ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=namedwindow#namedwindow%s', None),
'wait_key': ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=waitkey#waitkey%s', None), 'wait_key' : ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=waitkey#waitkey%s', None),
'add_weighted': ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=addweighted#addweighted%s', None), 'add_weighted' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=addweighted#addweighted%s', None),
'saturate_cast': ('http://docs.opencv.org/modules/core/doc/utility_and_system_functions_and_macros.html?highlight=saturate_cast#saturate-cast%s', None), 'saturate_cast' : ('http://docs.opencv.org/modules/core/doc/utility_and_system_functions_and_macros.html?highlight=saturate_cast#saturate-cast%s', None),
'mat_zeros': ('http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=zeros#mat-zeros%s', None), 'mat_zeros' : ('http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=zeros#mat-zeros%s', None),
'convert_to': ('http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-convertto%s', None), 'convert_to' : ('http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-convertto%s', None),
'create_trackbar': ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=createtrackbar#createtrackbar%s', None), 'create_trackbar' : ('http://docs.opencv.org/modules/highgui/doc/user_interface.html?highlight=createtrackbar#createtrackbar%s', None),
'point': ('http://docs.opencv.org/modules/core/doc/basic_structures.html#point%s', None), 'point' : ('http://docs.opencv.org/modules/core/doc/basic_structures.html#point%s', None),
'scalar': ('http://docs.opencv.org/modules/core/doc/basic_structures.html#scalar%s', None), 'scalar' : ('http://docs.opencv.org/modules/core/doc/basic_structures.html#scalar%s', None),
'line': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#line%s', None), 'line' : ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#line%s', None),
'ellipse': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#ellipse%s', None), 'ellipse' : ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#ellipse%s', None),
'rectangle': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#rectangle%s', None), 'rectangle' : ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#rectangle%s', None),
'circle': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#circle%s', None), 'circle' : ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#circle%s', None),
'fill_poly': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#fillpoly%s', None), 'fill_poly' : ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#fillpoly%s', None),
'rng': ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=rng#rng%s', None), 'rng' : ('http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=rng#rng%s', None),
'put_text': ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#puttext%s', None), 'put_text' : ('http://docs.opencv.org/modules/core/doc/drawing_functions.html#puttext%s', None),
'gaussian_blur': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=gaussianblur#gaussianblur%s', None), 'gaussian_blur' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=gaussianblur#gaussianblur%s', None),
'blur': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=blur#blur%s', None), 'blur' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=blur#blur%s', None),
'median_blur': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=medianblur#medianblur%s', None), 'median_blur' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=medianblur#medianblur%s', None),
'bilateral_filter': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=bilateralfilter#bilateralfilter%s', None), 'bilateral_filter' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=bilateralfilter#bilateralfilter%s', None),
'erode': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=erode#erode%s', None), 'erode' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=erode#erode%s', None),
'dilate': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=dilate#dilate%s', None), 'dilate' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=dilate#dilate%s', None),
'get_structuring_element': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=getstructuringelement#getstructuringelement%s', None), 'get_structuring_element' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=getstructuringelement#getstructuringelement%s', None),
'flood_fill': ( 'http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=floodfill#floodfill%s', None), 'flood_fill' : ( 'http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=floodfill#floodfill%s', None),
'morphology_ex': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=morphologyex#morphologyex%s', None), 'morphology_ex' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=morphologyex#morphologyex%s', None),
'pyr_down': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=pyrdown#pyrdown%s', None), 'pyr_down' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=pyrdown#pyrdown%s', None),
'pyr_up': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=pyrup#pyrup%s', None), 'pyr_up' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=pyrup#pyrup%s', None),
'resize': ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html?highlight=resize#resize%s', None), 'resize' : ('http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html?highlight=resize#resize%s', None),
'threshold': ('http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=threshold#threshold%s', None), 'threshold' : ('http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html?highlight=threshold#threshold%s', None),
'filter2d': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=filter2d#filter2d%s', None), 'filter2d' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=filter2d#filter2d%s', None),
'copy_make_border': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=copymakeborder#copymakeborder%s', None), 'copy_make_border' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=copymakeborder#copymakeborder%s', None),
'sobel': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=sobel#sobel%s', None), 'sobel' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=sobel#sobel%s', None),
'scharr': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=scharr#scharr%s', None), 'scharr' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=scharr#scharr%s', None),
'laplacian': ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=laplacian#laplacian%s', None), 'laplacian' : ('http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=laplacian#laplacian%s', None),
'canny': ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=canny#canny%s', None), 'canny' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=canny#canny%s', None),
'copy_to': ('http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=copyto#mat-copyto%s', None), 'copy_to' : ('http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=copyto#mat-copyto%s', None),
'hough_lines' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghlines#houghlines%s', None), 'hough_lines' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghlines#houghlines%s', None),
'hough_lines_p' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghlinesp#houghlinesp%s', None), 'hough_lines_p' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghlinesp#houghlinesp%s', None),
'hough_circles' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghcircles#houghcircles%s', None), 'hough_circles' : ('http://docs.opencv.org/modules/imgproc/doc/feature_detection.html?highlight=houghcircles#houghcircles%s', None),

View File

@ -123,7 +123,7 @@ Let (x,y) be the top-left coordinate of the rectangle and (w,h) be its width and
7.b. Rotated Rectangle 7.b. Rotated Rectangle
----------------------- -----------------------
Here, bounding rectangle is drawn with minimum area, so it considers the rotation also. The function used is **cv2.minAreaRect()**. It returns a Box2D structure which contains following detals - ( top-left corner(x,y), (width, height), angle of rotation ). But to draw this rectangle, we need 4 corners of the rectangle. It is obtained by the function **cv2.boxPoints()** Here, bounding rectangle is drawn with minimum area, so it considers the rotation also. The function used is **cv2.minAreaRect()**. It returns a Box2D structure which contains following detals - ( center (x,y), (width, height), angle of rotation ). But to draw this rectangle, we need 4 corners of the rectangle. It is obtained by the function **cv2.boxPoints()**
:: ::
rect = cv2.minAreaRect(cnt) rect = cv2.minAreaRect(cnt)

View File

@ -7,45 +7,41 @@ Introduction to OpenCV-Python Tutorials
OpenCV OpenCV
=============== ===============
OpenCV was started at Intel in 1999 by **Gary Bradsky** and the first release came out in 2000. **Vadim Pisarevsky** joined Gary Bradsky to manage Intel's Russian software OpenCV team. In 2005, OpenCV was used on Stanley, the vehicle who won 2005 DARPA Grand Challenge. Later its active development continued under the support of Willow Garage, with Gary Bradsky and Vadim Pisarevsky leading the project. Right now, OpenCV supports a lot of algorithms related to Computer Vision and Machine Learning and it is expanding day-by-day. OpenCV was started at Intel in 1999 by **Gary Bradsky**, and the first release came out in 2000. **Vadim Pisarevsky** joined Gary Bradsky to manage Intel's Russian software OpenCV team. In 2005, OpenCV was used on Stanley, the vehicle that won the 2005 DARPA Grand Challenge. Later, its active development continued under the support of Willow Garage with Gary Bradsky and Vadim Pisarevsky leading the project. OpenCV now supports a multitude of algorithms related to Computer Vision and Machine Learning and is expanding day by day.
Currently OpenCV supports a wide variety of programming languages like C++, Python, Java etc and is available on different platforms including Windows, Linux, OS X, Android, iOS etc. Also, interfaces based on CUDA and OpenCL are also under active development for high-speed GPU operations. OpenCV supports a wide variety of programming languages such as C++, Python, Java, etc., and is available on different platforms including Windows, Linux, OS X, Android, and iOS. Interfaces for high-speed GPU operations based on CUDA and OpenCL are also under active development.
OpenCV-Python is the Python API of OpenCV. It combines the best qualities of OpenCV C++ API and Python language. OpenCV-Python is the Python API for OpenCV, combining the best qualities of the OpenCV C++ API and the Python language.
OpenCV-Python OpenCV-Python
=============== ===============
Python is a general purpose programming language started by **Guido van Rossum**, which became very popular in short time mainly because of its simplicity and code readability. It enables the programmer to express his ideas in fewer lines of code without reducing any readability. OpenCV-Python is a library of Python bindings designed to solve computer vision problems.
Compared to other languages like C/C++, Python is slower. But another important feature of Python is that it can be easily extended with C/C++. This feature helps us to write computationally intensive codes in C/C++ and create a Python wrapper for it so that we can use these wrappers as Python modules. This gives us two advantages: first, our code is as fast as original C/C++ code (since it is the actual C++ code working in background) and second, it is very easy to code in Python. This is how OpenCV-Python works, it is a Python wrapper around original C++ implementation. Python is a general purpose programming language started by **Guido van Rossum** that became very popular very quickly, mainly because of its simplicity and code readability. It enables the programmer to express ideas in fewer lines of code without reducing readability.
And the support of Numpy makes the task more easier. **Numpy** is a highly optimized library for numerical operations. It gives a MATLAB-style syntax. All the OpenCV array structures are converted to-and-from Numpy arrays. So whatever operations you can do in Numpy, you can combine it with OpenCV, which increases number of weapons in your arsenal. Besides that, several other libraries like SciPy, Matplotlib which supports Numpy can be used with this. Compared to languages like C/C++, Python is slower. That said, Python can be easily extended with C/C++, which allows us to write computationally intensive code in C/C++ and create Python wrappers that can be used as Python modules. This gives us two advantages: first, the code is as fast as the original C/C++ code (since it is the actual C++ code working in background) and second, it easier to code in Python than C/C++. OpenCV-Python is a Python wrapper for the original OpenCV C++ implementation.
So OpenCV-Python is an appropriate tool for fast prototyping of computer vision problems. OpenCV-Python makes use of **Numpy**, which is a highly optimized library for numerical operations with a MATLAB-style syntax. All the OpenCV array structures are converted to and from Numpy arrays. This also makes it easier to integrate with other libraries that use Numpy such as SciPy and Matplotlib.
OpenCV-Python Tutorials OpenCV-Python Tutorials
============================= =============================
OpenCV introduces a new set of tutorials which will guide you through various functions available in OpenCV-Python. **This guide is mainly focused on OpenCV 3.x version** (although most of the tutorials will work with OpenCV 2.x also). OpenCV introduces a new set of tutorials which will guide you through various functions available in OpenCV-Python. **This guide is mainly focused on OpenCV 3.x version** (although most of the tutorials will also work with OpenCV 2.x).
A prior knowledge on Python and Numpy is required before starting because they won't be covered in this guide. **Especially, a good knowledge on Numpy is must to write optimized codes in OpenCV-Python.** Prior knowledge of Python and Numpy is recommended as they won't be covered in this guide. **Proficiency with Numpy is a must in order to write optimized code using OpenCV-Python.**
This tutorial has been started by *Abid Rahman K.* as part of Google Summer of Code 2013 program, under the guidance of *Alexander Mordvintsev*. This tutorial was originally started by *Abid Rahman K.* as part of the Google Summer of Code 2013 program under the guidance of *Alexander Mordvintsev*.
OpenCV Needs You !!! OpenCV Needs You !!!
========================== ==========================
Since OpenCV is an open source initiative, all are welcome to make contributions to this library. And it is same for this tutorial also. Since OpenCV is an open source initiative, all are welcome to make contributions to the library, documentation, and tutorials. If you find any mistake in this tutorial (from a small spelling mistake to an egregious error in code or concept), feel free to correct it by cloning OpenCV in `GitHub <https://github.com/Itseez/opencv>`_ and submitting a pull request. OpenCV developers will check your pull request, give you important feedback and (once it passes the approval of the reviewer) it will be merged into OpenCV. You will then become an open source contributor :-)
So, if you find any mistake in this tutorial (whether it be a small spelling mistake or a big error in code or concepts, whatever), feel free to correct it. As new modules are added to OpenCV-Python, this tutorial will have to be expanded. If you are familiar with a particular algorithm and can write up a tutorial including basic theory of the algorithm and code showing example usage, please do so.
And that will be a good task for freshers who begin to contribute to open source projects. Just fork the OpenCV in github, make necessary corrections and send a pull request to OpenCV. OpenCV developers will check your pull request, give you important feedback and once it passes the approval of the reviewer, it will be merged to OpenCV. Then you become a open source contributor. Similar is the case with other tutorials, documentation etc.
As new modules are added to OpenCV-Python, this tutorial will have to be expanded. So those who knows about particular algorithm can write up a tutorial which includes a basic theory of the algorithm and a code showing basic usage of the algorithm and submit it to OpenCV.
Remember, we **together** can make this project a great success !!! Remember, we **together** can make this project a great success !!!

View File

@ -52,7 +52,7 @@ To use meanshift in OpenCV, first we need to setup the target, find its histogra
# set up the ROI for tracking # set up the ROI for tracking
roi = frame[r:r+h, c:c+w] roi = frame[r:r+h, c:c+w]
hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.))) mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180]) roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX) cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)
@ -127,7 +127,7 @@ It is almost same as meanshift, but it returns a rotated rectangle (that is our
# set up the ROI for tracking # set up the ROI for tracking
roi = frame[r:r+h, c:c+w] roi = frame[r:r+h, c:c+w]
hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.))) mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180]) roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX) cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)

View File

@ -6,12 +6,12 @@ Adding (blending) two images using OpenCV
Goal Goal
===== =====
In this tutorial you will learn how to: In this tutorial you will learn:
.. container:: enumeratevisibleitemswithsquare .. container:: enumeratevisibleitemswithsquare
* What is *linear blending* and why it is useful. * what is *linear blending* and why it is useful;
* Add two images using :add_weighted:`addWeighted <>` * how to add two images using :add_weighted:`addWeighted <>`
Theory Theory
======= =======

View File

@ -18,7 +18,7 @@ We'll seek answers for the following questions:
Our test case Our test case
============= =============
Let us consider a simple color reduction method. Using the unsigned char C and C++ type for matrix item storing a channel of pixel may have up to 256 different values. For a three channel image this can allow the formation of way too many colors (16 million to be exact). Working with so many color shades may give a heavy blow to our algorithm performance. However, sometimes it is enough to work with a lot less of them to get the same final result. Let us consider a simple color reduction method. By using the unsigned char C and C++ type for matrix item storing, a channel of pixel may have up to 256 different values. For a three channel image this can allow the formation of way too many colors (16 million to be exact). Working with so many color shades may give a heavy blow to our algorithm performance. However, sometimes it is enough to work with a lot less of them to get the same final result.
In this cases it's common that we make a *color space reduction*. This means that we divide the color space current value with a new input value to end up with fewer colors. For instance every value between zero and nine takes the new value zero, every value between ten and nineteen the value ten and so on. In this cases it's common that we make a *color space reduction*. This means that we divide the color space current value with a new input value to end up with fewer colors. For instance every value between zero and nine takes the new value zero, every value between ten and nineteen the value ten and so on.

View File

@ -32,14 +32,14 @@ Here's a function that will do this:
.. code-block:: cpp .. code-block:: cpp
void Sharpen(const Mat& myImage,Mat& Result) void Sharpen(const Mat& myImage, Mat& Result)
{ {
CV_Assert(myImage.depth() == CV_8U); // accept only uchar images CV_Assert(myImage.depth() == CV_8U); // accept only uchar images
Result.create(myImage.size(),myImage.type()); Result.create(myImage.size(), myImage.type());
const int nChannels = myImage.channels(); const int nChannels = myImage.channels();
for(int j = 1 ; j < myImage.rows-1; ++j) for(int j = 1; j < myImage.rows - 1; ++j)
{ {
const uchar* previous = myImage.ptr<uchar>(j - 1); const uchar* previous = myImage.ptr<uchar>(j - 1);
const uchar* current = myImage.ptr<uchar>(j ); const uchar* current = myImage.ptr<uchar>(j );
@ -47,17 +47,17 @@ Here's a function that will do this:
uchar* output = Result.ptr<uchar>(j); uchar* output = Result.ptr<uchar>(j);
for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i) for(int i = nChannels; i < nChannels * (myImage.cols - 1); ++i)
{ {
*output++ = saturate_cast<uchar>(5*current[i] *output++ = saturate_cast<uchar>(5 * current[i]
-current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]); -current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]);
} }
} }
Result.row(0).setTo(Scalar(0)); Result.row(0).setTo(Scalar(0));
Result.row(Result.rows-1).setTo(Scalar(0)); Result.row(Result.rows - 1).setTo(Scalar(0));
Result.col(0).setTo(Scalar(0)); Result.col(0).setTo(Scalar(0));
Result.col(Result.cols-1).setTo(Scalar(0)); Result.col(Result.cols - 1).setTo(Scalar(0));
} }
At first we make sure that the input images data is in unsigned char format. For this we use the :utilitysystemfunctions:`CV_Assert <cv-assert>` function that throws an error when the expression inside it is false. At first we make sure that the input images data is in unsigned char format. For this we use the :utilitysystemfunctions:`CV_Assert <cv-assert>` function that throws an error when the expression inside it is false.
@ -70,14 +70,14 @@ We create an output image with the same size and the same type as our input. As
.. code-block:: cpp .. code-block:: cpp
Result.create(myImage.size(),myImage.type()); Result.create(myImage.size(), myImage.type());
const int nChannels = myImage.channels(); const int nChannels = myImage.channels();
We'll use the plain C [] operator to access pixels. Because we need to access multiple rows at the same time we'll acquire the pointers for each of them (a previous, a current and a next line). We need another pointer to where we're going to save the calculation. Then simply access the right items with the [] operator. For moving the output pointer ahead we simply increase this (with one byte) after each operation: We'll use the plain C [] operator to access pixels. Because we need to access multiple rows at the same time we'll acquire the pointers for each of them (a previous, a current and a next line). We need another pointer to where we're going to save the calculation. Then simply access the right items with the [] operator. For moving the output pointer ahead we simply increase this (with one byte) after each operation:
.. code-block:: cpp .. code-block:: cpp
for(int j = 1 ; j < myImage.rows-1; ++j) for(int j = 1; j < myImage.rows - 1; ++j)
{ {
const uchar* previous = myImage.ptr<uchar>(j - 1); const uchar* previous = myImage.ptr<uchar>(j - 1);
const uchar* current = myImage.ptr<uchar>(j ); const uchar* current = myImage.ptr<uchar>(j );
@ -85,21 +85,21 @@ We'll use the plain C [] operator to access pixels. Because we need to access mu
uchar* output = Result.ptr<uchar>(j); uchar* output = Result.ptr<uchar>(j);
for(int i= nChannels;i < nChannels*(myImage.cols-1); ++i) for(int i = nChannels; i < nChannels * (myImage.cols - 1); ++i)
{ {
*output++ = saturate_cast<uchar>(5*current[i] *output++ = saturate_cast<uchar>(5 * current[i]
-current[i-nChannels] - current[i+nChannels] - previous[i] - next[i]); -current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]);
} }
} }
On the borders of the image the upper notation results inexistent pixel locations (like minus one - minus one). In these points our formula is undefined. A simple solution is to not apply the mask in these points and, for example, set the pixels on the borders to zeros: On the borders of the image the upper notation results inexistent pixel locations (like minus one - minus one). In these points our formula is undefined. A simple solution is to not apply the kernel in these points and, for example, set the pixels on the borders to zeros:
.. code-block:: cpp .. code-block:: cpp
Result.row(0).setTo(Scalar(0)); // The top row Result.row(0).setTo(Scalar(0)); // The top row
Result.row(Result.rows-1).setTo(Scalar(0)); // The bottom row Result.row(Result.rows - 1).setTo(Scalar(0)); // The bottom row
Result.col(0).setTo(Scalar(0)); // The left column Result.col(0).setTo(Scalar(0)); // The left column
Result.col(Result.cols-1).setTo(Scalar(0)); // The right column Result.col(Result.cols - 1).setTo(Scalar(0)); // The right column
The filter2D function The filter2D function
===================== =====================
@ -116,7 +116,7 @@ Then call the :filtering:`filter2D <filter2d>` function specifying the input, th
.. code-block:: cpp .. code-block:: cpp
filter2D(I, K, I.depth(), kern ); filter2D(I, K, I.depth(), kern);
The function even has a fifth optional argument to specify the center of the kernel, and a sixth one for determining what to do in the regions where the operation is undefined (borders). Using this function has the advantage that it's shorter, less verbose and because there are some optimization techniques implemented it is usually faster than the *hand-coded method*. For example in my test while the second one took only 13 milliseconds the first took around 31 milliseconds. Quite some difference. The function even has a fifth optional argument to specify the center of the kernel, and a sixth one for determining what to do in the regions where the operation is undefined (borders). Using this function has the advantage that it's shorter, less verbose and because there are some optimization techniques implemented it is usually faster than the *hand-coded method*. For example in my test while the second one took only 13 milliseconds the first took around 31 milliseconds. Quite some difference.

View File

@ -45,7 +45,7 @@ All the above objects, in the end, point to the same single data matrix. Their h
:linenos: :linenos:
Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
Mat E = A(Range:all(), Range(1,3)); // using row and column boundaries Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries
Now you may ask if the matrix itself may belong to multiple *Mat* objects who takes responsibility for cleaning it up when it's no longer needed. The short answer is: the last object that used it. This is handled by using a reference counting mechanism. Whenever somebody copies a header of a *Mat* object, a counter is increased for the matrix. Whenever a header is cleaned this counter is decreased. When the counter reaches zero the matrix too is freed. Sometimes you will want to copy the matrix itself too, so OpenCV provides the :basicstructures:`clone() <mat-clone>` and :basicstructures:`copyTo() <mat-copyto>` functions. Now you may ask if the matrix itself may belong to multiple *Mat* objects who takes responsibility for cleaning it up when it's no longer needed. The short answer is: the last object that used it. This is handled by using a reference counting mechanism. Whenever somebody copies a header of a *Mat* object, a counter is increased for the matrix. Whenever a header is cleaned this counter is decreased. When the counter reaches zero the matrix too is freed. Sometimes you will want to copy the matrix itself too, so OpenCV provides the :basicstructures:`clone() <mat-clone>` and :basicstructures:`copyTo() <mat-copyto>` functions.
@ -86,7 +86,7 @@ Each of the building components has their own valid domains. This leads to the d
Creating a *Mat* object explicitly Creating a *Mat* object explicitly
================================== ==================================
In the :ref:`Load_Save_Image` tutorial you have already learned how to write a matrix to an image file by using the :readWriteImageVideo:` imwrite() <imwrite>` function. However, for debugging purposes it's much more convenient to see the actual values. You can do this using the << operator of *Mat*. Be aware that this only works for two dimensional matrices. In the :ref:`Load_Save_Image` tutorial you have already learned how to write a matrix to an image file by using the :readwriteimagevideo:`imwrite() <imwrite>` function. However, for debugging purposes it's much more convenient to see the actual values. You can do this using the << operator of *Mat*. Be aware that this only works for two dimensional matrices.
Although *Mat* works really well as an image container, it is also a general matrix class. Therefore, it is possible to create and manipulate multidimensional matrices. You can create a Mat object in multiple ways: Although *Mat* works really well as an image container, it is also a general matrix class. Therefore, it is possible to create and manipulate multidimensional matrices. You can create a Mat object in multiple ways:

View File

@ -84,88 +84,10 @@ Code
* **Code at glance:** * **Code at glance:**
.. code-block:: cpp .. literalinclude:: ../../../../../samples/cpp/tutorial_code/Histograms_Matching/compareHist_Demo.cpp
:language: cpp
:tab-width: 4
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
/** @function main */
int main( int argc, char** argv )
{
Mat src_base, hsv_base;
Mat src_test1, hsv_test1;
Mat src_test2, hsv_test2;
Mat hsv_half_down;
/// Load three images with different environment settings
if( argc < 4 )
{ printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n");
return -1;
}
src_base = imread( argv[1], 1 );
src_test1 = imread( argv[2], 1 );
src_test2 = imread( argv[3], 1 );
/// Convert to HSV
cvtColor( src_base, hsv_base, CV_BGR2HSV );
cvtColor( src_test1, hsv_test1, CV_BGR2HSV );
cvtColor( src_test2, hsv_test2, CV_BGR2HSV );
hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
/// Using 30 bins for hue and 32 for saturation
int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins };
// hue varies from 0 to 256, saturation from 0 to 180
float h_ranges[] = { 0, 256 };
float s_ranges[] = { 0, 180 };
const float* ranges[] = { h_ranges, s_ranges };
// Use the o-th and 1-st channels
int channels[] = { 0, 1 };
/// Histograms
MatND hist_base;
MatND hist_half_down;
MatND hist_test1;
MatND hist_test2;
/// Calculate the histograms for the HSV images
calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );
normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false );
normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false );
normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false );
normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
/// Apply the histogram comparison methods
for( int i = 0; i < 4; i++ )
{ int compare_method = i;
double base_base = compareHist( hist_base, hist_base, compare_method );
double base_half = compareHist( hist_base, hist_half_down, compare_method );
double base_test1 = compareHist( hist_base, hist_test1, compare_method );
double base_test2 = compareHist( hist_base, hist_test2, compare_method );
printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 );
}
printf( "Done \n" );
return 0;
}
Explanation Explanation
@ -211,11 +133,11 @@ Explanation
.. code-block:: cpp .. code-block:: cpp
int h_bins = 50; int s_bins = 32; int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins }; int histSize[] = { h_bins, s_bins };
float h_ranges[] = { 0, 256 }; float h_ranges[] = { 0, 180 };
float s_ranges[] = { 0, 180 }; float s_ranges[] = { 0, 256 };
const float* ranges[] = { h_ranges, s_ranges }; const float* ranges[] = { h_ranges, s_ranges };

View File

@ -5,7 +5,7 @@ Load, Modify, and Save an Image
.. note:: .. note::
We assume that by now you know how to load an image using :imread:`imread <>` and to display it in a window (using :imshow:`imshow <>`). Read the :ref:`Display_Image` tutorial otherwise. We assume that by now you know how to load an image using :readwriteimagevideo:`imread <imread>` and to display it in a window (using :user_interface:`imshow <imshow>`). Read the :ref:`Display_Image` tutorial otherwise.
Goals Goals
====== ======
@ -14,9 +14,9 @@ In this tutorial you will learn how to:
.. container:: enumeratevisibleitemswithsquare .. container:: enumeratevisibleitemswithsquare
* Load an image using :imread:`imread <>` * Load an image using :readwriteimagevideo:`imread <imread>`
* Transform an image from BGR to Grayscale format by using :cvt_color:`cvtColor <>` * Transform an image from BGR to Grayscale format by using :miscellaneous_transformations:`cvtColor <cvtcolor>`
* Save your transformed image in a file on disk (using :imwrite:`imwrite <>`) * Save your transformed image in a file on disk (using :readwriteimagevideo:`imwrite <imwrite>`)
Code Code
====== ======
@ -62,10 +62,7 @@ Here it is:
Explanation Explanation
============ ============
#. We begin by: #. We begin by loading an image using :readwriteimagevideo:`imread <imread>`, located in the path given by *imageName*. For this example, assume you are loading a RGB image.
* Creating a Mat object to store the image information
* Load an image using :imread:`imread <>`, located in the path given by *imageName*. Fort this example, assume you are loading a RGB image.
#. Now we are going to convert our image from BGR to Grayscale format. OpenCV has a really nice function to do this kind of transformations: #. Now we are going to convert our image from BGR to Grayscale format. OpenCV has a really nice function to do this kind of transformations:
@ -73,15 +70,15 @@ Explanation
cvtColor( image, gray_image, CV_BGR2GRAY ); cvtColor( image, gray_image, CV_BGR2GRAY );
As you can see, :cvt_color:`cvtColor <>` takes as arguments: As you can see, :miscellaneous_transformations:`cvtColor <cvtcolor>` takes as arguments:
.. container:: enumeratevisibleitemswithsquare .. container:: enumeratevisibleitemswithsquare
* a source image (*image*) * a source image (*image*)
* a destination image (*gray_image*), in which we will save the converted image. * a destination image (*gray_image*), in which we will save the converted image.
* an additional parameter that indicates what kind of transformation will be performed. In this case we use **CV_BGR2GRAY** (because of :imread:`imread <>` has BGR default channel order in case of color images). * an additional parameter that indicates what kind of transformation will be performed. In this case we use **CV_BGR2GRAY** (because of :readwriteimagevideo:`imread <imread>` has BGR default channel order in case of color images).
#. So now we have our new *gray_image* and want to save it on disk (otherwise it will get lost after the program ends). To save it, we will use a function analagous to :imread:`imread <>`: :imwrite:`imwrite <>` #. So now we have our new *gray_image* and want to save it on disk (otherwise it will get lost after the program ends). To save it, we will use a function analagous to :readwriteimagevideo:`imread <imread>`: :readwriteimagevideo:`imwrite <imwrite>`
.. code-block:: cpp .. code-block:: cpp

View File

@ -58,7 +58,7 @@ SET_TARGET_PROPERTIES(${the_target} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
) )
if (NOT (CMAKE_BUILD_TYPE MATCHES "debug")) if (NOT (CMAKE_BUILD_TYPE MATCHES "Debug"))
ADD_CUSTOM_COMMAND( TARGET ${the_target} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${LIBRARY_OUTPUT_PATH}/lib${the_target}.so" ) ADD_CUSTOM_COMMAND( TARGET ${the_target} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${LIBRARY_OUTPUT_PATH}/lib${the_target}.so" )
endif() endif()

View File

@ -61,6 +61,12 @@
using namespace android; using namespace android;
// non-public camera related classes are not binary compatible
// objects of these classes have different sizeof on different platforms
// additional memory tail to all system objects to overcome sizeof issue
#define MAGIC_TAIL 4096
void debugShowFPS(); void debugShowFPS();
#if defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0) #if defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
@ -90,6 +96,7 @@ public:
}; };
#endif #endif
std::string getProcessName() std::string getProcessName()
{ {
std::string result; std::string result;
@ -142,12 +149,22 @@ class CameraHandler: public CameraListener
protected: protected:
int cameraId; int cameraId;
sp<Camera> camera; sp<Camera> camera;
CameraParameters params; #if defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
sp<SurfaceTexture> surface;
#endif
#if defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0) || defined(ANDROID_r4_4_0)
sp<BufferQueue> queue;
sp<ConsumerListenerStub> listener;
#endif
CameraParameters* params;
CameraCallback cameraCallback; CameraCallback cameraCallback;
void* userData; void* userData;
int emptyCameraCallbackReported; int emptyCameraCallbackReported;
int width;
int height;
static const char* flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM]; static const char* flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM];
static const char* focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM]; static const char* focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM];
static const char* whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM]; static const char* whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM];
@ -258,7 +275,7 @@ protected:
int is_supported(const char* supp_modes_key, const char* mode) int is_supported(const char* supp_modes_key, const char* mode)
{ {
const char* supported_modes = params.get(supp_modes_key); const char* supported_modes = params->get(supp_modes_key);
return (supported_modes && mode && (strstr(supported_modes, mode) > 0)); return (supported_modes && mode && (strstr(supported_modes, mode) > 0));
} }
@ -268,7 +285,7 @@ protected:
if (focus_distance_type >= 0 && focus_distance_type < 3) if (focus_distance_type >= 0 && focus_distance_type < 3)
{ {
float focus_distances[3]; float focus_distances[3];
const char* output = params.get(CameraParameters::KEY_FOCUS_DISTANCES); const char* output = params->get(CameraParameters::KEY_FOCUS_DISTANCES);
int val_num = CameraHandler::split_float(output, focus_distances, ',', 3); int val_num = CameraHandler::split_float(output, focus_distances, ',', 3);
if(val_num == 3) if(val_num == 3)
{ {
@ -300,10 +317,15 @@ public:
emptyCameraCallbackReported(0) emptyCameraCallbackReported(0)
{ {
LOGD("Instantiated new CameraHandler (%p, %p)", callback, _userData); LOGD("Instantiated new CameraHandler (%p, %p)", callback, _userData);
void* params_buffer = operator new(sizeof(CameraParameters) + MAGIC_TAIL);
params = new(params_buffer) CameraParameters();
} }
virtual ~CameraHandler() virtual ~CameraHandler()
{ {
if (params)
params->~CameraParameters();
operator delete(params);
LOGD("CameraHandler destructor is called"); LOGD("CameraHandler destructor is called");
} }
@ -371,10 +393,18 @@ const char* CameraHandler::focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM] =
CameraParameters::FOCUS_MODE_AUTO, CameraParameters::FOCUS_MODE_AUTO,
#if !defined(ANDROID_r2_2_0) #if !defined(ANDROID_r2_2_0)
CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO,
#else
CameraParameters::FOCUS_MODE_AUTO,
#endif #endif
CameraParameters::FOCUS_MODE_EDOF, CameraParameters::FOCUS_MODE_EDOF,
CameraParameters::FOCUS_MODE_FIXED, CameraParameters::FOCUS_MODE_FIXED,
CameraParameters::FOCUS_MODE_INFINITY CameraParameters::FOCUS_MODE_INFINITY,
CameraParameters::FOCUS_MODE_MACRO,
#if !defined(ANDROID_r2_2_0) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1)
CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE
#else
CameraParameters::FOCUS_MODE_AUTO
#endif
}; };
const char* CameraHandler::whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM] = const char* CameraHandler::whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM] =
@ -534,39 +564,39 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
{ {
LOGI("initCameraConnect: Setting paramers from previous camera handler"); LOGI("initCameraConnect: Setting paramers from previous camera handler");
camera->setParameters(prevCameraParameters->flatten()); camera->setParameters(prevCameraParameters->flatten());
handler->params.unflatten(prevCameraParameters->flatten()); handler->params->unflatten(prevCameraParameters->flatten());
} }
else else
{ {
android::String8 params_str = camera->getParameters(); android::String8 params_str = camera->getParameters();
LOGI("initCameraConnect: [%s]", params_str.string()); LOGI("initCameraConnect: [%s]", params_str.string());
handler->params.unflatten(params_str); handler->params->unflatten(params_str);
LOGD("Supported Cameras: %s", handler->params.get("camera-indexes")); LOGD("Supported Cameras: %s", handler->params->get("camera-indexes"));
LOGD("Supported Picture Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES)); LOGD("Supported Picture Sizes: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES));
LOGD("Supported Picture Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS)); LOGD("Supported Picture Formats: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
LOGD("Supported Preview Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES)); LOGD("Supported Preview Sizes: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES));
LOGD("Supported Preview Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS)); LOGD("Supported Preview Formats: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS));
LOGD("Supported Preview Frame Rates: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES)); LOGD("Supported Preview Frame Rates: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
LOGD("Supported Thumbnail Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES)); LOGD("Supported Thumbnail Sizes: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES));
LOGD("Supported Whitebalance Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE)); LOGD("Supported Whitebalance Modes: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE));
LOGD("Supported Effects: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_EFFECTS)); LOGD("Supported Effects: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_EFFECTS));
LOGD("Supported Scene Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES)); LOGD("Supported Scene Modes: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_SCENE_MODES));
LOGD("Supported Focus Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES)); LOGD("Supported Focus Modes: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
LOGD("Supported Antibanding Options: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING)); LOGD("Supported Antibanding Options: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_ANTIBANDING));
LOGD("Supported Flash Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES)); LOGD("Supported Flash Modes: %s", handler->params->get(CameraParameters::KEY_SUPPORTED_FLASH_MODES));
#if !defined(ANDROID_r2_2_0) #if !defined(ANDROID_r2_2_0)
// Set focus mode to continuous-video if supported // Set focus mode to continuous-video if supported
const char* available_focus_modes = handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES); const char* available_focus_modes = handler->params->get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
if (available_focus_modes != 0) if (available_focus_modes != 0)
{ {
if (strstr(available_focus_modes, "continuous-video") != NULL) if (strstr(available_focus_modes, "continuous-video") != NULL)
{ {
handler->params.set(CameraParameters::KEY_FOCUS_MODE, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO); handler->params->set(CameraParameters::KEY_FOCUS_MODE, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO);
status_t resParams = handler->camera->setParameters(handler->params.flatten()); status_t resParams = handler->camera->setParameters(handler->params->flatten());
if (resParams != 0) if (resParams != 0)
{ {
@ -581,7 +611,7 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
#endif #endif
//check if yuv420sp format available. Set this format as preview format. //check if yuv420sp format available. Set this format as preview format.
const char* available_formats = handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS); const char* available_formats = handler->params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
if (available_formats != 0) if (available_formats != 0)
{ {
const char* format_to_set = 0; const char* format_to_set = 0;
@ -607,9 +637,9 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
if (0 != format_to_set) if (0 != format_to_set)
{ {
handler->params.setPreviewFormat(format_to_set); handler->params->setPreviewFormat(format_to_set);
status_t resParams = handler->camera->setParameters(handler->params.flatten()); status_t resParams = handler->camera->setParameters(handler->params->flatten());
if (resParams != 0) if (resParams != 0)
LOGE("initCameraConnect: failed to set preview format to %s", format_to_set); LOGE("initCameraConnect: failed to set preview format to %s", format_to_set);
@ -617,6 +647,13 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
LOGD("initCameraConnect: preview format is set to %s", format_to_set); LOGD("initCameraConnect: preview format is set to %s", format_to_set);
} }
} }
handler->params->setPreviewSize(640, 480);
status_t resParams = handler->camera->setParameters(handler->params->flatten());
if (resParams != 0)
LOGE("initCameraConnect: failed to set preview resolution to 640x480");
else
LOGD("initCameraConnect: preview format is set to 640x480");
} }
status_t bufferStatus; status_t bufferStatus;
@ -627,22 +664,27 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback,
#elif defined(ANDROID_r2_3_3) #elif defined(ANDROID_r2_3_3)
/* Do nothing in case of 2.3 for now */ /* Do nothing in case of 2.3 for now */
#elif defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) #elif defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
sp<SurfaceTexture> surfaceTexture = new SurfaceTexture(MAGIC_OPENCV_TEXTURE_ID); void* surface_texture_obj = operator new(sizeof(SurfaceTexture) + MAGIC_TAIL);
bufferStatus = camera->setPreviewTexture(surfaceTexture); handler->surface = new(surface_texture_obj) SurfaceTexture(MAGIC_OPENCV_TEXTURE_ID);
bufferStatus = camera->setPreviewTexture(handler->surface);
if (bufferStatus != 0) if (bufferStatus != 0)
LOGE("initCameraConnect: failed setPreviewTexture call (status %d); camera might not work correctly", bufferStatus); LOGE("initCameraConnect: failed setPreviewTexture call (status %d); camera might not work correctly", bufferStatus);
#elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0) #elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
sp<BufferQueue> bufferQueue = new BufferQueue(); void* buffer_queue_obj = operator new(sizeof(BufferQueue) + MAGIC_TAIL);
sp<BufferQueue::ConsumerListener> queueListener = new ConsumerListenerStub(); handler->queue = new(buffer_queue_obj) BufferQueue();
bufferQueue->consumerConnect(queueListener); void* consumer_listener_obj = operator new(sizeof(ConsumerListenerStub) + MAGIC_TAIL);
bufferStatus = camera->setPreviewTexture(bufferQueue); handler->listener = new(consumer_listener_obj) ConsumerListenerStub();
handler->queue->consumerConnect(handler->listener);
bufferStatus = camera->setPreviewTexture(handler->queue);
if (bufferStatus != 0) if (bufferStatus != 0)
LOGE("initCameraConnect: failed setPreviewTexture call; camera might not work correctly"); LOGE("initCameraConnect: failed setPreviewTexture call; camera might not work correctly");
# elif defined(ANDROID_r4_4_0) # elif defined(ANDROID_r4_4_0)
sp<BufferQueue> bufferQueue = new BufferQueue(); void* buffer_queue_obj = operator new(sizeof(BufferQueue) + MAGIC_TAIL);
sp<IConsumerListener> queueListener = new ConsumerListenerStub(); handler->queue = new(buffer_queue_obj) BufferQueue();
bufferQueue->consumerConnect(queueListener, true); void* consumer_listener_obj = operator new(sizeof(ConsumerListenerStub) + MAGIC_TAIL);
bufferStatus = handler->camera->setPreviewTarget(bufferQueue); handler->listener = new(consumer_listener_obj) ConsumerListenerStub();
handler->queue->consumerConnect(handler->listener, true);
bufferStatus = handler->camera->setPreviewTarget(handler->queue);
if (bufferStatus != 0) if (bufferStatus != 0)
LOGE("applyProperties: failed setPreviewTexture call; camera might not work correctly"); LOGE("applyProperties: failed setPreviewTexture call; camera might not work correctly");
# endif # endif
@ -723,18 +765,18 @@ double CameraHandler::getProperty(int propIdx)
case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH: case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
{ {
int w,h; int w,h;
params.getPreviewSize(&w, &h); params->getPreviewSize(&w, &h);
return w; return w;
} }
case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT: case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
{ {
int w,h; int w,h;
params.getPreviewSize(&w, &h); params->getPreviewSize(&w, &h);
return h; return h;
} }
case ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING: case ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING:
{ {
cameraPropertySupportedPreviewSizesString = params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES); cameraPropertySupportedPreviewSizesString = params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
union {const char* str;double res;} u; union {const char* str;double res;} u;
memset(&u.res, 0, sizeof(u.res)); memset(&u.res, 0, sizeof(u.res));
u.str = cameraPropertySupportedPreviewSizesString.c_str(); u.str = cameraPropertySupportedPreviewSizesString.c_str();
@ -742,7 +784,7 @@ double CameraHandler::getProperty(int propIdx)
} }
case ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING: case ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING:
{ {
const char* fmt = params.get(CameraParameters::KEY_PREVIEW_FORMAT); const char* fmt = params->get(CameraParameters::KEY_PREVIEW_FORMAT);
if (fmt == CameraParameters::PIXEL_FORMAT_YUV422SP) if (fmt == CameraParameters::PIXEL_FORMAT_YUV422SP)
fmt = "yuv422sp"; fmt = "yuv422sp";
else if (fmt == CameraParameters::PIXEL_FORMAT_YUV420SP) else if (fmt == CameraParameters::PIXEL_FORMAT_YUV420SP)
@ -762,44 +804,44 @@ double CameraHandler::getProperty(int propIdx)
} }
case ANDROID_CAMERA_PROPERTY_EXPOSURE: case ANDROID_CAMERA_PROPERTY_EXPOSURE:
{ {
int exposure = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); int exposure = params->getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
return exposure; return exposure;
} }
case ANDROID_CAMERA_PROPERTY_FPS: case ANDROID_CAMERA_PROPERTY_FPS:
{ {
return params.getPreviewFrameRate(); return params->getPreviewFrameRate();
} }
case ANDROID_CAMERA_PROPERTY_FLASH_MODE: case ANDROID_CAMERA_PROPERTY_FLASH_MODE:
{ {
int flash_mode = getModeNum(CameraHandler::flashModesNames, int flash_mode = getModeNum(CameraHandler::flashModesNames,
ANDROID_CAMERA_FLASH_MODES_NUM, ANDROID_CAMERA_FLASH_MODES_NUM,
params.get(CameraParameters::KEY_FLASH_MODE)); params->get(CameraParameters::KEY_FLASH_MODE));
return flash_mode; return flash_mode;
} }
case ANDROID_CAMERA_PROPERTY_FOCUS_MODE: case ANDROID_CAMERA_PROPERTY_FOCUS_MODE:
{ {
int focus_mode = getModeNum(CameraHandler::focusModesNames, int focus_mode = getModeNum(CameraHandler::focusModesNames,
ANDROID_CAMERA_FOCUS_MODES_NUM, ANDROID_CAMERA_FOCUS_MODES_NUM,
params.get(CameraParameters::KEY_FOCUS_MODE)); params->get(CameraParameters::KEY_FOCUS_MODE));
return focus_mode; return focus_mode;
} }
case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE: case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE:
{ {
int white_balance = getModeNum(CameraHandler::whiteBalanceModesNames, int white_balance = getModeNum(CameraHandler::whiteBalanceModesNames,
ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM, ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM,
params.get(CameraParameters::KEY_WHITE_BALANCE)); params->get(CameraParameters::KEY_WHITE_BALANCE));
return white_balance; return white_balance;
} }
case ANDROID_CAMERA_PROPERTY_ANTIBANDING: case ANDROID_CAMERA_PROPERTY_ANTIBANDING:
{ {
int antibanding = getModeNum(CameraHandler::antibandingModesNames, int antibanding = getModeNum(CameraHandler::antibandingModesNames,
ANDROID_CAMERA_ANTIBANDING_MODES_NUM, ANDROID_CAMERA_ANTIBANDING_MODES_NUM,
params.get(CameraParameters::KEY_ANTIBANDING)); params->get(CameraParameters::KEY_ANTIBANDING));
return antibanding; return antibanding;
} }
case ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH: case ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH:
{ {
float focal_length = params.getFloat(CameraParameters::KEY_FOCAL_LENGTH); float focal_length = params->getFloat(CameraParameters::KEY_FOCAL_LENGTH);
return focal_length; return focal_length;
} }
case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR: case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR:
@ -814,6 +856,24 @@ double CameraHandler::getProperty(int propIdx)
{ {
return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_FAR_INDEX); return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_FAR_INDEX);
} }
#if !defined(ANDROID_r2_2_0) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1)
case ANDROID_CAMERA_PROPERTY_WHITEBALANCE_LOCK:
{
const char* status = params->get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK);
if (status == CameraParameters::TRUE)
return 1.;
else
return 0.;
}
case ANDROID_CAMERA_PROPERTY_EXPOSE_LOCK:
{
const char* status = params->get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK);
if (status == CameraParameters::TRUE)
return 1.;
else
return 0.;
}
#endif
default: default:
LOGW("CameraHandler::getProperty - Unsupported property."); LOGW("CameraHandler::getProperty - Unsupported property.");
}; };
@ -824,99 +884,151 @@ void CameraHandler::setProperty(int propIdx, double value)
{ {
LOGD("CameraHandler::setProperty(%d, %f)", propIdx, value); LOGD("CameraHandler::setProperty(%d, %f)", propIdx, value);
android::String8 params_str;
params_str = camera->getParameters();
LOGI("Params before set: [%s]", params_str.string());
switch (propIdx) switch (propIdx)
{ {
case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH: case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
{ {
int w,h; int w,h;
params.getPreviewSize(&w, &h); params->getPreviewSize(&w, &h);
w = (int)value; width = (int)value;
params.setPreviewSize(w, h);
} }
break; break;
case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT: case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
{ {
int w,h; int w,h;
params.getPreviewSize(&w, &h); params->getPreviewSize(&w, &h);
h = (int)value; height = (int)value;
params.setPreviewSize(w, h);
} }
break; break;
case ANDROID_CAMERA_PROPERTY_EXPOSURE: case ANDROID_CAMERA_PROPERTY_EXPOSURE:
{ {
int max_exposure = params.getInt("max-exposure-compensation"); int max_exposure = params->getInt("max-exposure-compensation");
int min_exposure = params.getInt("min-exposure-compensation"); int min_exposure = params->getInt("min-exposure-compensation");
if(max_exposure && min_exposure){ if(max_exposure && min_exposure)
{
int exposure = (int)value; int exposure = (int)value;
if(exposure >= min_exposure && exposure <= max_exposure){ if(exposure >= min_exposure && exposure <= max_exposure)
params.set("exposure-compensation", exposure); params->set("exposure-compensation", exposure);
} else { else
LOGE("Exposure compensation not in valid range (%i,%i).", min_exposure, max_exposure); LOGE("Exposure compensation not in valid range (%i,%i).", min_exposure, max_exposure);
} } else
} else {
LOGE("Exposure compensation adjust is not supported."); LOGE("Exposure compensation adjust is not supported.");
}
camera->setParameters(params->flatten());
} }
break; break;
case ANDROID_CAMERA_PROPERTY_FLASH_MODE: case ANDROID_CAMERA_PROPERTY_FLASH_MODE:
{ {
int new_val = (int)value; int new_val = (int)value;
if(new_val >= 0 && new_val < ANDROID_CAMERA_FLASH_MODES_NUM){ if(new_val >= 0 && new_val < ANDROID_CAMERA_FLASH_MODES_NUM)
{
const char* mode_name = flashModesNames[new_val]; const char* mode_name = flashModesNames[new_val];
if(is_supported(CameraParameters::KEY_SUPPORTED_FLASH_MODES, mode_name)) if(is_supported(CameraParameters::KEY_SUPPORTED_FLASH_MODES, mode_name))
params.set(CameraParameters::KEY_FLASH_MODE, mode_name); params->set(CameraParameters::KEY_FLASH_MODE, mode_name);
else else
LOGE("Flash mode %s is not supported.", mode_name); LOGE("Flash mode %s is not supported.", mode_name);
} else {
LOGE("Flash mode value not in valid range.");
} }
else
LOGE("Flash mode value not in valid range.");
camera->setParameters(params->flatten());
} }
break; break;
case ANDROID_CAMERA_PROPERTY_FOCUS_MODE: case ANDROID_CAMERA_PROPERTY_FOCUS_MODE:
{ {
int new_val = (int)value; int new_val = (int)value;
if(new_val >= 0 && new_val < ANDROID_CAMERA_FOCUS_MODES_NUM){ if(new_val >= 0 && new_val < ANDROID_CAMERA_FOCUS_MODES_NUM)
{
const char* mode_name = focusModesNames[new_val]; const char* mode_name = focusModesNames[new_val];
if(is_supported(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mode_name)) if(is_supported(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mode_name))
params.set(CameraParameters::KEY_FOCUS_MODE, mode_name); params->set(CameraParameters::KEY_FOCUS_MODE, mode_name);
else else
LOGE("Focus mode %s is not supported.", mode_name); LOGE("Focus mode %s is not supported.", mode_name);
} else {
LOGE("Focus mode value not in valid range.");
} }
else
LOGE("Focus mode value not in valid range.");
camera->setParameters(params->flatten());
} }
break; break;
case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE: case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE:
{ {
int new_val = (int)value; int new_val = (int)value;
if(new_val >= 0 && new_val < ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM){ if(new_val >= 0 && new_val < ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM)
{
const char* mode_name = whiteBalanceModesNames[new_val]; const char* mode_name = whiteBalanceModesNames[new_val];
if(is_supported(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mode_name)) if(is_supported(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mode_name))
params.set(CameraParameters::KEY_WHITE_BALANCE, mode_name); params->set(CameraParameters::KEY_WHITE_BALANCE, mode_name);
else else
LOGE("White balance mode %s is not supported.", mode_name); LOGE("White balance mode %s is not supported.", mode_name);
} else {
LOGE("White balance mode value not in valid range.");
} }
else
LOGE("White balance mode value not in valid range.");
camera->setParameters(params->flatten());
} }
break; break;
case ANDROID_CAMERA_PROPERTY_ANTIBANDING: case ANDROID_CAMERA_PROPERTY_ANTIBANDING:
{ {
int new_val = (int)value; int new_val = (int)value;
if(new_val >= 0 && new_val < ANDROID_CAMERA_ANTIBANDING_MODES_NUM){ if(new_val >= 0 && new_val < ANDROID_CAMERA_ANTIBANDING_MODES_NUM)
{
const char* mode_name = antibandingModesNames[new_val]; const char* mode_name = antibandingModesNames[new_val];
if(is_supported(CameraParameters::KEY_SUPPORTED_ANTIBANDING, mode_name)) if(is_supported(CameraParameters::KEY_SUPPORTED_ANTIBANDING, mode_name))
params.set(CameraParameters::KEY_ANTIBANDING, mode_name); params->set(CameraParameters::KEY_ANTIBANDING, mode_name);
else else
LOGE("Antibanding mode %s is not supported.", mode_name); LOGE("Antibanding mode %s is not supported.", mode_name);
} else {
LOGE("Antibanding mode value not in valid range.");
} }
else
LOGE("Antibanding mode value not in valid range.");
camera->setParameters(params->flatten());
} }
break; break;
#if !defined(ANDROID_r2_2_0) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1)
case ANDROID_CAMERA_PROPERTY_EXPOSE_LOCK:
{
if (is_supported(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, "true"))
{
if (value != 0)
params->set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, CameraParameters::TRUE);
else
params->set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK, CameraParameters::FALSE);
LOGE("Expose lock is set");
}
else
LOGE("Expose lock is not supported");
camera->setParameters(params->flatten());
}
break;
case ANDROID_CAMERA_PROPERTY_WHITEBALANCE_LOCK:
{
if (is_supported(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, "true"))
{
if (value != 0)
params->set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, CameraParameters::TRUE);
else
params->set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, CameraParameters::FALSE);
LOGE("White balance lock is set");
}
else
LOGE("White balance lock is not supported");
camera->setParameters(params->flatten());
}
break;
#endif
default: default:
LOGW("CameraHandler::setProperty - Unsupported property."); LOGW("CameraHandler::setProperty - Unsupported property.");
}; };
params_str = camera->getParameters();
LOGI("Params after set: [%s]", params_str.string());
} }
void CameraHandler::applyProperties(CameraHandler** ppcameraHandler) void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
@ -935,7 +1047,10 @@ void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
return; return;
} }
CameraParameters curCameraParameters((*ppcameraHandler)->params.flatten()); // delayed resolution setup to exclude errors during other parameres setup on the fly
// without camera restart
if (((*ppcameraHandler)->width != 0) && ((*ppcameraHandler)->height != 0))
(*ppcameraHandler)->params->setPreviewSize((*ppcameraHandler)->width, (*ppcameraHandler)->height);
#if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) \ #if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) \
|| defined(ANDROID_r4_3_0) || defined(ANDROID_r4_4_0) || defined(ANDROID_r4_3_0) || defined(ANDROID_r4_4_0)
@ -951,27 +1066,27 @@ void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
return; return;
} }
handler->camera->setParameters(curCameraParameters.flatten()); handler->camera->setParameters((*ppcameraHandler)->params->flatten());
handler->params.unflatten(curCameraParameters.flatten());
status_t bufferStatus; status_t bufferStatus;
# if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) # if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
sp<SurfaceTexture> surfaceTexture = new SurfaceTexture(MAGIC_OPENCV_TEXTURE_ID); void* surface_texture_obj = operator new(sizeof(SurfaceTexture) + MAGIC_TAIL);
bufferStatus = handler->camera->setPreviewTexture(surfaceTexture); handler->surface = new(surface_texture_obj) SurfaceTexture(MAGIC_OPENCV_TEXTURE_ID);
bufferStatus = handler->camera->setPreviewTexture(handler->surface);
if (bufferStatus != 0) if (bufferStatus != 0)
LOGE("applyProperties: failed setPreviewTexture call (status %d); camera might not work correctly", bufferStatus); LOGE("applyProperties: failed setPreviewTexture call (status %d); camera might not work correctly", bufferStatus);
# elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0) # elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
sp<BufferQueue> bufferQueue = new BufferQueue(); void* buffer_queue_obj = operator new(sizeof(BufferQueue) + MAGIC_TAIL);
sp<BufferQueue::ConsumerListener> queueListener = new ConsumerListenerStub(); handler->queue = new(buffer_queue_obj) BufferQueue();
bufferQueue->consumerConnect(queueListener); handler->queue->consumerConnect(handler->listener);
bufferStatus = handler->camera->setPreviewTexture(bufferQueue); bufferStatus = handler->camera->setPreviewTexture(handler->queue);
if (bufferStatus != 0) if (bufferStatus != 0)
LOGE("applyProperties: failed setPreviewTexture call; camera might not work correctly"); LOGE("applyProperties: failed setPreviewTexture call; camera might not work correctly");
# elif defined(ANDROID_r4_4_0) # elif defined(ANDROID_r4_4_0)
sp<BufferQueue> bufferQueue = new BufferQueue(); void* buffer_queue_obj = operator new(sizeof(BufferQueue) + MAGIC_TAIL);
sp<IConsumerListener> queueListener = new ConsumerListenerStub(); handler->queue = new(buffer_queue_obj) BufferQueue();
bufferQueue->consumerConnect(queueListener, true); handler->queue->consumerConnect(handler->listener, true);
bufferStatus = handler->camera->setPreviewTarget(bufferQueue); bufferStatus = handler->camera->setPreviewTarget(handler->queue);
if (bufferStatus != 0) if (bufferStatus != 0)
LOGE("applyProperties: failed setPreviewTexture call; camera might not work correctly"); LOGE("applyProperties: failed setPreviewTexture call; camera might not work correctly");
# endif # endif
@ -1002,7 +1117,7 @@ void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
LOGD("CameraHandler::applyProperties(): after previousCameraHandler->closeCameraConnect"); LOGD("CameraHandler::applyProperties(): after previousCameraHandler->closeCameraConnect");
LOGD("CameraHandler::applyProperties(): before initCameraConnect"); LOGD("CameraHandler::applyProperties(): before initCameraConnect");
CameraHandler* handler=initCameraConnect(cameraCallback, cameraId, userData, &curCameraParameters); CameraHandler* handler=initCameraConnect(cameraCallback, cameraId, userData, (*ppcameraHandler)->params);
LOGD("CameraHandler::applyProperties(): after initCameraConnect, handler=0x%x", (int)handler); LOGD("CameraHandler::applyProperties(): after initCameraConnect, handler=0x%x", (int)handler);
if (handler == NULL) { if (handler == NULL) {
LOGE("ERROR in applyProperties --- cannot reinit camera"); LOGE("ERROR in applyProperties --- cannot reinit camera");

View File

@ -15,7 +15,9 @@ enum {
ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH = 105, ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH = 105,
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR = 106, ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR = 106,
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL = 107, ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL = 107,
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR = 108 ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR = 108,
ANDROID_CAMERA_PROPERTY_EXPOSE_LOCK = 109,
ANDROID_CAMERA_PROPERTY_WHITEBALANCE_LOCK = 110
}; };
@ -30,12 +32,12 @@ enum {
enum { enum {
ANDROID_CAMERA_FOCUS_MODE_AUTO = 0, ANDROID_CAMERA_FOCUS_MODE_AUTO = 0,
ANDROID_CAMERA_FOCUS_MODE_CONTINUOUS_PICTURE,
ANDROID_CAMERA_FOCUS_MODE_CONTINUOUS_VIDEO, ANDROID_CAMERA_FOCUS_MODE_CONTINUOUS_VIDEO,
ANDROID_CAMERA_FOCUS_MODE_EDOF, ANDROID_CAMERA_FOCUS_MODE_EDOF,
ANDROID_CAMERA_FOCUS_MODE_FIXED, ANDROID_CAMERA_FOCUS_MODE_FIXED,
ANDROID_CAMERA_FOCUS_MODE_INFINITY, ANDROID_CAMERA_FOCUS_MODE_INFINITY,
ANDROID_CAMERA_FOCUS_MODE_MACRO, ANDROID_CAMERA_FOCUS_MODE_MACRO,
ANDROID_CAMERA_FOCUS_MODE_CONTINUOUS_PICTURE,
ANDROID_CAMERA_FOCUS_MODES_NUM ANDROID_CAMERA_FOCUS_MODES_NUM
}; };

View File

@ -147,6 +147,8 @@ __kernel void stereoBM(__global const uchar * leftptr, __global const uchar * ri
__local int best_disp[2]; __local int best_disp[2];
__local int best_cost[2]; __local int best_cost[2];
best_cost[nthread] = MAX_VAL; best_cost[nthread] = MAX_VAL;
best_disp[nthread] = MAX_VAL;
barrier(CLK_LOCAL_MEM_FENCE);
short costbuf[wsz]; short costbuf[wsz];
int head = 0; int head = 0;
@ -159,7 +161,7 @@ __kernel void stereoBM(__global const uchar * leftptr, __global const uchar * ri
int costIdx = calcLocalIdx(lx, ly, d, sizeY); int costIdx = calcLocalIdx(lx, ly, d, sizeY);
cost = costFunc + costIdx; cost = costFunc + costIdx;
short tempcost = 0; int tempcost = 0;
if(x < cols-wsz2-mindisp && y < rows-wsz2) if(x < cols-wsz2-mindisp && y < rows-wsz2)
{ {
int shift = 1*nthread + cols*(1-nthread); int shift = 1*nthread + cols*(1-nthread);
@ -191,7 +193,7 @@ __kernel void stereoBM(__global const uchar * leftptr, __global const uchar * ri
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
if(best_cost[1] == tempcost) if(best_cost[1] == tempcost)
best_disp[1] = ndisp - d - 1; atomic_min(best_disp + 1, ndisp - d - 1);
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
int dispIdx = mad24(gy, disp_step, disp_offset + gx*(int)sizeof(short)); int dispIdx = mad24(gy, disp_step, disp_offset + gx*(int)sizeof(short));
@ -209,6 +211,7 @@ __kernel void stereoBM(__global const uchar * leftptr, __global const uchar * ri
y = (ly < sizeY) ? gy + shiftY + ly : rows; y = (ly < sizeY) ? gy + shiftY + ly : rows;
best_cost[nthread] = MAX_VAL; best_cost[nthread] = MAX_VAL;
best_disp[nthread] = MAX_VAL;
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
costIdx = calcLocalIdx(lx, ly, d, sizeY); costIdx = calcLocalIdx(lx, ly, d, sizeY);
@ -227,12 +230,11 @@ __kernel void stereoBM(__global const uchar * leftptr, __global const uchar * ri
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
if(best_cost[nthread] == tempcost) if(best_cost[nthread] == tempcost)
best_disp[nthread] = ndisp - d - 1; atomic_min(best_disp + nthread, ndisp - d - 1);
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
int dispIdx = mad24(gy+ly, disp_step, disp_offset + (gx+lx)*(int)sizeof(short)); int dispIdx = mad24(gy+ly, disp_step, disp_offset + (gx+lx)*(int)sizeof(short));
disp = (__global short *)(dispptr + dispIdx); disp = (__global short *)(dispptr + dispIdx);
calcDisp(cost, disp, uniquenessRatio, mindisp, ndisp, 2*sizeY, calcDisp(cost, disp, uniquenessRatio, mindisp, ndisp, 2*sizeY,
best_disp + nthread, best_cost + nthread, d, x, y, cols, rows, wsz2); best_disp + nthread, best_cost + nthread, d, x, y, cols, rows, wsz2);
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);

View File

@ -1387,7 +1387,7 @@ description rewritten using
IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3);
IplImage gray_img_hdr, *gray_img; IplImage gray_img_hdr, *gray_img;
gray_img = (IplImage*)cvReshapeND(color_img, &gray_img_hdr, 1, 0, 0); gray_img = (IplImage*)cvReshapeMatND(color_img, sizeof(gray_img_hdr), &gray_img_hdr, 1, 0, 0);
... ...
@ -1395,6 +1395,18 @@ description rewritten using
int size[] = { 2, 2, 2 }; int size[] = { 2, 2, 2 };
CvMatND* mat = cvCreateMatND(3, size, CV_32F); CvMatND* mat = cvCreateMatND(3, size, CV_32F);
CvMat row_header, *row; CvMat row_header, *row;
row = (CvMat*)cvReshapeMatND(mat, sizeof(row_header), &row_header, 0, 1, 0);
..
In C, the header file for this function includes a convenient macro ``cvReshapeND`` that does away with the ``sizeof_header`` parameter. So, the lines containing the call to ``cvReshapeMatND`` in the examples may be replaced as follow:
::
gray_img = (IplImage*)cvReshapeND(color_img, &gray_img_hdr, 1, 0, 0);
...
row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0); row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0);
.. ..

View File

@ -118,6 +118,8 @@ public:
virtual int kind() const; virtual int kind() const;
virtual int dims(int i=-1) const; virtual int dims(int i=-1) const;
virtual int cols(int i=-1) const;
virtual int rows(int i=-1) const;
virtual Size size(int i=-1) const; virtual Size size(int i=-1) const;
virtual int sizend(int* sz, int i=-1) const; virtual int sizend(int* sz, int i=-1) const;
virtual bool sameSize(const _InputArray& arr) const; virtual bool sameSize(const _InputArray& arr) const;

View File

@ -592,7 +592,7 @@ protected:
CV_EXPORTS const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf); CV_EXPORTS const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf);
CV_EXPORTS const char* typeToStr(int t); CV_EXPORTS const char* typeToStr(int t);
CV_EXPORTS const char* memopTypeToStr(int t); CV_EXPORTS const char* memopTypeToStr(int t);
CV_EXPORTS String kernelToStr(InputArray _kernel, int ddepth = -1); CV_EXPORTS String kernelToStr(InputArray _kernel, int ddepth = -1, const char * name = NULL);
CV_EXPORTS void getPlatfomsInfo(std::vector<PlatformInfo>& platform_info); CV_EXPORTS void getPlatfomsInfo(std::vector<PlatformInfo>& platform_info);
CV_EXPORTS int predictOptimalVectorWidth(InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(), CV_EXPORTS int predictOptimalVectorWidth(InputArray src1, InputArray src2 = noArray(), InputArray src3 = noArray(),
InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(), InputArray src4 = noArray(), InputArray src5 = noArray(), InputArray src6 = noArray(),

View File

@ -1299,7 +1299,7 @@ static bool ocl_arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
int type1 = _src1.type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1); int type1 = _src1.type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1);
bool haveMask = !_mask.empty(); bool haveMask = !_mask.empty();
if( ((haveMask || haveScalar) && cn > 4) ) if ( (haveMask || haveScalar) && cn > 4 )
return false; return false;
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), wdepth = std::max(CV_32S, CV_MAT_DEPTH(wtype)); int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), wdepth = std::max(CV_32S, CV_MAT_DEPTH(wtype));
@ -1320,14 +1320,11 @@ static bool ocl_arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
"-D convertToWT2=%s -D convertToDT=%s%s -D cn=%d", "-D convertToWT2=%s -D convertToDT=%s%s -D cn=%d",
(haveMask ? "MASK_" : ""), (haveScalar ? "UNARY_OP" : "BINARY_OP"), (haveMask ? "MASK_" : ""), (haveScalar ? "UNARY_OP" : "BINARY_OP"),
oclop2str[oclop], ocl::typeToStr(CV_MAKETYPE(depth1, kercn)), oclop2str[oclop], ocl::typeToStr(CV_MAKETYPE(depth1, kercn)),
ocl::typeToStr(CV_MAKETYPE(depth1, 1)), ocl::typeToStr(depth1), ocl::typeToStr(CV_MAKETYPE(depth2, kercn)),
ocl::typeToStr(CV_MAKETYPE(depth2, kercn)), ocl::typeToStr(depth2), ocl::typeToStr(CV_MAKETYPE(ddepth, kercn)),
ocl::typeToStr(CV_MAKETYPE(depth2, 1)), ocl::typeToStr(ddepth), ocl::typeToStr(CV_MAKETYPE(wdepth, kercn)),
ocl::typeToStr(CV_MAKETYPE(ddepth, kercn)),
ocl::typeToStr(CV_MAKETYPE(ddepth, 1)),
ocl::typeToStr(CV_MAKETYPE(wdepth, kercn)),
ocl::typeToStr(CV_MAKETYPE(wdepth, scalarcn)), ocl::typeToStr(CV_MAKETYPE(wdepth, scalarcn)),
ocl::typeToStr(CV_MAKETYPE(wdepth, 1)), wdepth, ocl::typeToStr(wdepth), wdepth,
ocl::convertTypeStr(depth1, wdepth, kercn, cvtstr[0]), ocl::convertTypeStr(depth1, wdepth, kercn, cvtstr[0]),
ocl::convertTypeStr(depth2, wdepth, kercn, cvtstr[1]), ocl::convertTypeStr(depth2, wdepth, kercn, cvtstr[1]),
ocl::convertTypeStr(wdepth, ddepth, kercn, cvtstr[2]), ocl::convertTypeStr(wdepth, ddepth, kercn, cvtstr[2]),
@ -1347,7 +1344,7 @@ static bool ocl_arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
} }
ocl::Kernel k("KF", ocl::core::arithm_oclsrc, opts); ocl::Kernel k("KF", ocl::core::arithm_oclsrc, opts);
if( k.empty() ) if (k.empty())
return false; return false;
UMat src1 = _src1.getUMat(), src2; UMat src1 = _src1.getUMat(), src2;
@ -1388,12 +1385,12 @@ static bool ocl_arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
if( !haveMask ) if( !haveMask )
{ {
if(n == 0) if (n == 0)
k.args(src1arg, src2arg, dstarg); k.args(src1arg, src2arg, dstarg);
else if(n == 1) else if (n == 1)
k.args(src1arg, src2arg, dstarg, k.args(src1arg, src2arg, dstarg,
ocl::KernelArg(0, 0, 0, 0, usrdata_p, usrdata_esz)); ocl::KernelArg(0, 0, 0, 0, usrdata_p, usrdata_esz));
else if(n == 3) else if (n == 3)
k.args(src1arg, src2arg, dstarg, k.args(src1arg, src2arg, dstarg,
ocl::KernelArg(0, 0, 0, 0, usrdata_p, usrdata_esz), ocl::KernelArg(0, 0, 0, 0, usrdata_p, usrdata_esz),
ocl::KernelArg(0, 0, 0, 0, usrdata_p + usrdata_esz, usrdata_esz), ocl::KernelArg(0, 0, 0, 0, usrdata_p + usrdata_esz, usrdata_esz),
@ -2621,53 +2618,37 @@ static bool ocl_compare(InputArray _src1, InputArray _src2, OutputArray _dst, in
{ {
const ocl::Device& dev = ocl::Device::getDefault(); const ocl::Device& dev = ocl::Device::getDefault();
bool doubleSupport = dev.doubleFPConfig() > 0; bool doubleSupport = dev.doubleFPConfig() > 0;
int type1 = _src1.type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1); int type1 = _src1.type(), depth1 = CV_MAT_DEPTH(type1), cn = CV_MAT_CN(type1),
int type2 = _src2.type(); type2 = _src2.type(), depth2 = CV_MAT_DEPTH(type2);
if (!haveScalar)
{
if ( (!doubleSupport && (depth1 == CV_64F || _src2.depth() == CV_64F)) ||
!_src1.sameSize(_src2) || type1 != type2)
return false;
}
else
{
if (cn > 1 || depth1 <= CV_32S) // FIXIT: if (cn > 4): Need to clear CPU-based compare behavior
return false;
}
if (!doubleSupport && depth1 == CV_64F) if (!doubleSupport && depth1 == CV_64F)
return false; return false;
if (!haveScalar && (!_src1.sameSize(_src2) || type1 != type2))
return false;
int kercn = haveScalar ? cn : ocl::predictOptimalVectorWidth(_src1, _src2, _dst); int kercn = haveScalar ? cn : ocl::predictOptimalVectorWidth(_src1, _src2, _dst);
// Workaround for bug with "?:" operator in AMD OpenCL compiler // Workaround for bug with "?:" operator in AMD OpenCL compiler
bool workaroundForAMD = /*dev.isAMD() &&*/ if (depth1 >= CV_16U)
(
(depth1 != CV_8U && depth1 != CV_8S)
);
if (workaroundForAMD)
kercn = 1; kercn = 1;
int scalarcn = kercn == 3 ? 4 : kercn; int scalarcn = kercn == 3 ? 4 : kercn;
const char * const operationMap[] = { "==", ">", ">=", "<", "<=", "!=" }; const char * const operationMap[] = { "==", ">", ">=", "<", "<=", "!=" };
char cvt[40]; char cvt[40];
String buildOptions = format( String opts = format("-D %s -D srcT1=%s -D dstT=%s -D workT=srcT1 -D cn=%d"
"-D %s -D srcT1=%s -D dstT=%s -D workT=srcT1 -D cn=%d" " -D convertToDT=%s -D OP_CMP -D CMP_OPERATOR=%s -D srcT1_C1=%s"
" -D convertToDT=%s -D OP_CMP -D CMP_OPERATOR=%s -D srcT1_C1=%s" " -D srcT2_C1=%s -D dstT_C1=%s -D workST=%s%s",
" -D srcT2_C1=%s -D dstT_C1=%s -D workST=%s%s", haveScalar ? "UNARY_OP" : "BINARY_OP",
(haveScalar ? "UNARY_OP" : "BINARY_OP"), ocl::typeToStr(CV_MAKE_TYPE(depth1, kercn)),
ocl::typeToStr(CV_MAKE_TYPE(depth1, kercn)), ocl::typeToStr(CV_8UC(kercn)), kercn,
ocl::typeToStr(CV_8UC(kercn)), kercn, ocl::convertTypeStr(depth1, CV_8U, kercn, cvt),
ocl::convertTypeStr(depth1, CV_8U, kercn, cvt), operationMap[op], ocl::typeToStr(depth1),
operationMap[op], ocl::typeToStr(depth1), ocl::typeToStr(CV_8U),
ocl::typeToStr(depth1), ocl::typeToStr(depth1), ocl::typeToStr(CV_8U), ocl::typeToStr(CV_MAKE_TYPE(depth1, scalarcn)),
ocl::typeToStr(CV_MAKE_TYPE(depth1, scalarcn)), doubleSupport ? " -D DOUBLE_SUPPORT" : "");
doubleSupport ? " -D DOUBLE_SUPPORT" : ""
);
ocl::Kernel k("KF", ocl::core::arithm_oclsrc, buildOptions); ocl::Kernel k("KF", ocl::core::arithm_oclsrc, opts);
if (k.empty()) if (k.empty())
return false; return false;
@ -2678,24 +2659,43 @@ static bool ocl_compare(InputArray _src1, InputArray _src2, OutputArray _dst, in
if (haveScalar) if (haveScalar)
{ {
size_t esz = CV_ELEM_SIZE1(type1)*scalarcn; size_t esz = CV_ELEM_SIZE1(type1) * scalarcn;
double buf[4]={0,0,0,0}; double buf[4] = { 0, 0, 0, 0 };
Mat src2sc = _src2.getMat(); Mat src2 = _src2.getMat();
if (!src2sc.empty()) if( depth1 > CV_32S )
convertAndUnrollScalar(src2sc, type1, (uchar*)buf, 1); convertAndUnrollScalar( src2, depth1, (uchar *)buf, kercn );
else
{
double fval = 0;
getConvertFunc(depth2, CV_64F)(src2.data, 0, 0, 0, (uchar *)&fval, 0, Size(1, 1), 0);
if( fval < getMinVal(depth1) )
return dst.setTo(Scalar::all(op == CMP_GT || op == CMP_GE || op == CMP_NE ? 255 : 0)), true;
if( fval > getMaxVal(depth1) )
return dst.setTo(Scalar::all(op == CMP_LT || op == CMP_LE || op == CMP_NE ? 255 : 0)), true;
int ival = cvRound(fval);
if( fval != ival )
{
if( op == CMP_LT || op == CMP_GE )
ival = cvCeil(fval);
else if( op == CMP_LE || op == CMP_GT )
ival = cvFloor(fval);
else
return dst.setTo(Scalar::all(op == CMP_NE ? 255 : 0)), true;
}
convertAndUnrollScalar(Mat(1, 1, CV_32S, &ival), depth1, (uchar *)buf, kercn);
}
ocl::KernelArg scalararg = ocl::KernelArg(0, 0, 0, 0, buf, esz); ocl::KernelArg scalararg = ocl::KernelArg(0, 0, 0, 0, buf, esz);
k.args(ocl::KernelArg::ReadOnlyNoSize(src1, cn, kercn), k.args(ocl::KernelArg::ReadOnlyNoSize(src1, cn, kercn),
ocl::KernelArg::WriteOnly(dst, cn, kercn), ocl::KernelArg::WriteOnly(dst, cn, kercn), scalararg);
scalararg);
} }
else else
{ {
CV_DbgAssert(type1 == type2);
UMat src2 = _src2.getUMat(); UMat src2 = _src2.getUMat();
CV_DbgAssert(size == src2.size());
k.args(ocl::KernelArg::ReadOnlyNoSize(src1), k.args(ocl::KernelArg::ReadOnlyNoSize(src1),
ocl::KernelArg::ReadOnlyNoSize(src2), ocl::KernelArg::ReadOnlyNoSize(src2),

View File

@ -415,42 +415,54 @@ namespace cv {
static bool ocl_merge( InputArrayOfArrays _mv, OutputArray _dst ) static bool ocl_merge( InputArrayOfArrays _mv, OutputArray _dst )
{ {
std::vector<UMat> src; std::vector<UMat> src, ksrc;
_mv.getUMatVector(src); _mv.getUMatVector(src);
CV_Assert(!src.empty()); CV_Assert(!src.empty());
int type = src[0].type(), depth = CV_MAT_DEPTH(type); int type = src[0].type(), depth = CV_MAT_DEPTH(type);
Size size = src[0].size(); Size size = src[0].size();
size_t srcsize = src.size(); for (size_t i = 0, srcsize = src.size(); i < srcsize; ++i)
for (size_t i = 0; i < srcsize; ++i)
{ {
int itype = src[i].type(), icn = CV_MAT_CN(itype), idepth = CV_MAT_DEPTH(itype); int itype = src[i].type(), icn = CV_MAT_CN(itype), idepth = CV_MAT_DEPTH(itype),
if (src[i].dims > 2 || icn != 1) esz1 = CV_ELEM_SIZE1(idepth);
if (src[i].dims > 2)
return false; return false;
CV_Assert(size == src[i].size() && depth == idepth);
}
String srcargs, srcdecl, processelem; CV_Assert(size == src[i].size() && depth == idepth);
for (size_t i = 0; i < srcsize; ++i)
for (int cn = 0; cn < icn; ++cn)
{
UMat tsrc = src[i];
tsrc.offset += cn * esz1;
ksrc.push_back(tsrc);
}
}
int dcn = (int)ksrc.size();
String srcargs, srcdecl, processelem, cndecl;
for (int i = 0; i < dcn; ++i)
{ {
srcargs += format("DECLARE_SRC_PARAM(%d)", i); srcargs += format("DECLARE_SRC_PARAM(%d)", i);
srcdecl += format("DECLARE_DATA(%d)", i); srcdecl += format("DECLARE_DATA(%d)", i);
processelem += format("PROCESS_ELEM(%d)", i); processelem += format("PROCESS_ELEM(%d)", i);
cndecl += format(" -D scn%d=%d", i, ksrc[i].channels());
} }
ocl::Kernel k("merge", ocl::core::split_merge_oclsrc, ocl::Kernel k("merge", ocl::core::split_merge_oclsrc,
format("-D OP_MERGE -D cn=%d -D T=%s -D DECLARE_SRC_PARAMS_N=%s -D DECLARE_DATA_N=%s -D PROCESS_ELEMS_N=%s", format("-D OP_MERGE -D cn=%d -D T=%s -D DECLARE_SRC_PARAMS_N=%s"
(int)srcsize, ocl::memopTypeToStr(depth), srcargs.c_str(), srcdecl.c_str(), processelem.c_str())); " -D DECLARE_DATA_N=%s -D PROCESS_ELEMS_N=%s%s",
dcn, ocl::memopTypeToStr(depth), srcargs.c_str(),
srcdecl.c_str(), processelem.c_str(), cndecl.c_str()));
if (k.empty()) if (k.empty())
return false; return false;
_dst.create(size, CV_MAKE_TYPE(depth, (int)srcsize)); _dst.create(size, CV_MAKE_TYPE(depth, dcn));
UMat dst = _dst.getUMat(); UMat dst = _dst.getUMat();
int argidx = 0; int argidx = 0;
for (size_t i = 0; i < srcsize; ++i) for (int i = 0; i < dcn; ++i)
argidx = k.set(argidx, ocl::KernelArg::ReadOnlyNoSize(src[i])); argidx = k.set(argidx, ocl::KernelArg::ReadOnlyNoSize(ksrc[i]));
k.set(argidx, ocl::KernelArg::WriteOnly(dst)); k.set(argidx, ocl::KernelArg::WriteOnly(dst));
size_t globalsize[2] = { dst.cols, dst.rows }; size_t globalsize[2] = { dst.cols, dst.rows };

View File

@ -482,9 +482,9 @@ enum { FLIP_COLS = 1 << 0, FLIP_ROWS = 1 << 1, FLIP_BOTH = FLIP_ROWS | FLIP_COLS
static bool ocl_flip(InputArray _src, OutputArray _dst, int flipCode ) static bool ocl_flip(InputArray _src, OutputArray _dst, int flipCode )
{ {
CV_Assert(flipCode >= - 1 && flipCode <= 1); CV_Assert(flipCode >= - 1 && flipCode <= 1);
int type = _src.type(), cn = CV_MAT_CN(type), flipType; int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type), flipType;
if (cn > 4 || cn == 3) if (cn > 4)
return false; return false;
const char * kernelName; const char * kernelName;
@ -506,7 +506,8 @@ static bool ocl_flip(InputArray _src, OutputArray _dst, int flipCode )
} }
ocl::Kernel k(kernelName, ocl::core::flip_oclsrc, ocl::Kernel k(kernelName, ocl::core::flip_oclsrc,
format( "-D type=%s", ocl::memopTypeToStr(type))); format( "-D T=%s -D T1=%s -D cn=%d", ocl::memopTypeToStr(type),
ocl::memopTypeToStr(depth), cn));
if (k.empty()) if (k.empty())
return false; return false;

View File

@ -2041,7 +2041,7 @@ static bool ocl_pow(InputArray _src, double power, OutputArray _dst,
const char * const op = issqrt ? "OP_SQRT" : is_ipower ? "OP_POWN" : "OP_POW"; const char * const op = issqrt ? "OP_SQRT" : is_ipower ? "OP_POWN" : "OP_POW";
ocl::Kernel k("KF", ocl::core::arithm_oclsrc, ocl::Kernel k("KF", ocl::core::arithm_oclsrc,
format("-D dstT=%s -D %s -D UNARY_OP%s", ocl::typeToStr(CV_MAKE_TYPE(depth, 1)), format("-D dstT=%s -D %s -D UNARY_OP%s", ocl::typeToStr(depth),
op, doubleSupport ? " -D DOUBLE_SUPPORT" : "")); op, doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
if (k.empty()) if (k.empty())
return false; return false;
@ -2081,7 +2081,7 @@ void pow( InputArray _src, double power, OutputArray _dst )
{ {
if( ipower < 0 ) if( ipower < 0 )
{ {
divide( 1., _src, _dst ); divide( Scalar::all(1), _src, _dst );
if( ipower == -1 ) if( ipower == -1 )
return; return;
ipower = -ipower; ipower = -ipower;
@ -2115,10 +2115,7 @@ void pow( InputArray _src, double power, OutputArray _dst )
Mat src, dst; Mat src, dst;
if (same) if (same)
{ src = dst = _dst.getMat();
dst = _dst.getMat();
src = dst;
}
else else
{ {
src = _src.getMat(); src = _src.getMat();

View File

@ -1416,6 +1416,16 @@ int _InputArray::kind() const
return flags & KIND_MASK; return flags & KIND_MASK;
} }
int _InputArray::rows(int i) const
{
return size(i).height;
}
int _InputArray::cols(int i) const
{
return size(i).width;
}
Size _InputArray::size(int i) const Size _InputArray::size(int i) const
{ {
int k = kind(); int k = kind();
@ -2078,45 +2088,45 @@ void _OutputArray::create(Size _sz, int mtype, int i, bool allowTransposed, int
create(2, sizes, mtype, i, allowTransposed, fixedDepthMask); create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
} }
void _OutputArray::create(int rows, int cols, int mtype, int i, bool allowTransposed, int fixedDepthMask) const void _OutputArray::create(int _rows, int _cols, int mtype, int i, bool allowTransposed, int fixedDepthMask) const
{ {
int k = kind(); int k = kind();
if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) if( k == MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{ {
CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(cols, rows)); CV_Assert(!fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows));
CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype); CV_Assert(!fixedType() || ((Mat*)obj)->type() == mtype);
((Mat*)obj)->create(rows, cols, mtype); ((Mat*)obj)->create(_rows, _cols, mtype);
return; return;
} }
if( k == UMAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) if( k == UMAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{ {
CV_Assert(!fixedSize() || ((UMat*)obj)->size.operator()() == Size(cols, rows)); CV_Assert(!fixedSize() || ((UMat*)obj)->size.operator()() == Size(_cols, _rows));
CV_Assert(!fixedType() || ((UMat*)obj)->type() == mtype); CV_Assert(!fixedType() || ((UMat*)obj)->type() == mtype);
((UMat*)obj)->create(rows, cols, mtype); ((UMat*)obj)->create(_rows, _cols, mtype);
return; return;
} }
if( k == GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 ) if( k == GPU_MAT && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{ {
CV_Assert(!fixedSize() || ((cuda::GpuMat*)obj)->size() == Size(cols, rows)); CV_Assert(!fixedSize() || ((cuda::GpuMat*)obj)->size() == Size(_cols, _rows));
CV_Assert(!fixedType() || ((cuda::GpuMat*)obj)->type() == mtype); CV_Assert(!fixedType() || ((cuda::GpuMat*)obj)->type() == mtype);
((cuda::GpuMat*)obj)->create(rows, cols, mtype); ((cuda::GpuMat*)obj)->create(_rows, _cols, mtype);
return; return;
} }
if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 ) if( k == OPENGL_BUFFER && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{ {
CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == Size(cols, rows)); CV_Assert(!fixedSize() || ((ogl::Buffer*)obj)->size() == Size(_cols, _rows));
CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype); CV_Assert(!fixedType() || ((ogl::Buffer*)obj)->type() == mtype);
((ogl::Buffer*)obj)->create(rows, cols, mtype); ((ogl::Buffer*)obj)->create(_rows, _cols, mtype);
return; return;
} }
if( k == CUDA_MEM && i < 0 && !allowTransposed && fixedDepthMask == 0 ) if( k == CUDA_MEM && i < 0 && !allowTransposed && fixedDepthMask == 0 )
{ {
CV_Assert(!fixedSize() || ((cuda::CudaMem*)obj)->size() == Size(cols, rows)); CV_Assert(!fixedSize() || ((cuda::CudaMem*)obj)->size() == Size(_cols, _rows));
CV_Assert(!fixedType() || ((cuda::CudaMem*)obj)->type() == mtype); CV_Assert(!fixedType() || ((cuda::CudaMem*)obj)->type() == mtype);
((cuda::CudaMem*)obj)->create(rows, cols, mtype); ((cuda::CudaMem*)obj)->create(_rows, _cols, mtype);
return; return;
} }
int sizes[] = {rows, cols}; int sizes[] = {_rows, _cols};
create(2, sizes, mtype, i, allowTransposed, fixedDepthMask); create(2, sizes, mtype, i, allowTransposed, fixedDepthMask);
} }
@ -2679,17 +2689,17 @@ namespace cv {
static bool ocl_setIdentity( InputOutputArray _m, const Scalar& s ) static bool ocl_setIdentity( InputOutputArray _m, const Scalar& s )
{ {
int type = _m.type(), cn = CV_MAT_CN(type); int type = _m.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type),
if (cn == 3) sctype = CV_MAKE_TYPE(depth, cn == 3 ? 4 : cn);
return false;
ocl::Kernel k("setIdentity", ocl::core::set_identity_oclsrc, ocl::Kernel k("setIdentity", ocl::core::set_identity_oclsrc,
format("-D T=%s", ocl::memopTypeToStr(type))); format("-D T=%s -D T1=%s -D cn=%d -D ST=%s", ocl::memopTypeToStr(type),
ocl::memopTypeToStr(depth), cn, ocl::memopTypeToStr(sctype)));
if (k.empty()) if (k.empty())
return false; return false;
UMat m = _m.getUMat(); UMat m = _m.getUMat();
k.args(ocl::KernelArg::WriteOnly(m), ocl::KernelArg::Constant(Mat(1, 1, type, s))); k.args(ocl::KernelArg::WriteOnly(m), ocl::KernelArg::Constant(Mat(1, 1, sctype, s)));
size_t globalsize[2] = { m.cols, m.rows }; size_t globalsize[2] = { m.cols, m.rows };
return k.run(2, globalsize, NULL, false); return k.run(2, globalsize, NULL, false);

View File

@ -1410,7 +1410,7 @@ bool useOpenCL()
{ {
CoreTLSData* data = coreTlsData.get(); CoreTLSData* data = coreTlsData.get();
if( data->useOpenCL < 0 ) if( data->useOpenCL < 0 )
data->useOpenCL = (int)haveOpenCL(); data->useOpenCL = (int)haveOpenCL() && Device::getDefault().ptr() != NULL;
return data->useOpenCL > 0; return data->useOpenCL > 0;
} }
@ -1419,7 +1419,7 @@ void setUseOpenCL(bool flag)
if( haveOpenCL() ) if( haveOpenCL() )
{ {
CoreTLSData* data = coreTlsData.get(); CoreTLSData* data = coreTlsData.get();
data->useOpenCL = flag ? 1 : 0; data->useOpenCL = (flag && Device::getDefault().ptr() != NULL) ? 1 : 0;
} }
} }
@ -2179,7 +2179,6 @@ static cl_device_id selectOpenCLDevice()
goto not_found; goto not_found;
} }
} }
if (deviceTypes.size() == 0) if (deviceTypes.size() == 0)
{ {
if (!isID) if (!isID)
@ -2193,13 +2192,16 @@ static cl_device_id selectOpenCLDevice()
for (size_t t = 0; t < deviceTypes.size(); t++) for (size_t t = 0; t < deviceTypes.size(); t++)
{ {
int deviceType = 0; int deviceType = 0;
if (deviceTypes[t] == "GPU") std::string tempStrDeviceType = deviceTypes[t];
std::transform( tempStrDeviceType.begin(), tempStrDeviceType.end(), tempStrDeviceType.begin(), tolower );
if (tempStrDeviceType == "gpu" || tempStrDeviceType == "dgpu" || tempStrDeviceType == "igpu")
deviceType = Device::TYPE_GPU; deviceType = Device::TYPE_GPU;
else if (deviceTypes[t] == "CPU") else if (tempStrDeviceType == "cpu")
deviceType = Device::TYPE_CPU; deviceType = Device::TYPE_CPU;
else if (deviceTypes[t] == "ACCELERATOR") else if (tempStrDeviceType == "accelerator")
deviceType = Device::TYPE_ACCELERATOR; deviceType = Device::TYPE_ACCELERATOR;
else if (deviceTypes[t] == "ALL") else if (tempStrDeviceType == "all")
deviceType = Device::TYPE_ALL; deviceType = Device::TYPE_ALL;
else else
{ {
@ -2229,7 +2231,14 @@ static cl_device_id selectOpenCLDevice()
{ {
std::string name; std::string name;
CV_OclDbgAssert(getStringInfo(clGetDeviceInfo, devices[i], CL_DEVICE_NAME, name) == CL_SUCCESS); CV_OclDbgAssert(getStringInfo(clGetDeviceInfo, devices[i], CL_DEVICE_NAME, name) == CL_SUCCESS);
if (isID || name.find(deviceName) != std::string::npos) cl_bool useGPU = true;
if(tempStrDeviceType == "dgpu" || tempStrDeviceType == "igpu")
{
cl_bool isIGPU = CL_FALSE;
clGetDeviceInfo(devices[i], CL_DEVICE_HOST_UNIFIED_MEMORY, sizeof(isIGPU), &isIGPU, NULL);
useGPU = tempStrDeviceType == "dgpu" ? !isIGPU : isIGPU;
}
if ( (isID || name.find(deviceName) != std::string::npos) && useGPU)
{ {
// TODO check for OpenCL 1.1 // TODO check for OpenCL 1.1
return devices[i]; return devices[i];
@ -2245,6 +2254,7 @@ not_found:
std::cerr << deviceTypes[t] << " "; std::cerr << deviceTypes[t] << " ";
std::cerr << std::endl << " Device name: " << (deviceName.length() == 0 ? "any" : deviceName) << std::endl; std::cerr << std::endl << " Device name: " << (deviceName.length() == 0 ? "any" : deviceName) << std::endl;
CV_Error(CL_INVALID_DEVICE, "Requested OpenCL device is not found");
return NULL; return NULL;
} }
@ -4306,7 +4316,7 @@ static std::string kerToStr(const Mat & k)
return stream.str(); return stream.str();
} }
String kernelToStr(InputArray _kernel, int ddepth) String kernelToStr(InputArray _kernel, int ddepth, const char * name)
{ {
Mat kernel = _kernel.getMat().reshape(1, 1); Mat kernel = _kernel.getMat().reshape(1, 1);
@ -4317,13 +4327,13 @@ String kernelToStr(InputArray _kernel, int ddepth)
if (ddepth != depth) if (ddepth != depth)
kernel.convertTo(kernel, ddepth); kernel.convertTo(kernel, ddepth);
typedef std::string (*func_t)(const Mat &); typedef std::string (* func_t)(const Mat &);
static const func_t funcs[] = { kerToStr<uchar>, kerToStr<char>, kerToStr<ushort>,kerToStr<short>, static const func_t funcs[] = { kerToStr<uchar>, kerToStr<char>, kerToStr<ushort>, kerToStr<short>,
kerToStr<int>, kerToStr<float>, kerToStr<double>, 0 }; kerToStr<int>, kerToStr<float>, kerToStr<double>, 0 };
const func_t func = funcs[depth]; const func_t func = funcs[depth];
CV_Assert(func != 0); CV_Assert(func != 0);
return cv::format(" -D COEFF=%s", func(kernel).c_str()); return cv::format(" -D %s=%s", name ? name : "COEFF", func(kernel).c_str());
} }
#define PROCESS_SRC(src) \ #define PROCESS_SRC(src) \
@ -4347,7 +4357,7 @@ int predictOptimalVectorWidth(InputArray src1, InputArray src2, InputArray src3,
InputArray src4, InputArray src5, InputArray src6, InputArray src4, InputArray src5, InputArray src6,
InputArray src7, InputArray src8, InputArray src9) InputArray src7, InputArray src8, InputArray src9)
{ {
int type = src1.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); int type = src1.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type), esz = CV_ELEM_SIZE(depth);
Size ssize = src1.size(); Size ssize = src1.size();
const ocl::Device & d = ocl::Device::getDefault(); const ocl::Device & d = ocl::Device::getDefault();
@ -4371,7 +4381,8 @@ int predictOptimalVectorWidth(InputArray src1, InputArray src2, InputArray src3,
PROCESS_SRC(src9); PROCESS_SRC(src9);
size_t size = offsets.size(); size_t size = offsets.size();
std::vector<int> dividers(size, width); int wsz = width * esz;
std::vector<int> dividers(size, wsz);
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
while (offsets[i] % dividers[i] != 0 || steps[i] % dividers[i] != 0 || cols[i] % dividers[i] != 0) while (offsets[i] % dividers[i] != 0 || steps[i] % dividers[i] != 0 || cols[i] % dividers[i] != 0)
@ -4379,7 +4390,7 @@ int predictOptimalVectorWidth(InputArray src1, InputArray src2, InputArray src3,
// default strategy // default strategy
for (size_t i = 0; i < size; ++i) for (size_t i = 0; i < size; ++i)
if (dividers[i] != width) if (dividers[i] != wsz)
{ {
width = 1; width = 1;
break; break;

View File

@ -39,10 +39,18 @@
// //
//M*/ //M*/
#define sizeoftype ((int)sizeof(type)) #if cn != 3
#define loadpix(addr) *(__global const T *)(addr)
#define storepix(val, addr) *(__global T *)(addr) = val
#define TSIZE (int)sizeof(T)
#else
#define loadpix(addr) vload3(0, (__global const T1 *)(addr))
#define storepix(val, addr) vstore3(val, 0, (__global T1 *)(addr))
#define TSIZE ((int)sizeof(T1)*3)
#endif
__kernel void arithm_flip_rows(__global const uchar* srcptr, int srcstep, int srcoffset, __kernel void arithm_flip_rows(__global const uchar * srcptr, int src_step, int src_offset,
__global uchar* dstptr, int dststep, int dstoffset, __global uchar * dstptr, int dst_step, int dst_offset,
int rows, int cols, int thread_rows, int thread_cols) int rows, int cols, int thread_rows, int thread_cols)
{ {
int x = get_global_id(0); int x = get_global_id(0);
@ -50,19 +58,16 @@ __kernel void arithm_flip_rows(__global const uchar* srcptr, int srcstep, int sr
if (x < cols && y < thread_rows) if (x < cols && y < thread_rows)
{ {
__global const type* src0 = (__global const type*)(srcptr + mad24(y, srcstep, mad24(x, sizeoftype, srcoffset))); T src0 = loadpix(srcptr + mad24(y, src_step, mad24(x, TSIZE, src_offset)));
__global const type* src1 = (__global const type*)(srcptr + mad24(rows - y - 1, srcstep, mad24(x, sizeoftype, srcoffset))); T src1 = loadpix(srcptr + mad24(rows - y - 1, src_step, mad24(x, TSIZE, src_offset)));
__global type* dst0 = (__global type*)(dstptr + mad24(y, dststep, mad24(x, sizeoftype, dstoffset))); storepix(src1, dstptr + mad24(y, dst_step, mad24(x, TSIZE, dst_offset)));
__global type* dst1 = (__global type*)(dstptr + mad24(rows - y - 1, dststep, mad24(x, sizeoftype, dstoffset))); storepix(src0, dstptr + mad24(rows - y - 1, dst_step, mad24(x, TSIZE, dst_offset)));
dst0[0] = src1[0];
dst1[0] = src0[0];
} }
} }
__kernel void arithm_flip_rows_cols(__global const uchar* srcptr, int srcstep, int srcoffset, __kernel void arithm_flip_rows_cols(__global const uchar * srcptr, int src_step, int src_offset,
__global uchar* dstptr, int dststep, int dstoffset, __global uchar * dstptr, int dst_step, int dst_offset,
int rows, int cols, int thread_rows, int thread_cols) int rows, int cols, int thread_rows, int thread_cols)
{ {
int x = get_global_id(0); int x = get_global_id(0);
@ -71,19 +76,16 @@ __kernel void arithm_flip_rows_cols(__global const uchar* srcptr, int srcstep, i
if (x < cols && y < thread_rows) if (x < cols && y < thread_rows)
{ {
int x1 = cols - x - 1; int x1 = cols - x - 1;
__global const type* src0 = (__global const type*)(srcptr + mad24(y, srcstep, mad24(x, sizeoftype, srcoffset))); T src0 = loadpix(srcptr + mad24(y, src_step, mad24(x, TSIZE, src_offset)));
__global const type* src1 = (__global const type*)(srcptr + mad24(rows - y - 1, srcstep, mad24(x1, sizeoftype, srcoffset))); T src1 = loadpix(srcptr + mad24(rows - y - 1, src_step, mad24(x1, TSIZE, src_offset)));
__global type* dst0 = (__global type*)(dstptr + mad24(rows - y - 1, dststep, mad24(x1, sizeoftype, dstoffset))); storepix(src0, dstptr + mad24(rows - y - 1, dst_step, mad24(x1, TSIZE, dst_offset)));
__global type* dst1 = (__global type*)(dstptr + mad24(y, dststep, mad24(x, sizeoftype, dstoffset))); storepix(src1, dstptr + mad24(y, dst_step, mad24(x, TSIZE, dst_offset)));
dst0[0] = src0[0];
dst1[0] = src1[0];
} }
} }
__kernel void arithm_flip_cols(__global const uchar* srcptr, int srcstep, int srcoffset, __kernel void arithm_flip_cols(__global const uchar * srcptr, int src_step, int src_offset,
__global uchar* dstptr, int dststep, int dstoffset, __global uchar * dstptr, int dst_step, int dst_offset,
int rows, int cols, int thread_rows, int thread_cols) int rows, int cols, int thread_rows, int thread_cols)
{ {
int x = get_global_id(0); int x = get_global_id(0);
@ -92,13 +94,10 @@ __kernel void arithm_flip_cols(__global const uchar* srcptr, int srcstep, int sr
if (x < thread_cols && y < rows) if (x < thread_cols && y < rows)
{ {
int x1 = cols - x - 1; int x1 = cols - x - 1;
__global const type* src0 = (__global const type*)(srcptr + mad24(y, srcstep, mad24(x, sizeoftype, srcoffset))); T src0 = loadpix(srcptr + mad24(y, src_step, mad24(x, TSIZE, src_offset)));
__global const type* src1 = (__global const type*)(srcptr + mad24(y, srcstep, mad24(x1, sizeoftype, srcoffset))); T src1 = loadpix(srcptr + mad24(y, src_step, mad24(x1, TSIZE, src_offset)));
__global type* dst0 = (__global type*)(dstptr + mad24(y, dststep, mad24(x1, sizeoftype, dstoffset))); storepix(src0, dstptr + mad24(y, dst_step, mad24(x1, TSIZE, dst_offset)));
__global type* dst1 = (__global type*)(dstptr + mad24(y, dststep, mad24(x, sizeoftype, dstoffset))); storepix(src1, dstptr + mad24(y, dst_step, mad24(x, TSIZE, dst_offset)));
dst1[0] = src1[0];
dst0[0] = src0[0];
} }
} }

View File

@ -43,17 +43,28 @@
// //
//M*/ //M*/
#if cn != 3
#define loadpix(addr) *(__global const T *)(addr)
#define storepix(val, addr) *(__global T *)(addr) = val
#define TSIZE (int)sizeof(T)
#define scalar scalar_
#else
#define loadpix(addr) vload3(0, (__global const T1 *)(addr))
#define storepix(val, addr) vstore3(val, 0, (__global T1 *)(addr))
#define TSIZE ((int)sizeof(T1)*3)
#define scalar (T)(scalar_.x, scalar_.y, scalar_.z)
#endif
__kernel void setIdentity(__global uchar * srcptr, int src_step, int src_offset, int rows, int cols, __kernel void setIdentity(__global uchar * srcptr, int src_step, int src_offset, int rows, int cols,
T scalar) ST scalar_)
{ {
int x = get_global_id(0); int x = get_global_id(0);
int y = get_global_id(1); int y = get_global_id(1);
if (x < cols && y < rows) if (x < cols && y < rows)
{ {
int src_index = mad24(y, src_step, mad24(x, (int)sizeof(T), src_offset)); int src_index = mad24(y, src_step, mad24(x, TSIZE, src_offset));
__global T * src = (__global T *)(srcptr + src_index);
src[0] = x == y ? scalar : (T)(0); storepix(x == y ? scalar : (T)(0), srcptr + src_index);
} }
} }

View File

@ -45,7 +45,7 @@
#define DECLARE_SRC_PARAM(index) __global const uchar * src##index##ptr, int src##index##_step, int src##index##_offset, #define DECLARE_SRC_PARAM(index) __global const uchar * src##index##ptr, int src##index##_step, int src##index##_offset,
#define DECLARE_DATA(index) __global const T * src##index = \ #define DECLARE_DATA(index) __global const T * src##index = \
(__global T *)(src##index##ptr + mad24(src##index##_step, y, mad24(x, (int)sizeof(T), src##index##_offset))); (__global T *)(src##index##ptr + mad24(src##index##_step, y, mad24(x, (int)sizeof(T) * scn##index, src##index##_offset)));
#define PROCESS_ELEM(index) dst[index] = src##index[0]; #define PROCESS_ELEM(index) dst[index] = src##index[0];
__kernel void merge(DECLARE_SRC_PARAMS_N __kernel void merge(DECLARE_SRC_PARAMS_N

View File

@ -4824,7 +4824,7 @@ cvRegisterType( const CvTypeInfo* _info )
"Type name should contain only letters, digits, - and _" ); "Type name should contain only letters, digits, - and _" );
} }
info = (CvTypeInfo*)malloc( sizeof(*info) + len + 1 ); info = (CvTypeInfo*)cvAlloc( sizeof(*info) + len + 1 );
*info = *_info; *info = *_info;
info->type_name = (char*)(info + 1); info->type_name = (char*)(info + 1);
@ -4862,7 +4862,7 @@ cvUnregisterType( const char* type_name )
if( !CvType::first || !CvType::last ) if( !CvType::first || !CvType::last )
CvType::first = CvType::last = 0; CvType::first = CvType::last = 0;
free( info ); cvFree( &info );
} }
} }
@ -5486,11 +5486,27 @@ internal::WriteStructContext::WriteStructContext(FileStorage& _fs,
{ {
cvStartWriteStruct(**fs, !name.empty() ? name.c_str() : 0, flags, cvStartWriteStruct(**fs, !name.empty() ? name.c_str() : 0, flags,
!typeName.empty() ? typeName.c_str() : 0); !typeName.empty() ? typeName.c_str() : 0);
fs->elname = String();
if ((flags & FileNode::TYPE_MASK) == FileNode::SEQ)
{
fs->state = FileStorage::VALUE_EXPECTED;
fs->structs.push_back('[');
}
else
{
fs->state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
fs->structs.push_back('{');
}
} }
internal::WriteStructContext::~WriteStructContext() internal::WriteStructContext::~WriteStructContext()
{ {
cvEndWriteStruct(**fs); cvEndWriteStruct(**fs);
fs->structs.pop_back();
fs->state = fs->structs.empty() || fs->structs.back() == '{' ?
FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP :
FileStorage::VALUE_EXPECTED;
fs->elname = String();
} }

View File

@ -414,24 +414,23 @@ const String& getBuildInformation()
String format( const char* fmt, ... ) String format( const char* fmt, ... )
{ {
char buf[1024]; AutoBuffer<char, 1024> buf;
va_list va; for ( ; ; )
va_start(va, fmt);
int len = vsnprintf(buf, sizeof(buf), fmt, va);
va_end(va);
if (len >= (int)sizeof(buf))
{ {
String s(len, '\0'); va_list va;
va_start(va, fmt); va_start(va, fmt);
len = vsnprintf((char*)s.c_str(), len + 1, fmt, va); int bsize = static_cast<int>(buf.size()),
(void)len; len = vsnprintf((char *)buf, bsize, fmt, va);
va_end(va); va_end(va);
return s;
}
return String(buf, len); if (len < 0 || len >= bsize)
{
buf.resize(std::max(bsize << 1, len + 1));
continue;
}
return String((char *)buf, len);
}
} }
String tempfile( const char* suffix ) String tempfile( const char* suffix )

View File

@ -88,8 +88,10 @@ void UMatData::unlock()
MatAllocator* UMat::getStdAllocator() MatAllocator* UMat::getStdAllocator()
{ {
if( ocl::haveOpenCL() ) #ifdef HAVE_OPENCL
if( ocl::haveOpenCL() && ocl::useOpenCL() )
return ocl::getOpenCLAllocator(); return ocl::getOpenCLAllocator();
#endif
return Mat::getStdAllocator(); return Mat::getStdAllocator();
} }
@ -665,7 +667,7 @@ void UMat::copyTo(OutputArray _dst, InputArray _mask) const
copyTo(_dst); copyTo(_dst);
return; return;
} }
#ifdef HAVE_OPENCL
int cn = channels(), mtype = _mask.type(), mdepth = CV_MAT_DEPTH(mtype), mcn = CV_MAT_CN(mtype); int cn = channels(), mtype = _mask.type(), mdepth = CV_MAT_DEPTH(mtype), mcn = CV_MAT_CN(mtype);
CV_Assert( mdepth == CV_8U && (mcn == 1 || mcn == cn) ); CV_Assert( mdepth == CV_8U && (mcn == 1 || mcn == cn) );
@ -692,7 +694,7 @@ void UMat::copyTo(OutputArray _dst, InputArray _mask) const
return; return;
} }
} }
#endif
Mat src = getMat(ACCESS_READ); Mat src = getMat(ACCESS_READ);
src.copyTo(_dst, _mask); src.copyTo(_dst, _mask);
} }
@ -713,7 +715,7 @@ void UMat::convertTo(OutputArray _dst, int _type, double alpha, double beta) con
copyTo(_dst); copyTo(_dst);
return; return;
} }
#ifdef HAVE_OPENCL
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0; bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
bool needDouble = sdepth == CV_64F || ddepth == CV_64F; bool needDouble = sdepth == CV_64F || ddepth == CV_64F;
if( dims <= 2 && cn && _dst.isUMat() && ocl::useOpenCL() && if( dims <= 2 && cn && _dst.isUMat() && ocl::useOpenCL() &&
@ -748,7 +750,7 @@ void UMat::convertTo(OutputArray _dst, int _type, double alpha, double beta) con
return; return;
} }
} }
#endif
Mat m = getMat(ACCESS_READ); Mat m = getMat(ACCESS_READ);
m.convertTo(_dst, _type, alpha, beta); m.convertTo(_dst, _type, alpha, beta);
} }
@ -756,7 +758,9 @@ void UMat::convertTo(OutputArray _dst, int _type, double alpha, double beta) con
UMat& UMat::setTo(InputArray _value, InputArray _mask) UMat& UMat::setTo(InputArray _value, InputArray _mask)
{ {
bool haveMask = !_mask.empty(); bool haveMask = !_mask.empty();
#ifdef HAVE_OPENCL
int tp = type(), cn = CV_MAT_CN(tp); int tp = type(), cn = CV_MAT_CN(tp);
if( dims <= 2 && cn <= 4 && CV_MAT_DEPTH(tp) < CV_64F && ocl::useOpenCL() ) if( dims <= 2 && cn <= 4 && CV_MAT_DEPTH(tp) < CV_64F && ocl::useOpenCL() )
{ {
Mat value = _value.getMat(); Mat value = _value.getMat();
@ -795,6 +799,7 @@ UMat& UMat::setTo(InputArray _value, InputArray _mask)
return *this; return *this;
} }
} }
#endif
Mat m = getMat(haveMask ? ACCESS_RW : ACCESS_WRITE); Mat m = getMat(haveMask ? ACCESS_RW : ACCESS_WRITE);
m.setTo(_value, _mask); m.setTo(_value, _mask);
return *this; return *this;

View File

@ -57,9 +57,9 @@ PARAM_TEST_CASE(Lut, MatDepth, MatDepth, Channels, bool, bool)
int cn; int cn;
bool use_roi, same_cn; bool use_roi, same_cn;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_INPUT_PARAMETER(lut) TEST_DECLARE_INPUT_PARAMETER(lut);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -87,14 +87,14 @@ PARAM_TEST_CASE(Lut, MatDepth, MatDepth, Channels, bool, bool)
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0); Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, dst_type, 5, 16); randomSubMat(dst, dst_roi, roiSize, dstBorder, dst_type, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src) UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_INPUT_PARAMETER(lut) UMAT_UPLOAD_INPUT_PARAMETER(lut);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst) UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
void Near(double threshold = 0.) void Near(double threshold = 0.)
{ {
OCL_EXPECT_MATS_NEAR(dst, threshold) OCL_EXPECT_MATS_NEAR(dst, threshold);
} }
}; };
@ -121,11 +121,11 @@ PARAM_TEST_CASE(ArithmTestBase, MatDepth, Channels, bool)
cv::Scalar val; cv::Scalar val;
cv::Scalar val_in_range; cv::Scalar val_in_range;
TEST_DECLARE_INPUT_PARAMETER(src1) TEST_DECLARE_INPUT_PARAMETER(src1);
TEST_DECLARE_INPUT_PARAMETER(src2) TEST_DECLARE_INPUT_PARAMETER(src2);
TEST_DECLARE_INPUT_PARAMETER(mask) TEST_DECLARE_INPUT_PARAMETER(mask);
TEST_DECLARE_OUTPUT_PARAMETER(dst1) TEST_DECLARE_OUTPUT_PARAMETER(dst1);
TEST_DECLARE_OUTPUT_PARAMETER(dst2) TEST_DECLARE_OUTPUT_PARAMETER(dst2);
virtual void SetUp() virtual void SetUp()
{ {
@ -167,21 +167,21 @@ PARAM_TEST_CASE(ArithmTestBase, MatDepth, Channels, bool)
rng.uniform(minV, maxV), rng.uniform(minV, maxV)); rng.uniform(minV, maxV), rng.uniform(minV, maxV));
} }
UMAT_UPLOAD_INPUT_PARAMETER(src1) UMAT_UPLOAD_INPUT_PARAMETER(src1);
UMAT_UPLOAD_INPUT_PARAMETER(src2) UMAT_UPLOAD_INPUT_PARAMETER(src2);
UMAT_UPLOAD_INPUT_PARAMETER(mask) UMAT_UPLOAD_INPUT_PARAMETER(mask);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst1) UMAT_UPLOAD_OUTPUT_PARAMETER(dst1);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst2) UMAT_UPLOAD_OUTPUT_PARAMETER(dst2);
} }
void Near(double threshold = 0.) void Near(double threshold = 0.)
{ {
OCL_EXPECT_MATS_NEAR(dst1, threshold) OCL_EXPECT_MATS_NEAR(dst1, threshold);
} }
void Near1(double threshold = 0.) void Near1(double threshold = 0.)
{ {
OCL_EXPECT_MATS_NEAR(dst2, threshold) OCL_EXPECT_MATS_NEAR(dst2, threshold);
} }
}; };
@ -556,6 +556,12 @@ OCL_TEST_P(Transpose, Mat)
{ {
generateTestData(); generateTestData();
Size roiSize = src1_roi.size();
Border dst1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst1, dst1_roi, Size(roiSize.height, roiSize.width), dst1Border, src1.type(), 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(dst1);
OCL_OFF(cv::transpose(src1_roi, dst1_roi)); OCL_OFF(cv::transpose(src1_roi, dst1_roi));
OCL_ON(cv::transpose(usrc1_roi, udst1_roi)); OCL_ON(cv::transpose(usrc1_roi, udst1_roi));
@ -580,7 +586,7 @@ OCL_TEST_P(Transpose, SquareInplace)
OCL_OFF(cv::transpose(src1_roi, src1_roi)); OCL_OFF(cv::transpose(src1_roi, src1_roi));
OCL_ON(cv::transpose(usrc1_roi, usrc1_roi)); OCL_ON(cv::transpose(usrc1_roi, usrc1_roi));
OCL_EXPECT_MATS_NEAR(src1, 0) OCL_EXPECT_MATS_NEAR(src1, 0);
} }
} }
@ -761,7 +767,7 @@ OCL_TEST_P(Bitwise_not, Mat)
typedef ArithmTestBase Compare; typedef ArithmTestBase Compare;
static const int cmp_codes[] = { CMP_EQ, CMP_GT, CMP_GE, CMP_LT, CMP_LE, CMP_NE }; static const int cmp_codes[] = { CMP_EQ, CMP_GT, CMP_GE, CMP_LT, CMP_LE, CMP_NE };
static const char* cmp_strs[] = { "CMP_EQ", "CMP_GT", "CMP_GE", "CMP_LT", "CMP_LE", "CMP_NE" }; static const char * cmp_strs[] = { "CMP_EQ", "CMP_GT", "CMP_GE", "CMP_LT", "CMP_LE", "CMP_NE" };
static const int cmp_num = sizeof(cmp_codes) / sizeof(int); static const int cmp_num = sizeof(cmp_codes) / sizeof(int);
OCL_TEST_P(Compare, Mat) OCL_TEST_P(Compare, Mat)
@ -826,12 +832,14 @@ OCL_TEST_P(Pow, Mat)
for (int j = 0; j < test_loop_times; j++) for (int j = 0; j < test_loop_times; j++)
for (int k = 0, size = sizeof(pows) / sizeof(double); k < size; ++k) for (int k = 0, size = sizeof(pows) / sizeof(double); k < size; ++k)
{ {
SCOPED_TRACE(pows[k]);
generateTestData(); generateTestData();
OCL_OFF(cv::pow(src1_roi, pows[k], dst1_roi)); OCL_OFF(cv::pow(src1_roi, pows[k], dst1_roi));
OCL_ON(cv::pow(usrc1_roi, pows[k], udst1_roi)); OCL_ON(cv::pow(usrc1_roi, pows[k], udst1_roi));
Near(1); // FIXIT: Relative error check! OCL_EXPECT_MATS_NEAR_RELATIVE(dst1, 1e-5);
} }
} }
@ -893,8 +901,8 @@ struct RepeatTestCase :
Border dst1Border = randomBorder(0, use_roi ? MAX_VALUE : 0); Border dst1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst1, dst1_roi, dstRoiSize, dst1Border, type, 5, 16); randomSubMat(dst1, dst1_roi, dstRoiSize, dst1Border, type, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src1) UMAT_UPLOAD_INPUT_PARAMETER(src1);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst1) UMAT_UPLOAD_OUTPUT_PARAMETER(dst1);
} }
}; };
@ -1450,10 +1458,10 @@ PARAM_TEST_CASE(InRange, MatDepth, Channels, bool /*Scalar or not*/, bool /*Roi*
bool scalars, use_roi; bool scalars, use_roi;
cv::Scalar val1, val2; cv::Scalar val1, val2;
TEST_DECLARE_INPUT_PARAMETER(src1) TEST_DECLARE_INPUT_PARAMETER(src1);
TEST_DECLARE_INPUT_PARAMETER(src2) TEST_DECLARE_INPUT_PARAMETER(src2);
TEST_DECLARE_INPUT_PARAMETER(src3) TEST_DECLARE_INPUT_PARAMETER(src3);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -1485,15 +1493,15 @@ PARAM_TEST_CASE(InRange, MatDepth, Channels, bool /*Scalar or not*/, bool /*Roi*
val2 = cv::Scalar(rng.uniform(-100.0, 100.0), rng.uniform(-100.0, 100.0), val2 = cv::Scalar(rng.uniform(-100.0, 100.0), rng.uniform(-100.0, 100.0),
rng.uniform(-100.0, 100.0), rng.uniform(-100.0, 100.0)); rng.uniform(-100.0, 100.0), rng.uniform(-100.0, 100.0));
UMAT_UPLOAD_INPUT_PARAMETER(src1) UMAT_UPLOAD_INPUT_PARAMETER(src1);
UMAT_UPLOAD_INPUT_PARAMETER(src2) UMAT_UPLOAD_INPUT_PARAMETER(src2);
UMAT_UPLOAD_INPUT_PARAMETER(src3) UMAT_UPLOAD_INPUT_PARAMETER(src3);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst) UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
void Near() void Near()
{ {
OCL_EXPECT_MATS_NEAR(dst, 0) OCL_EXPECT_MATS_NEAR(dst, 0);
} }
}; };
@ -1565,7 +1573,7 @@ PARAM_TEST_CASE(PatchNaNs, Channels, bool)
bool use_roi; bool use_roi;
double value; double value;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
virtual void SetUp() virtual void SetUp()
{ {
@ -1592,12 +1600,12 @@ PARAM_TEST_CASE(PatchNaNs, Channels, bool)
value = randomDouble(-100, 100); value = randomDouble(-100, 100);
UMAT_UPLOAD_INPUT_PARAMETER(src) UMAT_UPLOAD_INPUT_PARAMETER(src);
} }
void Near() void Near()
{ {
OCL_EXPECT_MATS_NEAR(src, 0) OCL_EXPECT_MATS_NEAR(src, 0);
} }
}; };
@ -1640,8 +1648,8 @@ PARAM_TEST_CASE(Reduce, std::pair<MatDepth, MatDepth>, Channels, int, bool)
int sdepth, ddepth, cn, dim, dtype; int sdepth, ddepth, cn, dim, dtype;
bool use_roi; bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -1666,8 +1674,8 @@ PARAM_TEST_CASE(Reduce, std::pair<MatDepth, MatDepth>, Channels, int, bool)
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0); Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, dstRoiSize, dstBorder, dtype, 5, 16); randomSubMat(dst, dst_roi, dstRoiSize, dstBorder, dtype, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src) UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst) UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
}; };
@ -1683,7 +1691,7 @@ OCL_TEST_P(ReduceSum, Mat)
OCL_ON(cv::reduce(usrc_roi, udst_roi, dim, CV_REDUCE_SUM, dtype)); OCL_ON(cv::reduce(usrc_roi, udst_roi, dim, CV_REDUCE_SUM, dtype));
double eps = ddepth <= CV_32S ? 1 : 1e-4; double eps = ddepth <= CV_32S ? 1 : 1e-4;
OCL_EXPECT_MATS_NEAR(dst, eps) OCL_EXPECT_MATS_NEAR(dst, eps);
} }
} }
@ -1698,7 +1706,7 @@ OCL_TEST_P(ReduceMax, Mat)
OCL_OFF(cv::reduce(src_roi, dst_roi, dim, CV_REDUCE_MAX, dtype)); OCL_OFF(cv::reduce(src_roi, dst_roi, dim, CV_REDUCE_MAX, dtype));
OCL_ON(cv::reduce(usrc_roi, udst_roi, dim, CV_REDUCE_MAX, dtype)); OCL_ON(cv::reduce(usrc_roi, udst_roi, dim, CV_REDUCE_MAX, dtype));
OCL_EXPECT_MATS_NEAR(dst, 0) OCL_EXPECT_MATS_NEAR(dst, 0);
} }
} }
@ -1713,7 +1721,7 @@ OCL_TEST_P(ReduceMin, Mat)
OCL_OFF(cv::reduce(src_roi, dst_roi, dim, CV_REDUCE_MIN, dtype)); OCL_OFF(cv::reduce(src_roi, dst_roi, dim, CV_REDUCE_MIN, dtype));
OCL_ON(cv::reduce(usrc_roi, udst_roi, dim, CV_REDUCE_MIN, dtype)); OCL_ON(cv::reduce(usrc_roi, udst_roi, dim, CV_REDUCE_MIN, dtype));
OCL_EXPECT_MATS_NEAR(dst, 0) OCL_EXPECT_MATS_NEAR(dst, 0);
} }
} }
@ -1729,7 +1737,7 @@ OCL_TEST_P(ReduceAvg, Mat)
OCL_ON(cv::reduce(usrc_roi, udst_roi, dim, CV_REDUCE_AVG, dtype)); OCL_ON(cv::reduce(usrc_roi, udst_roi, dim, CV_REDUCE_AVG, dtype));
double eps = ddepth <= CV_32S ? 1 : 5e-6; double eps = ddepth <= CV_32S ? 1 : 5e-6;
OCL_EXPECT_MATS_NEAR(dst, eps) OCL_EXPECT_MATS_NEAR(dst, eps);
} }
} }

View File

@ -54,16 +54,16 @@ namespace ocl {
//////////////////////////////////////// Merge /////////////////////////////////////////////// //////////////////////////////////////// Merge ///////////////////////////////////////////////
PARAM_TEST_CASE(Merge, MatDepth, Channels, bool) PARAM_TEST_CASE(Merge, MatDepth, int, bool)
{ {
int depth, cn; int depth, nsrc;
bool use_roi; bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src1) TEST_DECLARE_INPUT_PARAMETER(src1);
TEST_DECLARE_INPUT_PARAMETER(src2) TEST_DECLARE_INPUT_PARAMETER(src2);
TEST_DECLARE_INPUT_PARAMETER(src3) TEST_DECLARE_INPUT_PARAMETER(src3);
TEST_DECLARE_INPUT_PARAMETER(src4) TEST_DECLARE_INPUT_PARAMETER(src4);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
std::vector<Mat> src_roi; std::vector<Mat> src_roi;
std::vector<UMat> usrc_roi; std::vector<UMat> usrc_roi;
@ -71,10 +71,15 @@ PARAM_TEST_CASE(Merge, MatDepth, Channels, bool)
virtual void SetUp() virtual void SetUp()
{ {
depth = GET_PARAM(0); depth = GET_PARAM(0);
cn = GET_PARAM(1); nsrc = GET_PARAM(1);
use_roi = GET_PARAM(2); use_roi = GET_PARAM(2);
CV_Assert(cn >= 1 && cn <= 4); CV_Assert(nsrc >= 1 && nsrc <= 4);
}
int type()
{
return CV_MAKE_TYPE(depth, randomInt(1, 3));
} }
void generateTestData() void generateTestData()
@ -83,34 +88,39 @@ PARAM_TEST_CASE(Merge, MatDepth, Channels, bool)
{ {
Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0); Border src1Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src1, src1_roi, roiSize, src1Border, depth, 2, 11); randomSubMat(src1, src1_roi, roiSize, src1Border, type(), 2, 11);
Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0); Border src2Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src2, src2_roi, roiSize, src2Border, depth, -1540, 1740); randomSubMat(src2, src2_roi, roiSize, src2Border, type(), -1540, 1740);
Border src3Border = randomBorder(0, use_roi ? MAX_VALUE : 0); Border src3Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src3, src3_roi, roiSize, src3Border, depth, -1540, 1740); randomSubMat(src3, src3_roi, roiSize, src3Border, type(), -1540, 1740);
Border src4Border = randomBorder(0, use_roi ? MAX_VALUE : 0); Border src4Border = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(src4, src4_roi, roiSize, src4Border, depth, -1540, 1740); randomSubMat(src4, src4_roi, roiSize, src4Border, type(), -1540, 1740);
} }
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0); UMAT_UPLOAD_INPUT_PARAMETER(src1);
randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, cn), 5, 16); UMAT_UPLOAD_INPUT_PARAMETER(src2);
UMAT_UPLOAD_INPUT_PARAMETER(src3);
UMAT_UPLOAD_INPUT_PARAMETER(src1) UMAT_UPLOAD_INPUT_PARAMETER(src4);
UMAT_UPLOAD_INPUT_PARAMETER(src2)
UMAT_UPLOAD_INPUT_PARAMETER(src3)
UMAT_UPLOAD_INPUT_PARAMETER(src4)
UMAT_UPLOAD_OUTPUT_PARAMETER(dst)
src_roi.push_back(src1_roi), usrc_roi.push_back(usrc1_roi); src_roi.push_back(src1_roi), usrc_roi.push_back(usrc1_roi);
if (cn >= 2) if (nsrc >= 2)
src_roi.push_back(src2_roi), usrc_roi.push_back(usrc2_roi); src_roi.push_back(src2_roi), usrc_roi.push_back(usrc2_roi);
if (cn >= 3) if (nsrc >= 3)
src_roi.push_back(src3_roi), usrc_roi.push_back(usrc3_roi); src_roi.push_back(src3_roi), usrc_roi.push_back(usrc3_roi);
if (cn >= 4) if (nsrc >= 4)
src_roi.push_back(src4_roi), usrc_roi.push_back(usrc4_roi); src_roi.push_back(src4_roi), usrc_roi.push_back(usrc4_roi);
int dcn = 0;
for (int i = 0; i < nsrc; ++i)
dcn += src_roi[i].channels();
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, dcn), 5, 16);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
void Near(double threshold = 0.) void Near(double threshold = 0.)
@ -139,11 +149,11 @@ PARAM_TEST_CASE(Split, MatType, Channels, bool)
int depth, cn; int depth, cn;
bool use_roi; bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst1) TEST_DECLARE_OUTPUT_PARAMETER(dst1);
TEST_DECLARE_OUTPUT_PARAMETER(dst2) TEST_DECLARE_OUTPUT_PARAMETER(dst2);
TEST_DECLARE_OUTPUT_PARAMETER(dst3) TEST_DECLARE_OUTPUT_PARAMETER(dst3);
TEST_DECLARE_OUTPUT_PARAMETER(dst4) TEST_DECLARE_OUTPUT_PARAMETER(dst4);
std::vector<Mat> dst_roi, dst; std::vector<Mat> dst_roi, dst;
std::vector<UMat> udst_roi, udst; std::vector<UMat> udst_roi, udst;
@ -177,11 +187,11 @@ PARAM_TEST_CASE(Split, MatType, Channels, bool)
randomSubMat(dst4, dst4_roi, roiSize, dst4Border, depth, -1540, 1740); randomSubMat(dst4, dst4_roi, roiSize, dst4Border, depth, -1540, 1740);
} }
UMAT_UPLOAD_INPUT_PARAMETER(src) UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst1) UMAT_UPLOAD_OUTPUT_PARAMETER(dst1);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst2) UMAT_UPLOAD_OUTPUT_PARAMETER(dst2);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst3) UMAT_UPLOAD_OUTPUT_PARAMETER(dst3);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst4) UMAT_UPLOAD_OUTPUT_PARAMETER(dst4);
dst_roi.push_back(dst1_roi), udst_roi.push_back(udst1_roi), dst_roi.push_back(dst1_roi), udst_roi.push_back(udst1_roi),
dst.push_back(dst1), udst.push_back(udst1); dst.push_back(dst1), udst.push_back(udst1);
@ -221,14 +231,14 @@ PARAM_TEST_CASE(MixChannels, MatType, bool)
int depth; int depth;
bool use_roi; bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src1) TEST_DECLARE_INPUT_PARAMETER(src1);
TEST_DECLARE_INPUT_PARAMETER(src2) TEST_DECLARE_INPUT_PARAMETER(src2);
TEST_DECLARE_INPUT_PARAMETER(src3) TEST_DECLARE_INPUT_PARAMETER(src3);
TEST_DECLARE_INPUT_PARAMETER(src4) TEST_DECLARE_INPUT_PARAMETER(src4);
TEST_DECLARE_OUTPUT_PARAMETER(dst1) TEST_DECLARE_OUTPUT_PARAMETER(dst1);
TEST_DECLARE_OUTPUT_PARAMETER(dst2) TEST_DECLARE_OUTPUT_PARAMETER(dst2);
TEST_DECLARE_OUTPUT_PARAMETER(dst3) TEST_DECLARE_OUTPUT_PARAMETER(dst3);
TEST_DECLARE_OUTPUT_PARAMETER(dst4) TEST_DECLARE_OUTPUT_PARAMETER(dst4);
std::vector<Mat> src_roi, dst_roi, dst; std::vector<Mat> src_roi, dst_roi, dst;
std::vector<UMat> usrc_roi, udst_roi, udst; std::vector<UMat> usrc_roi, udst_roi, udst;
@ -287,15 +297,15 @@ PARAM_TEST_CASE(MixChannels, MatType, bool)
randomSubMat(dst4, dst4_roi, roiSize, dst4Border, type(), -1540, 1740); randomSubMat(dst4, dst4_roi, roiSize, dst4Border, type(), -1540, 1740);
} }
UMAT_UPLOAD_INPUT_PARAMETER(src1) UMAT_UPLOAD_INPUT_PARAMETER(src1);
UMAT_UPLOAD_INPUT_PARAMETER(src2) UMAT_UPLOAD_INPUT_PARAMETER(src2);
UMAT_UPLOAD_INPUT_PARAMETER(src3) UMAT_UPLOAD_INPUT_PARAMETER(src3);
UMAT_UPLOAD_INPUT_PARAMETER(src4) UMAT_UPLOAD_INPUT_PARAMETER(src4);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst1) UMAT_UPLOAD_OUTPUT_PARAMETER(dst1);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst2) UMAT_UPLOAD_OUTPUT_PARAMETER(dst2);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst3) UMAT_UPLOAD_OUTPUT_PARAMETER(dst3);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst4) UMAT_UPLOAD_OUTPUT_PARAMETER(dst4);
int nsrc = randomInt(1, 5), ndst = randomInt(1, 5); int nsrc = randomInt(1, 5), ndst = randomInt(1, 5);
@ -360,8 +370,8 @@ PARAM_TEST_CASE(InsertChannel, MatDepth, Channels, bool)
int depth, cn, coi; int depth, cn, coi;
bool use_roi; bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -381,8 +391,8 @@ PARAM_TEST_CASE(InsertChannel, MatDepth, Channels, bool)
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0); Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, cn), 5, 16); randomSubMat(dst, dst_roi, roiSize, dstBorder, CV_MAKE_TYPE(depth, cn), 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src) UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst) UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
}; };
@ -406,8 +416,8 @@ PARAM_TEST_CASE(ExtractChannel, MatDepth, Channels, bool)
int depth, cn, coi; int depth, cn, coi;
bool use_roi; bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -427,8 +437,8 @@ PARAM_TEST_CASE(ExtractChannel, MatDepth, Channels, bool)
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0); Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, depth, 5, 16); randomSubMat(dst, dst_roi, roiSize, dstBorder, depth, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src) UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst) UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
}; };
@ -447,7 +457,7 @@ OCL_TEST_P(ExtractChannel, Accuracy)
//////////////////////////////////////// Instantiation /////////////////////////////////////////////// //////////////////////////////////////// Instantiation ///////////////////////////////////////////////
OCL_INSTANTIATE_TEST_CASE_P(Channels, Merge, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool())); OCL_INSTANTIATE_TEST_CASE_P(Channels, Merge, Combine(OCL_ALL_DEPTHS, Values(1, 2, 3, 4), Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Channels, Split, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool())); OCL_INSTANTIATE_TEST_CASE_P(Channels, Split, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Channels, MixChannels, Combine(OCL_ALL_DEPTHS, Bool())); OCL_INSTANTIATE_TEST_CASE_P(Channels, MixChannels, Combine(OCL_ALL_DEPTHS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(Channels, InsertChannel, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool())); OCL_INSTANTIATE_TEST_CASE_P(Channels, InsertChannel, Combine(OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));

View File

@ -60,8 +60,8 @@ PARAM_TEST_CASE(Dft, cv::Size, MatDepth, bool, bool, bool, bool)
int dft_flags, depth; int dft_flags, depth;
bool inplace; bool inplace;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -106,9 +106,9 @@ PARAM_TEST_CASE(MulSpectrums, bool, bool)
{ {
bool ccorr, useRoi; bool ccorr, useRoi;
TEST_DECLARE_INPUT_PARAMETER(src1) TEST_DECLARE_INPUT_PARAMETER(src1);
TEST_DECLARE_INPUT_PARAMETER(src2) TEST_DECLARE_INPUT_PARAMETER(src2);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -129,9 +129,9 @@ PARAM_TEST_CASE(MulSpectrums, bool, bool)
Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0); Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, srcRoiSize, dstBorder, CV_32FC2, 5, 16); randomSubMat(dst, dst_roi, srcRoiSize, dstBorder, CV_32FC2, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src1) UMAT_UPLOAD_INPUT_PARAMETER(src1);
UMAT_UPLOAD_INPUT_PARAMETER(src2) UMAT_UPLOAD_INPUT_PARAMETER(src2);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst) UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
}; };

View File

@ -67,10 +67,10 @@ PARAM_TEST_CASE(Gemm,
double alpha, beta; double alpha, beta;
TEST_DECLARE_INPUT_PARAMETER(A) TEST_DECLARE_INPUT_PARAMETER(A);
TEST_DECLARE_INPUT_PARAMETER(B) TEST_DECLARE_INPUT_PARAMETER(B);
TEST_DECLARE_INPUT_PARAMETER(C) TEST_DECLARE_INPUT_PARAMETER(C);
TEST_DECLARE_OUTPUT_PARAMETER(D) TEST_DECLARE_OUTPUT_PARAMETER(D);
virtual void SetUp() virtual void SetUp()
{ {
@ -119,10 +119,10 @@ PARAM_TEST_CASE(Gemm,
alpha = randomDouble(-4, 4); alpha = randomDouble(-4, 4);
beta = randomDouble(-4, 4); beta = randomDouble(-4, 4);
UMAT_UPLOAD_INPUT_PARAMETER(A) UMAT_UPLOAD_INPUT_PARAMETER(A);
UMAT_UPLOAD_INPUT_PARAMETER(B) UMAT_UPLOAD_INPUT_PARAMETER(B);
UMAT_UPLOAD_INPUT_PARAMETER(C) UMAT_UPLOAD_INPUT_PARAMETER(C);
UMAT_UPLOAD_OUTPUT_PARAMETER(D) UMAT_UPLOAD_OUTPUT_PARAMETER(D);
} }
}; };

View File

@ -59,8 +59,8 @@ PARAM_TEST_CASE(ConvertTo, MatDepth, MatDepth, Channels, bool)
int src_depth, cn, dstType; int src_depth, cn, dstType;
bool use_roi; bool use_roi;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -80,8 +80,8 @@ PARAM_TEST_CASE(ConvertTo, MatDepth, MatDepth, Channels, bool)
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0); Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, dstType, 5, 16); randomSubMat(dst, dst_roi, roiSize, dstBorder, dstType, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src) UMAT_UPLOAD_INPUT_PARAMETER(src);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst) UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
}; };
@ -108,9 +108,9 @@ PARAM_TEST_CASE(CopyTo, MatDepth, Channels, bool, bool)
int depth, cn; int depth, cn;
bool use_roi, use_mask; bool use_roi, use_mask;
TEST_DECLARE_INPUT_PARAMETER(src) TEST_DECLARE_INPUT_PARAMETER(src);
TEST_DECLARE_INPUT_PARAMETER(mask) TEST_DECLARE_INPUT_PARAMETER(mask);
TEST_DECLARE_OUTPUT_PARAMETER(dst) TEST_DECLARE_OUTPUT_PARAMETER(dst);
virtual void SetUp() virtual void SetUp()
{ {
@ -139,10 +139,10 @@ PARAM_TEST_CASE(CopyTo, MatDepth, Channels, bool, bool)
Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0); Border dstBorder = randomBorder(0, use_roi ? MAX_VALUE : 0);
randomSubMat(dst, dst_roi, roiSize, dstBorder, type, 5, 16); randomSubMat(dst, dst_roi, roiSize, dstBorder, type, 5, 16);
UMAT_UPLOAD_INPUT_PARAMETER(src) UMAT_UPLOAD_INPUT_PARAMETER(src);
if (use_mask) if (use_mask)
UMAT_UPLOAD_INPUT_PARAMETER(mask) UMAT_UPLOAD_INPUT_PARAMETER(mask);
UMAT_UPLOAD_OUTPUT_PARAMETER(dst) UMAT_UPLOAD_OUTPUT_PARAMETER(dst);
} }
}; };
@ -169,7 +169,7 @@ OCL_TEST_P(CopyTo, Accuracy)
} }
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, ConvertTo, Combine( OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, ConvertTo, Combine(
OCL_ALL_DEPTHS, OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool())); OCL_ALL_DEPTHS, OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool()));
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, CopyTo, Combine( OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, CopyTo, Combine(
OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool(), Bool())); OCL_ALL_DEPTHS, OCL_ALL_CHANNELS, Bool(), Bool()));

View File

@ -380,6 +380,40 @@ TEST(Core_InputOutput, write_read_consistency) { Core_IOTest test; test.safe_run
extern void testFormatter(); extern void testFormatter();
struct UserDefinedType
{
int a;
float b;
};
static inline bool operator==(const UserDefinedType &x,
const UserDefinedType &y) {
return (x.a == y.a) && (x.b == y.b);
}
static inline void write(FileStorage &fs,
const String&,
const UserDefinedType &value)
{
fs << "{:" << "a" << value.a << "b" << value.b << "}";
}
static inline void read(const FileNode& node,
UserDefinedType& value,
const UserDefinedType& default_value
= UserDefinedType()) {
if(node.empty())
{
value = default_value;
}
else
{
node["a"] >> value.a;
node["b"] >> value.b;
}
}
class CV_MiscIOTest : public cvtest::BaseTest class CV_MiscIOTest : public cvtest::BaseTest
{ {
public: public:
@ -393,11 +427,14 @@ protected:
string fname = cv::tempfile(".xml"); string fname = cv::tempfile(".xml");
vector<int> mi, mi2, mi3, mi4; vector<int> mi, mi2, mi3, mi4;
vector<Mat> mv, mv2, mv3, mv4; vector<Mat> mv, mv2, mv3, mv4;
vector<UserDefinedType> vudt, vudt2, vudt3, vudt4;
Mat m(10, 9, CV_32F); Mat m(10, 9, CV_32F);
Mat empty; Mat empty;
UserDefinedType udt = { 8, 3.3f };
randu(m, 0, 1); randu(m, 0, 1);
mi3.push_back(5); mi3.push_back(5);
mv3.push_back(m); mv3.push_back(m);
vudt3.push_back(udt);
Point_<float> p1(1.1f, 2.2f), op1; Point_<float> p1(1.1f, 2.2f), op1;
Point3i p2(3, 4, 5), op2; Point3i p2(3, 4, 5), op2;
Size s1(6, 7), os1; Size s1(6, 7), os1;
@ -412,6 +449,8 @@ protected:
fs << "mv" << mv; fs << "mv" << mv;
fs << "mi3" << mi3; fs << "mi3" << mi3;
fs << "mv3" << mv3; fs << "mv3" << mv3;
fs << "vudt" << vudt;
fs << "vudt3" << vudt3;
fs << "empty" << empty; fs << "empty" << empty;
fs << "p1" << p1; fs << "p1" << p1;
fs << "p2" << p2; fs << "p2" << p2;
@ -428,6 +467,8 @@ protected:
fs["mv"] >> mv2; fs["mv"] >> mv2;
fs["mi3"] >> mi4; fs["mi3"] >> mi4;
fs["mv3"] >> mv4; fs["mv3"] >> mv4;
fs["vudt"] >> vudt2;
fs["vudt3"] >> vudt4;
fs["empty"] >> empty; fs["empty"] >> empty;
fs["p1"] >> op1; fs["p1"] >> op1;
fs["p2"] >> op2; fs["p2"] >> op2;
@ -442,6 +483,8 @@ protected:
CV_Assert( norm(mi3, mi4, CV_C) == 0 ); CV_Assert( norm(mi3, mi4, CV_C) == 0 );
CV_Assert( mv4.size() == 1 ); CV_Assert( mv4.size() == 1 );
double n = norm(mv3[0], mv4[0], CV_C); double n = norm(mv3[0], mv4[0], CV_C);
CV_Assert( vudt2.empty() );
CV_Assert( vudt3 == vudt4 );
CV_Assert( n == 0 ); CV_Assert( n == 0 );
CV_Assert( op1 == p1 ); CV_Assert( op1 == p1 );
CV_Assert( op2 == p2 ); CV_Assert( op2 == p2 );

View File

@ -795,4 +795,176 @@ TEST(UMat, ReadBufferRect)
EXPECT_MAT_NEAR(t, t2, 0); EXPECT_MAT_NEAR(t, t2, 0);
} }
// Use iGPU or OPENCV_OPENCL_DEVICE=:CPU: to catch problem
TEST(UMat, DISABLED_synchronization_map_unmap)
{
class TestParallelLoopBody : public cv::ParallelLoopBody
{
UMat u_;
public:
TestParallelLoopBody(const UMat& u) : u_(u) { }
void operator() (const cv::Range& range) const
{
printf("range: %d, %d -- begin\n", range.start, range.end);
for (int i = 0; i < 10; i++)
{
printf("%d: %d map...\n", range.start, i);
Mat m = u_.getMat(cv::ACCESS_READ);
printf("%d: %d unmap...\n", range.start, i);
m.release();
}
printf("range: %d, %d -- end\n", range.start, range.end);
}
};
try
{
UMat u(1000, 1000, CV_32FC1);
parallel_for_(cv::Range(0, 2), TestParallelLoopBody(u));
}
catch (const cv::Exception& e)
{
FAIL() << "Exception: " << e.what();
ADD_FAILURE();
}
catch (...)
{
FAIL() << "Exception!";
}
}
} } // namespace cvtest::ocl } } // namespace cvtest::ocl
TEST(UMat, DISABLED_bug_with_unmap)
{
for (int i = 0; i < 20; i++)
{
try
{
Mat m = Mat(1000, 1000, CV_8UC1);
UMat u = m.getUMat(ACCESS_READ);
UMat dst;
add(u, Scalar::all(0), dst); // start async operation
u.release();
m.release();
}
catch (const cv::Exception& e)
{
printf("i = %d... %s\n", i, e.what());
ADD_FAILURE();
}
catch (...)
{
printf("i = %d...\n", i);
ADD_FAILURE();
}
}
}
TEST(UMat, DISABLED_bug_with_unmap_in_class)
{
class Logic
{
public:
Logic() {}
void processData(InputArray input)
{
Mat m = input.getMat();
{
Mat dst;
m.convertTo(dst, CV_32FC1);
// some additional CPU-based per-pixel processing into dst
intermediateResult = dst.getUMat(ACCESS_READ);
std::cout << "data processed..." << std::endl;
} // problem is here: dst::~Mat()
std::cout << "leave ProcessData()" << std::endl;
}
UMat getResult() const { return intermediateResult; }
protected:
UMat intermediateResult;
};
try
{
Mat m = Mat(1000, 1000, CV_8UC1);
Logic l;
l.processData(m);
UMat result = l.getResult();
}
catch (const cv::Exception& e)
{
printf("exception... %s\n", e.what());
ADD_FAILURE();
}
catch (...)
{
printf("exception... \n");
ADD_FAILURE();
}
}
TEST(UMat, Test_same_behaviour_read_and_read)
{
bool exceptionDetected = false;
try
{
UMat u(Size(10, 10), CV_8UC1);
Mat m = u.getMat(ACCESS_READ);
UMat dst;
add(u, Scalar::all(1), dst);
}
catch (...)
{
exceptionDetected = true;
}
ASSERT_FALSE(exceptionDetected); // no data race, 2+ reads are valid
}
// VP: this test (and probably others from same_behaviour series) is not valid in my opinion.
TEST(UMat, DISABLED_Test_same_behaviour_read_and_write)
{
bool exceptionDetected = false;
try
{
UMat u(Size(10, 10), CV_8UC1);
Mat m = u.getMat(ACCESS_READ);
add(u, Scalar::all(1), u);
}
catch (...)
{
exceptionDetected = true;
}
ASSERT_TRUE(exceptionDetected); // data race
}
TEST(UMat, DISABLED_Test_same_behaviour_write_and_read)
{
bool exceptionDetected = false;
try
{
UMat u(Size(10, 10), CV_8UC1);
Mat m = u.getMat(ACCESS_WRITE);
UMat dst;
add(u, Scalar::all(1), dst);
}
catch (...)
{
exceptionDetected = true;
}
ASSERT_TRUE(exceptionDetected); // data race
}
TEST(UMat, DISABLED_Test_same_behaviour_write_and_write)
{
bool exceptionDetected = false;
try
{
UMat u(Size(10, 10), CV_8UC1);
Mat m = u.getMat(ACCESS_WRITE);
add(u, Scalar::all(1), u);
}
catch (...)
{
exceptionDetected = true;
}
ASSERT_TRUE(exceptionDetected); // data race
}

View File

@ -163,7 +163,7 @@ namespace cv { namespace cuda { namespace device
{ {
//need only weight if fit is found //need only weight if fit is found
float weight = alpha1 * gmm_weight(mode * frame.rows + y, x) + prune; float weight = alpha1 * gmm_weight(mode * frame.rows + y, x) + prune;
int swap_count = 0;
//fit not found yet //fit not found yet
if (!fitsPDF) if (!fitsPDF)
{ {
@ -214,6 +214,7 @@ namespace cv { namespace cuda { namespace device
if (weight < gmm_weight((i - 1) * frame.rows + y, x)) if (weight < gmm_weight((i - 1) * frame.rows + y, x))
break; break;
swap_count++;
//swap one up //swap one up
swap(gmm_weight, x, y, i - 1, frame.rows); swap(gmm_weight, x, y, i - 1, frame.rows);
swap(gmm_variance, x, y, i - 1, frame.rows); swap(gmm_variance, x, y, i - 1, frame.rows);
@ -231,7 +232,7 @@ namespace cv { namespace cuda { namespace device
nmodes--; nmodes--;
} }
gmm_weight(mode * frame.rows + y, x) = weight; //update weight by the calculated value gmm_weight((mode - swap_count) * frame.rows + y, x) = weight; //update weight by the calculated value
totalWeight += weight; totalWeight += weight;
} }

View File

@ -69,7 +69,7 @@ Computes the descriptors for a set of keypoints detected in an image (first vari
:param keypoints: Input collection of keypoints. Keypoints for which a descriptor cannot be computed are removed. Sometimes new keypoints can be added, for example: ``SIFT`` duplicates keypoint with several dominant orientations (for each orientation). :param keypoints: Input collection of keypoints. Keypoints for which a descriptor cannot be computed are removed. Sometimes new keypoints can be added, for example: ``SIFT`` duplicates keypoint with several dominant orientations (for each orientation).
:param descriptors: Computed descriptors. In the second variant of the method ``descriptors[i]`` are descriptors computed for a ``keypoints[i]`. Row ``j`` is the ``keypoints`` (or ``keypoints[i]``) is the descriptor for keypoint ``j``-th keypoint. :param descriptors: Computed descriptors. In the second variant of the method ``descriptors[i]`` are descriptors computed for a ``keypoints[i]``. Row ``j`` is the ``keypoints`` (or ``keypoints[i]``) is the descriptor for keypoint ``j``-th keypoint.
DescriptorExtractor::create DescriptorExtractor::create

View File

@ -249,7 +249,7 @@ Brute-force matcher constructor.
:param normType: One of ``NORM_L1``, ``NORM_L2``, ``NORM_HAMMING``, ``NORM_HAMMING2``. ``L1`` and ``L2`` norms are preferable choices for SIFT and SURF descriptors, ``NORM_HAMMING`` should be used with ORB, BRISK and BRIEF, ``NORM_HAMMING2`` should be used with ORB when ``WTA_K==3`` or ``4`` (see ORB::ORB constructor description). :param normType: One of ``NORM_L1``, ``NORM_L2``, ``NORM_HAMMING``, ``NORM_HAMMING2``. ``L1`` and ``L2`` norms are preferable choices for SIFT and SURF descriptors, ``NORM_HAMMING`` should be used with ORB, BRISK and BRIEF, ``NORM_HAMMING2`` should be used with ORB when ``WTA_K==3`` or ``4`` (see ORB::ORB constructor description).
:param crossCheck: If it is false, this is will be default BFMatcher behaviour when it finds the k nearest neighbors for each query descriptor. If ``crossCheck==true``, then the ``knnMatch()`` method with ``k=1`` will only return pairs ``(i,j)`` such that for ``i-th`` query descriptor the ``j-th`` descriptor in the matcher's collection is the nearest and vice versa, i.e. the ``BFMathcher`` will only return consistent pairs. Such technique usually produces best results with minimal number of outliers when there are enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper. :param crossCheck: If it is false, this is will be default BFMatcher behaviour when it finds the k nearest neighbors for each query descriptor. If ``crossCheck==true``, then the ``knnMatch()`` method with ``k=1`` will only return pairs ``(i,j)`` such that for ``i-th`` query descriptor the ``j-th`` descriptor in the matcher's collection is the nearest and vice versa, i.e. the ``BFMatcher`` will only return consistent pairs. Such technique usually produces best results with minimal number of outliers when there are enough matches. This is alternative to the ratio test, used by D. Lowe in SIFT paper.
FlannBasedMatcher FlannBasedMatcher

View File

@ -616,14 +616,14 @@ protected:
}; };
class CV_EXPORTS DenseFeatureDetector : public FeatureDetector class CV_EXPORTS_W DenseFeatureDetector : public FeatureDetector
{ {
public: public:
explicit DenseFeatureDetector( float initFeatureScale=1.f, int featureScaleLevels=1, CV_WRAP explicit DenseFeatureDetector( float initFeatureScale=1.f, int featureScaleLevels=1,
float featureScaleMul=0.1f, float featureScaleMul=0.1f,
int initXyStep=6, int initImgBound=0, int initXyStep=6, int initImgBound=0,
bool varyXyStepWithScale=true, bool varyXyStepWithScale=true,
bool varyImgBoundWithScale=false ); bool varyImgBoundWithScale=false );
AlgorithmInfo* info() const; AlgorithmInfo* info() const;
protected: protected:

View File

@ -123,7 +123,7 @@ OCL_PERF_TEST_P(BruteForceMatcherFixture, RadiusMatch, ::testing::Combine(OCL_PE
SANITY_CHECK_MATCHES(matches1, 1e-3); SANITY_CHECK_MATCHES(matches1, 1e-3);
} }
}//ocl } // ocl
}//cvtest } // cvtest
#endif //HAVE_OPENCL #endif // HAVE_OPENCL

View File

@ -0,0 +1,50 @@
#include "perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL
namespace cvtest {
namespace ocl {
enum { TYPE_5_8 =FastFeatureDetector::TYPE_5_8, TYPE_7_12 = FastFeatureDetector::TYPE_7_12, TYPE_9_16 = FastFeatureDetector::TYPE_9_16 };
CV_ENUM(FastType, TYPE_5_8, TYPE_7_12)
typedef std::tr1::tuple<string, FastType> File_Type_t;
typedef TestBaseWithParam<File_Type_t> FASTFixture;
#define FAST_IMAGES \
"cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png",\
"stitching/a3.png"
OCL_PERF_TEST_P(FASTFixture, FastDetect, testing::Combine(
testing::Values(FAST_IMAGES),
FastType::all()
))
{
string filename = getDataPath(get<0>(GetParam()));
int type = get<1>(GetParam());
Mat mframe = imread(filename, IMREAD_GRAYSCALE);
if (mframe.empty())
FAIL() << "Unable to load source image " << filename;
UMat frame;
mframe.copyTo(frame);
declare.in(frame);
Ptr<FeatureDetector> fd = Algorithm::create<FeatureDetector>("Feature2D.FAST");
ASSERT_FALSE( fd.empty() );
fd->set("threshold", 20);
fd->set("nonmaxSuppression", true);
fd->set("type", type);
vector<KeyPoint> points;
OCL_TEST_CYCLE() fd->detect(frame, points);
SANITY_CHECK_KEYPOINTS(points);
}
} // ocl
} // cvtest
#endif // HAVE_OPENCL

View File

@ -0,0 +1,86 @@
#include "perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL
namespace cvtest {
namespace ocl {
typedef ::perf::TestBaseWithParam<std::string> ORBFixture;
#define ORB_IMAGES OCL_PERF_ENUM("cv/detectors_descriptors_evaluation/images_datasets/leuven/img1.png", "stitching/a3.png")
OCL_PERF_TEST_P(ORBFixture, ORB_Detect, ORB_IMAGES)
{
string filename = getDataPath(GetParam());
Mat mframe = imread(filename, IMREAD_GRAYSCALE);
if (mframe.empty())
FAIL() << "Unable to load source image " << filename;
UMat frame, mask;
mframe.copyTo(frame);
declare.in(frame);
ORB detector(1500, 1.3f, 1);
vector<KeyPoint> points;
OCL_TEST_CYCLE() detector(frame, mask, points);
std::sort(points.begin(), points.end(), comparators::KeypointGreater());
SANITY_CHECK_KEYPOINTS(points, 1e-5);
}
OCL_PERF_TEST_P(ORBFixture, ORB_Extract, ORB_IMAGES)
{
string filename = getDataPath(GetParam());
Mat mframe = imread(filename, IMREAD_GRAYSCALE);
if (mframe.empty())
FAIL() << "Unable to load source image " << filename;
UMat mask, frame;
mframe.copyTo(frame);
declare.in(frame);
ORB detector(1500, 1.3f, 1);
vector<KeyPoint> points;
detector(frame, mask, points);
std::sort(points.begin(), points.end(), comparators::KeypointGreater());
UMat descriptors;
OCL_TEST_CYCLE() detector(frame, mask, points, descriptors, true);
SANITY_CHECK(descriptors);
}
OCL_PERF_TEST_P(ORBFixture, ORB_Full, ORB_IMAGES)
{
string filename = getDataPath(GetParam());
Mat mframe = imread(filename, IMREAD_GRAYSCALE);
if (mframe.empty())
FAIL() << "Unable to load source image " << filename;
UMat mask, frame;
mframe.copyTo(frame);
declare.in(frame);
ORB detector(1500, 1.3f, 1);
vector<KeyPoint> points;
UMat descriptors;
OCL_TEST_CYCLE() detector(frame, mask, points, descriptors, false);
::perf::sort(points, descriptors);
SANITY_CHECK_KEYPOINTS(points, 1e-5);
SANITY_CHECK(descriptors);
}
} // ocl
} // cvtest
#endif // HAVE_OPENCL

View File

@ -758,10 +758,13 @@ private:
for (int k=0; k<indices_length; ++k) { for (int k=0; k<indices_length; ++k) {
if (belongs_to[k]==j) { if (belongs_to[k]==j) {
belongs_to[k] = i; // for cluster j, we move the furthest element from the center to the empty cluster i
count[j]--; if ( distance_(dataset_[indices[k]], dcenters[j], veclen_) == radiuses[j] ) {
count[i]++; belongs_to[k] = i;
break; count[j]--;
count[i]++;
break;
}
} }
} }
converged = false; converged = false;

View File

@ -483,7 +483,7 @@ VideoWriter constructors
:param filename: Name of the output video file. :param filename: Name of the output video file.
:param fourcc: 4-character code of codec used to compress the frames. For example, ``CV_FOURCC('P','I','M,'1')`` is a MPEG-1 codec, ``CV_FOURCC('M','J','P','G')`` is a motion-jpeg codec etc. List of codes can be obtained at `Video Codecs by FOURCC <http://www.fourcc.org/codecs.php>`_ page. :param fourcc: 4-character code of codec used to compress the frames. For example, ``CV_FOURCC('P','I','M','1')`` is a MPEG-1 codec, ``CV_FOURCC('M','J','P','G')`` is a motion-jpeg codec etc. List of codes can be obtained at `Video Codecs by FOURCC <http://www.fourcc.org/codecs.php>`_ page.
:param fps: Framerate of the created video stream. :param fps: Framerate of the created video stream.

View File

@ -215,12 +215,14 @@ enum { IMREAD_UNCHANGED = -1, // 8bit, color or not
IMREAD_ANYCOLOR = 4 // ?, any color IMREAD_ANYCOLOR = 4 // ?, any color
}; };
enum { IMWRITE_JPEG_QUALITY = 1, enum { IMWRITE_JPEG_QUALITY = 1,
IMWRITE_PNG_COMPRESSION = 16, IMWRITE_JPEG_PROGRESSIVE = 2,
IMWRITE_PNG_STRATEGY = 17, IMWRITE_JPEG_OPTIMIZE = 3,
IMWRITE_PNG_BILEVEL = 18, IMWRITE_PNG_COMPRESSION = 16,
IMWRITE_PXM_BINARY = 32, IMWRITE_PNG_STRATEGY = 17,
IMWRITE_WEBP_QUALITY = 64 IMWRITE_PNG_BILEVEL = 18,
IMWRITE_PXM_BINARY = 32,
IMWRITE_WEBP_QUALITY = 64
}; };
enum { IMWRITE_PNG_STRATEGY_DEFAULT = 0, enum { IMWRITE_PNG_STRATEGY_DEFAULT = 0,

View File

@ -220,6 +220,8 @@ CVAPI(CvMat*) cvLoadImageM( const char* filename, int iscolor CV_DEFAULT(CV_LOAD
enum enum
{ {
CV_IMWRITE_JPEG_QUALITY =1, CV_IMWRITE_JPEG_QUALITY =1,
CV_IMWRITE_JPEG_PROGRESSIVE =2,
CV_IMWRITE_JPEG_OPTIMIZE =3,
CV_IMWRITE_PNG_COMPRESSION =16, CV_IMWRITE_PNG_COMPRESSION =16,
CV_IMWRITE_PNG_STRATEGY =17, CV_IMWRITE_PNG_STRATEGY =17,
CV_IMWRITE_PNG_BILEVEL =18, CV_IMWRITE_PNG_BILEVEL =18,
@ -463,6 +465,8 @@ enum
CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR = 8006, CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR = 8006,
CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL = 8007, CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL = 8007,
CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR = 8008, CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR = 8008,
CV_CAP_PROP_ANDROID_EXPOSE_LOCK = 8009,
CV_CAP_PROP_ANDROID_WHITEBALANCE_LOCK = 8010,
// Properties of cameras available through AVFOUNDATION interface // Properties of cameras available through AVFOUNDATION interface
CV_CAP_PROP_IOS_DEVICE_FOCUS = 9001, CV_CAP_PROP_IOS_DEVICE_FOCUS = 9001,
@ -543,6 +547,7 @@ enum
enum enum
{ {
CV_CAP_ANDROID_FOCUS_MODE_AUTO = 0, CV_CAP_ANDROID_FOCUS_MODE_AUTO = 0,
CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_PICTURE,
CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_VIDEO, CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_VIDEO,
CV_CAP_ANDROID_FOCUS_MODE_EDOF, CV_CAP_ANDROID_FOCUS_MODE_EDOF,
CV_CAP_ANDROID_FOCUS_MODE_FIXED, CV_CAP_ANDROID_FOCUS_MODE_FIXED,

View File

@ -289,6 +289,10 @@ double CvCapture_Android::getProperty( int propIdx )
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL); return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL);
case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR: case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR); return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR);
case CV_CAP_PROP_ANDROID_EXPOSE_LOCK:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_EXPOSE_LOCK);
case CV_CAP_PROP_ANDROID_WHITEBALANCE_LOCK:
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_WHITEBALANCE_LOCK);
default: default:
CV_Error( CV_StsOutOfRange, "Failed attempt to GET unsupported camera property." ); CV_Error( CV_StsOutOfRange, "Failed attempt to GET unsupported camera property." );
break; break;
@ -327,14 +331,23 @@ bool CvCapture_Android::setProperty( int propIdx, double propValue )
case CV_CAP_PROP_ANDROID_ANTIBANDING: case CV_CAP_PROP_ANDROID_ANTIBANDING:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_ANTIBANDING, propValue); m_activity->setProperty(ANDROID_CAMERA_PROPERTY_ANTIBANDING, propValue);
break; break;
case CV_CAP_PROP_ANDROID_EXPOSE_LOCK:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_EXPOSE_LOCK, propValue);
break;
case CV_CAP_PROP_ANDROID_WHITEBALANCE_LOCK:
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_WHITEBALANCE_LOCK, propValue);
break;
default: default:
CV_Error( CV_StsOutOfRange, "Failed attempt to SET unsupported camera property." ); CV_Error( CV_StsOutOfRange, "Failed attempt to SET unsupported camera property." );
return false; return false;
} }
if (propIdx != CV_CAP_PROP_AUTOGRAB) {// property for highgui class CvCapture_Android only // Only changes in frame size require camera restart
if ((propIdx == CV_CAP_PROP_FRAME_WIDTH) || (propIdx == CV_CAP_PROP_FRAME_HEIGHT))
{ // property for highgui class CvCapture_Android only
m_CameraParamsChanged = true; m_CameraParamsChanged = true;
} }
res = true; res = true;
} }

View File

@ -1309,6 +1309,8 @@ bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) {
} }
//cleanup //cleanup
CFRelease(cfData);
CVPixelBufferRelease(pixelBuffer);
CGImageRelease(cgImage); CGImageRelease(cgImage);
CGDataProviderRelease(provider); CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace); CGColorSpaceRelease(colorSpace);

View File

@ -598,6 +598,8 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE; cinfo.in_color_space = channels > 1 ? JCS_RGB : JCS_GRAYSCALE;
int quality = 95; int quality = 95;
int progressive = 0;
int optimize = 0;
for( size_t i = 0; i < params.size(); i += 2 ) for( size_t i = 0; i < params.size(); i += 2 )
{ {
@ -606,11 +608,25 @@ bool JpegEncoder::write( const Mat& img, const std::vector<int>& params )
quality = params[i+1]; quality = params[i+1];
quality = MIN(MAX(quality, 0), 100); quality = MIN(MAX(quality, 0), 100);
} }
if( params[i] == CV_IMWRITE_JPEG_PROGRESSIVE )
{
progressive = params[i+1];
}
if( params[i] == CV_IMWRITE_JPEG_OPTIMIZE )
{
optimize = params[i+1];
}
} }
jpeg_set_defaults( &cinfo ); jpeg_set_defaults( &cinfo );
jpeg_set_quality( &cinfo, quality, jpeg_set_quality( &cinfo, quality,
TRUE /* limit to baseline-JPEG values */ ); TRUE /* limit to baseline-JPEG values */ );
if( progressive )
jpeg_simple_progression( &cinfo );
if( optimize )
cinfo.optimize_coding = TRUE;
jpeg_start_compress( &cinfo, TRUE ); jpeg_start_compress( &cinfo, TRUE );
if( channels > 1 ) if( channels > 1 )

View File

@ -386,6 +386,54 @@ TEST(Highgui_Jpeg, encode_empty)
ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception); ASSERT_THROW(cv::imencode(".jpg", img, jpegImg), cv::Exception);
} }
TEST(Highgui_Jpeg, encode_decode_progressive_jpeg)
{
cvtest::TS& ts = *cvtest::TS::ptr();
string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
cv::Mat img = cv::imread(input);
ASSERT_FALSE(img.empty());
std::vector<int> params;
params.push_back(IMWRITE_JPEG_PROGRESSIVE);
params.push_back(1);
string output_progressive = cv::tempfile(".jpg");
EXPECT_NO_THROW(cv::imwrite(output_progressive, img, params));
cv::Mat img_jpg_progressive = cv::imread(output_progressive);
string output_normal = cv::tempfile(".jpg");
EXPECT_NO_THROW(cv::imwrite(output_normal, img));
cv::Mat img_jpg_normal = cv::imread(output_normal);
EXPECT_EQ(0, cv::norm(img_jpg_progressive, img_jpg_normal, NORM_INF));
remove(output_progressive.c_str());
}
TEST(Highgui_Jpeg, encode_decode_optimize_jpeg)
{
cvtest::TS& ts = *cvtest::TS::ptr();
string input = string(ts.get_data_path()) + "../cv/shared/lena.png";
cv::Mat img = cv::imread(input);
ASSERT_FALSE(img.empty());
std::vector<int> params;
params.push_back(IMWRITE_JPEG_OPTIMIZE);
params.push_back(1);
string output_optimized = cv::tempfile(".jpg");
EXPECT_NO_THROW(cv::imwrite(output_optimized, img, params));
cv::Mat img_jpg_optimized = cv::imread(output_optimized);
string output_normal = cv::tempfile(".jpg");
EXPECT_NO_THROW(cv::imwrite(output_normal, img));
cv::Mat img_jpg_normal = cv::imread(output_normal);
EXPECT_EQ(0, cv::norm(img_jpg_optimized, img_jpg_normal, NORM_INF));
remove(output_optimized.c_str());
}
#endif #endif

View File

@ -211,7 +211,7 @@ OCL_PERF_TEST_P(SobelFixture, Sobel,
OCL_TEST_CYCLE() cv::Sobel(src, dst, -1, dx, dy); OCL_TEST_CYCLE() cv::Sobel(src, dst, -1, dx, dy);
SANITY_CHECK(dst); SANITY_CHECK(dst, 1e-6);
} }
///////////// Scharr //////////////////////// ///////////// Scharr ////////////////////////

View File

@ -95,6 +95,34 @@ OCL_PERF_TEST_P(CalcHistFixture, CalcHist, OCL_TEST_SIZES)
SANITY_CHECK(hist); SANITY_CHECK(hist);
} }
///////////// calcHist ////////////////////////
typedef TestBaseWithParam<Size> CalcBackProjFixture;
OCL_PERF_TEST_P(CalcBackProjFixture, CalcBackProj, OCL_TEST_SIZES)
{
const Size srcSize = GetParam();
const std::vector<int> channels(1, 0);
std::vector<float> ranges(2);
std::vector<int> histSize(1, 256);
ranges[0] = 0;
ranges[1] = 256;
checkDeviceMaxMemoryAllocSize(srcSize, CV_8UC1);
UMat src(srcSize, CV_8UC1), hist(256, 1, CV_32FC1), dst(srcSize, CV_8UC1);
declare.in(src, WARMUP_RNG).out(hist);
cv::calcHist(std::vector<UMat>(1, src), channels, noArray(), hist, histSize, ranges, false);
declare.in(src, WARMUP_RNG).out(dst);
OCL_TEST_CYCLE() cv::calcBackProject(std::vector<UMat>(1,src), channels, hist, dst, ranges, 1);
SANITY_CHECK_NOTHING();
}
/////////// CopyMakeBorder ////////////////////// /////////// CopyMakeBorder //////////////////////
CV_ENUM(Border, BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT, BORDER_WRAP, BORDER_REFLECT_101) CV_ENUM(Border, BORDER_CONSTANT, BORDER_REPLICATE, BORDER_REFLECT, BORDER_WRAP, BORDER_REFLECT_101)

View File

@ -100,19 +100,29 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
low_thresh = std::min(32767.0f, low_thresh); low_thresh = std::min(32767.0f, low_thresh);
high_thresh = std::min(32767.0f, high_thresh); high_thresh = std::min(32767.0f, high_thresh);
if (low_thresh > 0) low_thresh *= low_thresh; if (low_thresh > 0)
if (high_thresh > 0) high_thresh *= high_thresh; low_thresh *= low_thresh;
if (high_thresh > 0)
high_thresh *= high_thresh;
} }
int low = cvFloor(low_thresh), high = cvFloor(high_thresh); int low = cvFloor(low_thresh), high = cvFloor(high_thresh);
Size esize(size.width + 2, size.height + 2); Size esize(size.width + 2, size.height + 2);
UMat mag; UMat mag;
size_t globalsize[2] = { size.width * cn, size.height }, localsize[2] = { 16, 16 }; size_t globalsize[2] = { size.width, size.height }, localsize[2] = { 16, 16 };
if (aperture_size == 3 && !_src.isSubmatrix()) if (aperture_size == 3 && !_src.isSubmatrix())
{ {
// Sobel calculation // Sobel calculation
ocl::Kernel calcSobelRowPassKernel("calcSobelRowPass", ocl::imgproc::canny_oclsrc); char cvt[2][40];
ocl::Kernel calcSobelRowPassKernel("calcSobelRowPass", ocl::imgproc::canny_oclsrc,
format("-D OP_SOBEL -D cn=%d -D shortT=%s -D ucharT=%s"
" -D convertToIntT=%s -D intT=%s -D convertToShortT=%s", cn,
ocl::typeToStr(CV_16SC(cn)),
ocl::typeToStr(CV_8UC(cn)),
ocl::convertTypeStr(CV_8U, CV_32S, cn, cvt[0]),
ocl::typeToStr(CV_32SC(cn)),
ocl::convertTypeStr(CV_32S, CV_16S, cn, cvt[1])));
if (calcSobelRowPassKernel.empty()) if (calcSobelRowPassKernel.empty())
return false; return false;
@ -126,58 +136,62 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
// magnitude calculation // magnitude calculation
ocl::Kernel magnitudeKernel("calcMagnitude_buf", ocl::imgproc::canny_oclsrc, ocl::Kernel magnitudeKernel("calcMagnitude_buf", ocl::imgproc::canny_oclsrc,
L2gradient ? " -D L2GRAD" : ""); format("-D cn=%d%s -D OP_MAG_BUF -D shortT=%s -D convertToIntT=%s -D intT=%s",
cn, L2gradient ? " -D L2GRAD" : "",
ocl::typeToStr(CV_16SC(cn)),
ocl::convertTypeStr(CV_16S, CV_32S, cn, cvt[0]),
ocl::typeToStr(CV_32SC(cn))));
if (magnitudeKernel.empty()) if (magnitudeKernel.empty())
return false; return false;
mag = UMat(esize, CV_32SC(cn), Scalar::all(0)); mag = UMat(esize, CV_32SC1, Scalar::all(0));
dx.create(size, CV_16SC(cn)); dx.create(size, CV_16SC(cn));
dy.create(size, CV_16SC(cn)); dy.create(size, CV_16SC(cn));
magnitudeKernel.args(ocl::KernelArg::ReadOnlyNoSize(dxBuf), ocl::KernelArg::ReadOnlyNoSize(dyBuf), magnitudeKernel.args(ocl::KernelArg::ReadOnlyNoSize(dxBuf), ocl::KernelArg::ReadOnlyNoSize(dyBuf),
ocl::KernelArg::WriteOnlyNoSize(dx), ocl::KernelArg::WriteOnlyNoSize(dy), ocl::KernelArg::WriteOnlyNoSize(dx), ocl::KernelArg::WriteOnlyNoSize(dy),
ocl::KernelArg::WriteOnlyNoSize(mag, cn), size.height, size.width); ocl::KernelArg::WriteOnlyNoSize(mag), size.height, size.width);
if (!magnitudeKernel.run(2, globalsize, localsize, false)) if (!magnitudeKernel.run(2, globalsize, localsize, false))
return false; return false;
} }
else else
{ {
dx.create(size, CV_16SC(cn)); Sobel(_src, dx, CV_16S, 1, 0, aperture_size, 1, 0, BORDER_REPLICATE);
dy.create(size, CV_16SC(cn)); Sobel(_src, dy, CV_16S, 0, 1, aperture_size, 1, 0, BORDER_REPLICATE);
Sobel(_src, dx, CV_16SC1, 1, 0, aperture_size, 1, 0, BORDER_REPLICATE);
Sobel(_src, dy, CV_16SC1, 0, 1, aperture_size, 1, 0, BORDER_REPLICATE);
// magnitude calculation // magnitude calculation
ocl::Kernel magnitudeKernel("calcMagnitude", ocl::imgproc::canny_oclsrc, ocl::Kernel magnitudeKernel("calcMagnitude", ocl::imgproc::canny_oclsrc,
L2gradient ? " -D L2GRAD" : ""); format("-D OP_MAG -D cn=%d%s -D intT=int -D shortT=short -D convertToIntT=convert_int_sat",
cn, L2gradient ? " -D L2GRAD" : ""));
if (magnitudeKernel.empty()) if (magnitudeKernel.empty())
return false; return false;
mag = UMat(esize, CV_32SC(cn), Scalar::all(0)); mag = UMat(esize, CV_32SC1, Scalar::all(0));
magnitudeKernel.args(ocl::KernelArg::ReadOnlyNoSize(dx), ocl::KernelArg::ReadOnlyNoSize(dy), magnitudeKernel.args(ocl::KernelArg::ReadOnlyNoSize(dx), ocl::KernelArg::ReadOnlyNoSize(dy),
ocl::KernelArg::WriteOnlyNoSize(mag, cn), size.height, size.width); ocl::KernelArg::WriteOnlyNoSize(mag), size.height, size.width);
if (!magnitudeKernel.run(2, globalsize, NULL, false)) if (!magnitudeKernel.run(2, globalsize, NULL, false))
return false; return false;
} }
// map calculation // map calculation
ocl::Kernel calcMapKernel("calcMap", ocl::imgproc::canny_oclsrc); ocl::Kernel calcMapKernel("calcMap", ocl::imgproc::canny_oclsrc,
format("-D OP_MAP -D cn=%d", cn));
if (calcMapKernel.empty()) if (calcMapKernel.empty())
return false; return false;
UMat map(esize, CV_32SC(cn)); UMat map(esize, CV_32SC1);
calcMapKernel.args(ocl::KernelArg::ReadOnlyNoSize(dx), ocl::KernelArg::ReadOnlyNoSize(dy), calcMapKernel.args(ocl::KernelArg::ReadOnlyNoSize(dx), ocl::KernelArg::ReadOnlyNoSize(dy),
ocl::KernelArg::ReadOnlyNoSize(mag), ocl::KernelArg::WriteOnlyNoSize(map, cn), ocl::KernelArg::ReadOnlyNoSize(mag), ocl::KernelArg::WriteOnlyNoSize(map),
size.height, size.width, low, high); size.height, size.width, low, high);
if (!calcMapKernel.run(2, globalsize, localsize, false)) if (!calcMapKernel.run(2, globalsize, localsize, false))
return false; return false;
// local hysteresis thresholding // local hysteresis thresholding
ocl::Kernel edgesHysteresisLocalKernel("edgesHysteresisLocal", ocl::imgproc::canny_oclsrc); ocl::Kernel edgesHysteresisLocalKernel("edgesHysteresisLocal", ocl::imgproc::canny_oclsrc,
"-D OP_HYST_LOCAL");
if (edgesHysteresisLocalKernel.empty()) if (edgesHysteresisLocalKernel.empty())
return false; return false;
@ -193,7 +207,8 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
for ( ; ; ) for ( ; ; )
{ {
ocl::Kernel edgesHysteresisGlobalKernel("edgesHysteresisGlobal", ocl::imgproc::canny_oclsrc); ocl::Kernel edgesHysteresisGlobalKernel("edgesHysteresisGlobal", ocl::imgproc::canny_oclsrc,
"-D OP_HYST_GLOBAL");
if (edgesHysteresisGlobalKernel.empty()) if (edgesHysteresisGlobalKernel.empty())
return false; return false;
@ -221,14 +236,15 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
} }
// get edges // get edges
ocl::Kernel getEdgesKernel("getEdges", ocl::imgproc::canny_oclsrc); ocl::Kernel getEdgesKernel("getEdges", ocl::imgproc::canny_oclsrc, "-D OP_EDGES");
if (getEdgesKernel.empty()) if (getEdgesKernel.empty())
return false; return false;
_dst.create(size, CV_8UC(cn)); _dst.create(size, CV_8UC1);
UMat dst = _dst.getUMat(); UMat dst = _dst.getUMat();
getEdgesKernel.args(ocl::KernelArg::ReadOnlyNoSize(map), ocl::KernelArg::WriteOnly(dst)); getEdgesKernel.args(ocl::KernelArg::ReadOnlyNoSize(map), ocl::KernelArg::WriteOnly(dst));
return getEdgesKernel.run(2, globalsize, NULL, false); return getEdgesKernel.run(2, globalsize, NULL, false);
} }
@ -254,12 +270,12 @@ void cv::Canny( InputArray _src, OutputArray _dst,
} }
if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7))) if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7)))
CV_Error(CV_StsBadFlag, ""); CV_Error(CV_StsBadFlag, "Aperture size should be odd");
if (low_thresh > high_thresh) if (low_thresh > high_thresh)
std::swap(low_thresh, high_thresh); std::swap(low_thresh, high_thresh);
CV_OCL_RUN(_dst.isUMat() && cn == 1, CV_OCL_RUN(_dst.isUMat() && (cn == 1 || cn == 3),
ocl_Canny(_src, _dst, (float)low_thresh, (float)high_thresh, aperture_size, L2gradient, cn, size)) ocl_Canny(_src, _dst, (float)low_thresh, (float)high_thresh, aperture_size, L2gradient, cn, size))
Mat src = _src.getMat(), dst = _dst.getMat(); Mat src = _src.getMat(), dst = _dst.getMat();

View File

@ -11,6 +11,7 @@
// For Open Source Computer Vision Library // For Open Source Computer Vision Library
// //
// Copyright (C) 2000, Intel Corporation, all rights reserved. // Copyright (C) 2000, Intel Corporation, all rights reserved.
// Copyright (C) 2014, Itseez, Inc, all rights reserved.
// Third party copyrights are property of their respective owners. // Third party copyrights are property of their respective owners.
// //
// Redistribution and use in source and binary forms, with or without modification, // Redistribution and use in source and binary forms, with or without modification,
@ -40,6 +41,8 @@
//M*/ //M*/
#include "precomp.hpp" #include "precomp.hpp"
#include "opencl_kernels.hpp"
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
static IppStatus sts = ippInit(); static IppStatus sts = ippInit();
#endif #endif
@ -495,6 +498,58 @@ void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
sepFilter2D( _src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType ); sepFilter2D( _src, _dst, ddepth, kx, ky, Point(-1, -1), delta, borderType );
} }
#ifdef HAVE_OPENCL
namespace cv {
static bool ocl_Laplacian5(InputArray _src, OutputArray _dst,
const Mat & kd, const Mat & ks, double scale, double delta,
int borderType, int depth, int ddepth)
{
int iscale = cvRound(scale), idelta = cvRound(delta);
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0,
floatCoeff = std::fabs(delta - idelta) > DBL_EPSILON || std::fabs(scale - iscale) > DBL_EPSILON;
int cn = _src.channels(), wdepth = std::max(depth, floatCoeff ? CV_32F : CV_32S), kercn = 1;
if (!doubleSupport && wdepth == CV_64F)
return false;
char cvt[2][40];
ocl::Kernel k("sumConvert", ocl::imgproc::laplacian5_oclsrc,
format("-D srcT=%s -D WT=%s -D dstT=%s -D coeffT=%s -D wdepth=%d "
"-D convertToWT=%s -D convertToDT=%s%s",
ocl::typeToStr(CV_MAKE_TYPE(depth, kercn)),
ocl::typeToStr(CV_MAKE_TYPE(wdepth, kercn)),
ocl::typeToStr(CV_MAKE_TYPE(ddepth, kercn)),
ocl::typeToStr(wdepth), wdepth,
ocl::convertTypeStr(depth, wdepth, kercn, cvt[0]),
ocl::convertTypeStr(wdepth, ddepth, kercn, cvt[1]),
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
if (k.empty())
return false;
UMat d2x, d2y;
sepFilter2D(_src, d2x, depth, kd, ks, Point(-1, -1), 0, borderType);
sepFilter2D(_src, d2y, depth, ks, kd, Point(-1, -1), 0, borderType);
UMat dst = _dst.getUMat();
ocl::KernelArg d2xarg = ocl::KernelArg::ReadOnlyNoSize(d2x),
d2yarg = ocl::KernelArg::ReadOnlyNoSize(d2y),
dstarg = ocl::KernelArg::WriteOnly(dst, cn, kercn);
if (wdepth >= CV_32F)
k.args(d2xarg, d2yarg, dstarg, (float)scale, (float)delta);
else
k.args(d2xarg, d2yarg, dstarg, iscale, idelta);
size_t globalsize[] = { dst.cols * cn / kercn, dst.rows };
return k.run(2, globalsize, NULL, false);
}
}
#endif
void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize, void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
double scale, double delta, int borderType ) double scale, double delta, int borderType )
@ -531,27 +586,28 @@ void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
} }
else else
{ {
Mat src = _src.getMat(), dst = _dst.getMat(); int ktype = std::max(CV_32F, std::max(ddepth, sdepth));
const size_t STRIPE_SIZE = 1 << 14; int wdepth = sdepth == CV_8U && ksize <= 5 ? CV_16S : sdepth <= CV_32F ? CV_32F : CV_64F;
int wtype = CV_MAKETYPE(wdepth, cn);
int depth = src.depth();
int ktype = std::max(CV_32F, std::max(ddepth, depth));
int wdepth = depth == CV_8U && ksize <= 5 ? CV_16S : depth <= CV_32F ? CV_32F : CV_64F;
int wtype = CV_MAKETYPE(wdepth, src.channels());
Mat kd, ks; Mat kd, ks;
getSobelKernels( kd, ks, 2, 0, ksize, false, ktype ); getSobelKernels( kd, ks, 2, 0, ksize, false, ktype );
int dtype = CV_MAKETYPE(ddepth, src.channels());
int dy0 = std::min(std::max((int)(STRIPE_SIZE/(getElemSize(src.type())*src.cols)), 1), src.rows); CV_OCL_RUN(_dst.isUMat(),
Ptr<FilterEngine> fx = createSeparableLinearFilter(src.type(), ocl_Laplacian5(_src, _dst, kd, ks, scale,
delta, borderType, wdepth, ddepth))
const size_t STRIPE_SIZE = 1 << 14;
Ptr<FilterEngine> fx = createSeparableLinearFilter(stype,
wtype, kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() ); wtype, kd, ks, Point(-1,-1), 0, borderType, borderType, Scalar() );
Ptr<FilterEngine> fy = createSeparableLinearFilter(src.type(), Ptr<FilterEngine> fy = createSeparableLinearFilter(stype,
wtype, ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() ); wtype, ks, kd, Point(-1,-1), 0, borderType, borderType, Scalar() );
Mat src = _src.getMat(), dst = _dst.getMat();
int y = fx->start(src), dsty = 0, dy = 0; int y = fx->start(src), dsty = 0, dy = 0;
fy->start(src); fy->start(src);
const uchar* sptr = src.data + y*src.step; const uchar* sptr = src.data + y*src.step;
int dy0 = std::min(std::max((int)(STRIPE_SIZE/(CV_ELEM_SIZE(stype)*src.cols)), 1), src.rows);
Mat d2x( dy0 + kd.rows - 1, src.cols, wtype ); Mat d2x( dy0 + kd.rows - 1, src.cols, wtype );
Mat d2y( dy0 + kd.rows - 1, src.cols, wtype ); Mat d2y( dy0 + kd.rows - 1, src.cols, wtype );
@ -564,7 +620,7 @@ void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
Mat dstripe = dst.rowRange(dsty, dsty + dy); Mat dstripe = dst.rowRange(dsty, dsty + dy);
d2x.rows = d2y.rows = dy; // modify the headers, which should work d2x.rows = d2y.rows = dy; // modify the headers, which should work
d2x += d2y; d2x += d2y;
d2x.convertTo( dstripe, dtype, scale, delta ); d2x.convertTo( dstripe, ddepth, scale, delta );
} }
} }
} }

View File

@ -42,7 +42,6 @@
#include "precomp.hpp" #include "precomp.hpp"
#include "opencl_kernels.hpp" #include "opencl_kernels.hpp"
#include <sstream>
/****************************************************************************************\ /****************************************************************************************\
Base Image Filter Base Image Filter
@ -3134,7 +3133,7 @@ template<typename ST, class CastOp, class VecOp> struct Filter2D : public BaseFi
// b e h b e h 0 0 // b e h b e h 0 0
// c f i c f i 0 0 // c f i c f i 0 0
template <typename T> template <typename T>
static int _prepareKernelFilter2D(std::vector<T>& data, const Mat &kernel) static int _prepareKernelFilter2D(std::vector<T> & data, const Mat & kernel)
{ {
Mat _kernel; kernel.convertTo(_kernel, DataDepth<T>::value); Mat _kernel; kernel.convertTo(_kernel, DataDepth<T>::value);
int size_y_aligned = ROUNDUP(kernel.rows * 2, 4); int size_y_aligned = ROUNDUP(kernel.rows * 2, 4);
@ -3154,75 +3153,52 @@ static bool ocl_filter2D( InputArray _src, OutputArray _dst, int ddepth,
InputArray _kernel, Point anchor, InputArray _kernel, Point anchor,
double delta, int borderType ) double delta, int borderType )
{ {
if (abs(delta) > FLT_MIN) int type = _src.type(), sdepth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
ddepth = ddepth < 0 ? sdepth : ddepth;
int dtype = CV_MAKE_TYPE(ddepth, cn), wdepth = std::max(std::max(sdepth, ddepth), CV_32F),
wtype = CV_MAKE_TYPE(wdepth, cn);
if (cn > 4)
return false; return false;
int type = _src.type();
int cn = CV_MAT_CN(type);
if ((1 != cn) && (2 != cn) && (4 != cn))
return false;//TODO
int sdepth = CV_MAT_DEPTH(type);
Size ksize = _kernel.size(); Size ksize = _kernel.size();
if( anchor.x < 0 ) if (anchor.x < 0)
anchor.x = ksize.width / 2; anchor.x = ksize.width / 2;
if( anchor.y < 0 ) if (anchor.y < 0)
anchor.y = ksize.height / 2; anchor.y = ksize.height / 2;
if( ddepth < 0 )
ddepth = sdepth;
else if (ddepth != sdepth)
return false;
bool isIsolatedBorder = (borderType & BORDER_ISOLATED) != 0; bool isolated = (borderType & BORDER_ISOLATED) != 0;
bool useDouble = (CV_64F == sdepth); borderType &= ~BORDER_ISOLATED;
const cv::ocl::Device &device = cv::ocl::Device::getDefault(); const cv::ocl::Device &device = cv::ocl::Device::getDefault();
int doubleFPConfig = device.doubleFPConfig(); bool doubleSupport = device.doubleFPConfig() > 0;
if (useDouble && (0 == doubleFPConfig)) if (wdepth == CV_64F && !doubleSupport)
return false; return false;
const char* btype = NULL; const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT",
switch (borderType & ~BORDER_ISOLATED) "BORDER_WRAP", "BORDER_REFLECT_101" };
{
case BORDER_CONSTANT:
btype = "BORDER_CONSTANT";
break;
case BORDER_REPLICATE:
btype = "BORDER_REPLICATE";
break;
case BORDER_REFLECT:
btype = "BORDER_REFLECT";
break;
case BORDER_WRAP:
return false;
case BORDER_REFLECT101:
btype = "BORDER_REFLECT_101";
break;
}
cv::Mat kernelMat = _kernel.getMat(); cv::Mat kernelMat = _kernel.getMat();
std::vector<float> kernelMatDataFloat; std::vector<float> kernelMatDataFloat;
std::vector<double> kernelMatDataDouble; int kernel_size_y2_aligned = _prepareKernelFilter2D<float>(kernelMatDataFloat, kernelMat);
int kernel_size_y2_aligned = useDouble ?
_prepareKernelFilter2D<double>(kernelMatDataDouble, kernelMat)
: _prepareKernelFilter2D<float>(kernelMatDataFloat, kernelMat);
cv::Size sz = _src.size(), wholeSize;
size_t globalsize[2] = { sz.width, sz.height }, localsize[2] = { 0, 1 };
cv::Size sz = _src.size(); ocl::Kernel k;
size_t globalsize[2] = {sz.width, sz.height}; UMat src = _src.getUMat();
size_t localsize[2] = {0, 1}; if (!isolated)
ocl::Kernel kernel;
UMat src; Size wholeSize;
if (!isIsolatedBorder)
{ {
src = _src.getUMat();
Point ofs; Point ofs;
src.locateROI(wholeSize, ofs); src.locateROI(wholeSize, ofs);
} }
size_t maxWorkItemSizes[32]; device.maxWorkItemSizes(maxWorkItemSizes); size_t maxWorkItemSizes[32];
device.maxWorkItemSizes(maxWorkItemSizes);
size_t tryWorkItems = maxWorkItemSizes[0]; size_t tryWorkItems = maxWorkItemSizes[0];
for (;;) char cvt[2][40];
String kerStr = ocl::kernelToStr(kernelMatDataFloat, CV_32F);
for ( ; ; )
{ {
size_t BLOCK_SIZE = tryWorkItems; size_t BLOCK_SIZE = tryWorkItems;
while (BLOCK_SIZE > 32 && BLOCK_SIZE >= (size_t)ksize.width * 2 && BLOCK_SIZE > (size_t)sz.width * 2) while (BLOCK_SIZE > 32 && BLOCK_SIZE >= (size_t)ksize.width * 2 && BLOCK_SIZE > (size_t)sz.width * 2)
@ -3242,32 +3218,36 @@ static bool ocl_filter2D( InputArray _src, OutputArray _dst, int ddepth,
int requiredLeft = (int)BLOCK_SIZE; // not this: anchor.x; int requiredLeft = (int)BLOCK_SIZE; // not this: anchor.x;
int requiredBottom = ksize.height - 1 - anchor.y; int requiredBottom = ksize.height - 1 - anchor.y;
int requiredRight = (int)BLOCK_SIZE; // not this: ksize.width - 1 - anchor.x; int requiredRight = (int)BLOCK_SIZE; // not this: ksize.width - 1 - anchor.x;
int h = isIsolatedBorder ? sz.height : wholeSize.height; int h = isolated ? sz.height : wholeSize.height;
int w = isIsolatedBorder ? sz.width : wholeSize.width; int w = isolated ? sz.width : wholeSize.width;
bool extra_extrapolation = h < requiredTop || h < requiredBottom || w < requiredLeft || w < requiredRight; bool extra_extrapolation = h < requiredTop || h < requiredBottom || w < requiredLeft || w < requiredRight;
if ((w < ksize.width) || (h < ksize.height)) if ((w < ksize.width) || (h < ksize.height))
return false; return false;
char build_options[1024]; String opts = format("-D LOCAL_SIZE=%d -D BLOCK_SIZE_Y=%d -D cn=%d "
sprintf(build_options, "-D LOCAL_SIZE=%d -D BLOCK_SIZE_Y=%d -D DATA_DEPTH=%d -D DATA_CHAN=%d -D USE_DOUBLE=%d " "-D ANCHOR_X=%d -D ANCHOR_Y=%d -D KERNEL_SIZE_X=%d -D KERNEL_SIZE_Y=%d "
"-D ANCHOR_X=%d -D ANCHOR_Y=%d -D KERNEL_SIZE_X=%d -D KERNEL_SIZE_Y=%d -D KERNEL_SIZE_Y2_ALIGNED=%d " "-D KERNEL_SIZE_Y2_ALIGNED=%d -D %s -D %s -D %s%s%s "
"-D %s -D %s -D %s", "-D srcT=%s -D srcT1=%s -D dstT=%s -D dstT1=%s -D WT=%s -D WT1=%s "
(int)BLOCK_SIZE, (int)BLOCK_SIZE_Y, "-D convertToWT=%s -D convertToDstT=%s",
sdepth, cn, useDouble ? 1 : 0, (int)BLOCK_SIZE, (int)BLOCK_SIZE_Y, cn, anchor.x, anchor.y,
anchor.x, anchor.y, ksize.width, ksize.height, kernel_size_y2_aligned, ksize.width, ksize.height, kernel_size_y2_aligned, borderMap[borderType],
btype, extra_extrapolation ? "EXTRA_EXTRAPOLATION" : "NO_EXTRA_EXTRAPOLATION",
extra_extrapolation ? "EXTRA_EXTRAPOLATION" : "NO_EXTRA_EXTRAPOLATION", isolated ? "BORDER_ISOLATED" : "NO_BORDER_ISOLATED",
isIsolatedBorder ? "BORDER_ISOLATED" : "NO_BORDER_ISOLATED"); doubleSupport ? " -D DOUBLE_SUPPORT" : "", kerStr.c_str(),
ocl::typeToStr(type), ocl::typeToStr(sdepth), ocl::typeToStr(dtype),
ocl::typeToStr(ddepth), ocl::typeToStr(wtype), ocl::typeToStr(wdepth),
ocl::convertTypeStr(sdepth, wdepth, cn, cvt[0]),
ocl::convertTypeStr(wdepth, ddepth, cn, cvt[1]));
localsize[0] = BLOCK_SIZE; localsize[0] = BLOCK_SIZE;
globalsize[0] = DIVUP(sz.width, BLOCK_SIZE - (ksize.width - 1)) * BLOCK_SIZE; globalsize[0] = DIVUP(sz.width, BLOCK_SIZE - (ksize.width - 1)) * BLOCK_SIZE;
globalsize[1] = DIVUP(sz.height, BLOCK_SIZE_Y); globalsize[1] = DIVUP(sz.height, BLOCK_SIZE_Y);
cv::String errmsg; if (!k.create("filter2D", cv::ocl::imgproc::filter2D_oclsrc, opts))
if (!kernel.create("filter2D", cv::ocl::imgproc::filter2D_oclsrc, build_options))
return false; return false;
size_t kernelWorkGroupSize = kernel.workGroupSize();
size_t kernelWorkGroupSize = k.workGroupSize();
if (localsize[0] <= kernelWorkGroupSize) if (localsize[0] <= kernelWorkGroupSize)
break; break;
if (BLOCK_SIZE < kernelWorkGroupSize) if (BLOCK_SIZE < kernelWorkGroupSize)
@ -3275,242 +3255,238 @@ static bool ocl_filter2D( InputArray _src, OutputArray _dst, int ddepth,
tryWorkItems = kernelWorkGroupSize; tryWorkItems = kernelWorkGroupSize;
} }
_dst.create(sz, CV_MAKETYPE(ddepth, cn)); _dst.create(sz, dtype);
UMat dst = _dst.getUMat(); UMat dst = _dst.getUMat();
if (src.empty())
src = _src.getUMat();
int idxArg = 0;
idxArg = kernel.set(idxArg, ocl::KernelArg::PtrReadOnly(src));
idxArg = kernel.set(idxArg, (int)src.step);
int srcOffsetX = (int)((src.offset % src.step) / src.elemSize()); int srcOffsetX = (int)((src.offset % src.step) / src.elemSize());
int srcOffsetY = (int)(src.offset / src.step); int srcOffsetY = (int)(src.offset / src.step);
int srcEndX = (isIsolatedBorder ? (srcOffsetX + sz.width) : wholeSize.width); int srcEndX = (isolated ? (srcOffsetX + sz.width) : wholeSize.width);
int srcEndY = (isIsolatedBorder ? (srcOffsetY + sz.height) : wholeSize.height); int srcEndY = (isolated ? (srcOffsetY + sz.height) : wholeSize.height);
idxArg = kernel.set(idxArg, srcOffsetX);
idxArg = kernel.set(idxArg, srcOffsetY);
idxArg = kernel.set(idxArg, srcEndX);
idxArg = kernel.set(idxArg, srcEndY);
idxArg = kernel.set(idxArg, ocl::KernelArg::WriteOnly(dst)); k.args(ocl::KernelArg::PtrReadOnly(src), (int)src.step, srcOffsetX, srcOffsetY,
float borderValue[4] = {0, 0, 0, 0}; srcEndX, srcEndY, ocl::KernelArg::WriteOnly(dst), (float)delta);
double borderValueDouble[4] = {0, 0, 0, 0};
if ((borderType & ~BORDER_ISOLATED) == BORDER_CONSTANT) return k.run(2, globalsize, localsize, false);
{
int cnocl = (3 == cn) ? 4 : cn;
if (useDouble)
idxArg = kernel.set(idxArg, (void *)&borderValueDouble[0], sizeof(double) * cnocl);
else
idxArg = kernel.set(idxArg, (void *)&borderValue[0], sizeof(float) * cnocl);
}
if (useDouble)
{
UMat kernalDataUMat(kernelMatDataDouble, true);
idxArg = kernel.set(idxArg, ocl::KernelArg::PtrReadOnly(kernalDataUMat));
}
else
{
UMat kernalDataUMat(kernelMatDataFloat, true);
idxArg = kernel.set(idxArg, ocl::KernelArg::PtrReadOnly(kernalDataUMat));
}
return kernel.run(2, globalsize, localsize, true);
} }
static bool ocl_sepRowFilter2D( UMat &src, UMat &buf, Mat &kernelX, int anchor, int borderType, bool sync) static bool ocl_sepRowFilter2D(const UMat & src, UMat & buf, const Mat & kernelX, int anchor,
int borderType, int ddepth, bool fast8uc1)
{ {
int type = src.type(); int type = src.type(), cn = CV_MAT_CN(type), sdepth = CV_MAT_DEPTH(type);
int cn = CV_MAT_CN(type); bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
int sdepth = CV_MAT_DEPTH(type);
Size bufSize = buf.size(); Size bufSize = buf.size();
if (!doubleSupport && (sdepth == CV_64F || ddepth == CV_64F))
return false;
#ifdef ANDROID #ifdef ANDROID
size_t localsize[2] = {16, 10}; size_t localsize[2] = {16, 10};
#else #else
size_t localsize[2] = {16, 16}; size_t localsize[2] = {16, 16};
#endif #endif
size_t globalsize[2] = {DIVUP(bufSize.width, localsize[0]) * localsize[0], DIVUP(bufSize.height, localsize[1]) * localsize[1]}; size_t globalsize[2] = {DIVUP(bufSize.width, localsize[0]) * localsize[0], DIVUP(bufSize.height, localsize[1]) * localsize[1]};
if (CV_8U == sdepth) if (fast8uc1)
{ globalsize[0] = DIVUP((bufSize.width + 3) >> 2, localsize[0]) * localsize[0];
switch (cn)
{
case 1:
globalsize[0] = DIVUP((bufSize.width + 3) >> 2, localsize[0]) * localsize[0];
break;
case 2:
globalsize[0] = DIVUP((bufSize.width + 1) >> 1, localsize[0]) * localsize[0];
break;
case 4:
globalsize[0] = DIVUP(bufSize.width, localsize[0]) * localsize[0];
break;
}
}
int radiusX = anchor; int radiusX = anchor, radiusY = (buf.rows - src.rows) >> 1;
int radiusY = (int)((buf.rows - src.rows) >> 1);
bool isIsolatedBorder = (borderType & BORDER_ISOLATED) != 0; bool isolated = (borderType & BORDER_ISOLATED) != 0;
const char* btype = NULL; const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT", "BORDER_WRAP", "BORDER_REFLECT_101" },
switch (borderType & ~BORDER_ISOLATED) * const btype = borderMap[borderType & ~BORDER_ISOLATED];
{
case BORDER_CONSTANT:
btype = "BORDER_CONSTANT";
break;
case BORDER_REPLICATE:
btype = "BORDER_REPLICATE";
break;
case BORDER_REFLECT:
btype = "BORDER_REFLECT";
break;
case BORDER_WRAP:
btype = "BORDER_WRAP";
break;
case BORDER_REFLECT101:
btype = "BORDER_REFLECT_101";
break;
default:
return false;
}
bool extra_extrapolation = src.rows < (int)((-radiusY + globalsize[1]) >> 1) + 1; bool extra_extrapolation = src.rows < (int)((-radiusY + globalsize[1]) >> 1) + 1;
extra_extrapolation |= src.rows < radiusY; extra_extrapolation |= src.rows < radiusY;
extra_extrapolation |= src.cols < (int)((-radiusX + globalsize[0] + 8 * localsize[0] + 3) >> 1) + 1; extra_extrapolation |= src.cols < (int)((-radiusX + globalsize[0] + 8 * localsize[0] + 3) >> 1) + 1;
extra_extrapolation |= src.cols < radiusX; extra_extrapolation |= src.cols < radiusX;
cv::String build_options = cv::format("-D RADIUSX=%d -D LSIZE0=%d -D LSIZE1=%d -D CN=%d -D %s -D %s -D %s", char cvt[40];
radiusX, (int)localsize[0], (int)localsize[1], cn, cv::String build_options = cv::format("-D RADIUSX=%d -D LSIZE0=%d -D LSIZE1=%d -D CN=%d -D %s -D %s -D %s"
btype, " -D srcT=%s -D dstT=%s -D convertToDstT=%s -D srcT1=%s -D dstT1=%s%s",
extra_extrapolation ? "EXTRA_EXTRAPOLATION" : "NO_EXTRA_EXTRAPOLATION", radiusX, (int)localsize[0], (int)localsize[1], cn, btype,
isIsolatedBorder ? "BORDER_ISOLATED" : "NO_BORDER_ISOLATED"); extra_extrapolation ? "EXTRA_EXTRAPOLATION" : "NO_EXTRA_EXTRAPOLATION",
isolated ? "BORDER_ISOLATED" : "NO_BORDER_ISOLATED",
ocl::typeToStr(type), ocl::typeToStr(CV_32FC(cn)),
ocl::convertTypeStr(sdepth, CV_32F, cn, cvt),
ocl::typeToStr(sdepth), ocl::typeToStr(CV_32F),
doubleSupport ? " -D DOUBLE_SUPPORT" : "");
build_options += ocl::kernelToStr(kernelX, CV_32F); build_options += ocl::kernelToStr(kernelX, CV_32F);
Size srcWholeSize; Point srcOffset; Size srcWholeSize; Point srcOffset;
src.locateROI(srcWholeSize, srcOffset); src.locateROI(srcWholeSize, srcOffset);
std::stringstream strKernel; String kernelName("row_filter");
strKernel << "row_filter"; if (fast8uc1)
if (-1 != cn) kernelName += "_C1_D0";
strKernel << "_C" << cn;
if (-1 != sdepth)
strKernel << "_D" << sdepth;
ocl::Kernel kernelRow; ocl::Kernel k(kernelName.c_str(), cv::ocl::imgproc::filterSepRow_oclsrc,
if (!kernelRow.create(strKernel.str().c_str(), cv::ocl::imgproc::filterSepRow_oclsrc, build_options);
build_options)) if (k.empty())
return false; return false;
int idxArg = 0; if (fast8uc1)
idxArg = kernelRow.set(idxArg, ocl::KernelArg::PtrReadOnly(src)); k.args(ocl::KernelArg::PtrReadOnly(src), (int)(src.step / src.elemSize()), srcOffset.x,
idxArg = kernelRow.set(idxArg, (int)(src.step / src.elemSize())); srcOffset.y, src.cols, src.rows, srcWholeSize.width, srcWholeSize.height,
ocl::KernelArg::PtrWriteOnly(buf), (int)(buf.step / buf.elemSize()),
buf.cols, buf.rows, radiusY);
else
k.args(ocl::KernelArg::PtrReadOnly(src), (int)src.step, srcOffset.x,
srcOffset.y, src.cols, src.rows, srcWholeSize.width, srcWholeSize.height,
ocl::KernelArg::PtrWriteOnly(buf), (int)buf.step, buf.cols, buf.rows, radiusY);
idxArg = kernelRow.set(idxArg, srcOffset.x); return k.run(2, globalsize, localsize, false);
idxArg = kernelRow.set(idxArg, srcOffset.y);
idxArg = kernelRow.set(idxArg, src.cols);
idxArg = kernelRow.set(idxArg, src.rows);
idxArg = kernelRow.set(idxArg, srcWholeSize.width);
idxArg = kernelRow.set(idxArg, srcWholeSize.height);
idxArg = kernelRow.set(idxArg, ocl::KernelArg::PtrWriteOnly(buf));
idxArg = kernelRow.set(idxArg, (int)(buf.step / buf.elemSize()));
idxArg = kernelRow.set(idxArg, buf.cols);
idxArg = kernelRow.set(idxArg, buf.rows);
idxArg = kernelRow.set(idxArg, radiusY);
return kernelRow.run(2, globalsize, localsize, sync);
} }
static bool ocl_sepColFilter2D(const UMat &buf, UMat &dst, Mat &kernelY, int anchor, bool sync) static bool ocl_sepColFilter2D(const UMat & buf, UMat & dst, const Mat & kernelY, double delta, int anchor)
{ {
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
if (dst.depth() == CV_64F && !doubleSupport)
return false;
#ifdef ANDROID #ifdef ANDROID
size_t localsize[2] = {16, 10}; size_t localsize[2] = { 16, 10 };
#else #else
size_t localsize[2] = {16, 16}; size_t localsize[2] = { 16, 16 };
#endif #endif
size_t globalsize[2] = {0, 0}; size_t globalsize[2] = { 0, 0 };
int dtype = dst.type(), cn = CV_MAT_CN(dtype), ddepth = CV_MAT_DEPTH(dtype); int dtype = dst.type(), cn = CV_MAT_CN(dtype), ddepth = CV_MAT_DEPTH(dtype);
Size sz = dst.size(); Size sz = dst.size();
globalsize[1] = DIVUP(sz.height, localsize[1]) * localsize[1]; globalsize[1] = DIVUP(sz.height, localsize[1]) * localsize[1];
globalsize[0] = DIVUP(sz.width, localsize[0]) * localsize[0];
if (dtype == CV_8UC2)
globalsize[0] = DIVUP((sz.width + 1) / 2, localsize[0]) * localsize[0];
else
globalsize[0] = DIVUP(sz.width, localsize[0]) * localsize[0];
char cvt[40]; char cvt[40];
cv::String build_options = cv::format("-D RADIUSY=%d -D LSIZE0=%d -D LSIZE1=%d -D CN=%d -D GENTYPE_SRC=%s -D GENTYPE_DST=%s -D convert_to_DST=%s", cv::String build_options = cv::format("-D RADIUSY=%d -D LSIZE0=%d -D LSIZE1=%d -D CN=%d"
anchor, (int)localsize[0], (int)localsize[1], cn, ocl::typeToStr(buf.type()), " -D srcT=%s -D dstT=%s -D convertToDstT=%s"
ocl::typeToStr(dtype), ocl::convertTypeStr(CV_32F, ddepth, cn, cvt)); " -D srcT1=%s -D dstT1=%s%s",
anchor, (int)localsize[0], (int)localsize[1], cn,
ocl::typeToStr(buf.type()), ocl::typeToStr(dtype),
ocl::convertTypeStr(CV_32F, ddepth, cn, cvt),
ocl::typeToStr(CV_32F), ocl::typeToStr(ddepth),
doubleSupport ? " -D DOUBLE_SUPPORT" : "");
build_options += ocl::kernelToStr(kernelY, CV_32F); build_options += ocl::kernelToStr(kernelY, CV_32F);
ocl::Kernel kernelCol; ocl::Kernel k("col_filter", cv::ocl::imgproc::filterSepCol_oclsrc,
if (!kernelCol.create("col_filter", cv::ocl::imgproc::filterSepCol_oclsrc, build_options)) build_options);
if (k.empty())
return false; return false;
int idxArg = 0; k.args(ocl::KernelArg::ReadOnly(buf), ocl::KernelArg::WriteOnly(dst),
idxArg = kernelCol.set(idxArg, ocl::KernelArg::PtrReadOnly(buf)); static_cast<float>(delta));
idxArg = kernelCol.set(idxArg, (int)(buf.step / buf.elemSize()));
idxArg = kernelCol.set(idxArg, buf.cols);
idxArg = kernelCol.set(idxArg, buf.rows);
idxArg = kernelCol.set(idxArg, ocl::KernelArg::PtrWriteOnly(dst)); return k.run(2, globalsize, localsize, false);
idxArg = kernelCol.set(idxArg, (int)(dst.offset / dst.elemSize())); }
idxArg = kernelCol.set(idxArg, (int)(dst.step / dst.elemSize()));
idxArg = kernelCol.set(idxArg, dst.cols);
idxArg = kernelCol.set(idxArg, dst.rows);
return kernelCol.run(2, globalsize, localsize, sync); const int optimizedSepFilterLocalSize = 16;
static bool ocl_sepFilter2D_SinglePass(InputArray _src, OutputArray _dst,
Mat row_kernel, Mat col_kernel,
double delta, int borderType, int ddepth)
{
Size size = _src.size(), wholeSize;
Point origin;
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype),
esz = CV_ELEM_SIZE(stype), wdepth = std::max(std::max(sdepth, ddepth), CV_32F),
dtype = CV_MAKE_TYPE(ddepth, cn);
size_t src_step = _src.step(), src_offset = _src.offset();
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
if ((src_offset % src_step) % esz != 0 || (!doubleSupport && (sdepth == CV_64F || ddepth == CV_64F)) ||
!(borderType == BORDER_CONSTANT || borderType == BORDER_REPLICATE ||
borderType == BORDER_REFLECT || borderType == BORDER_WRAP ||
borderType == BORDER_REFLECT_101))
return false;
size_t lt2[2] = { optimizedSepFilterLocalSize, optimizedSepFilterLocalSize };
size_t gt2[2] = { lt2[0] * (1 + (size.width - 1) / lt2[0]), lt2[1] * (1 + (size.height - 1) / lt2[1]) };
char cvt[2][40];
const char * const borderMap[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT", "BORDER_WRAP",
"BORDER_REFLECT_101" };
String opts = cv::format("-D BLK_X=%d -D BLK_Y=%d -D RADIUSX=%d -D RADIUSY=%d%s%s"
" -D srcT=%s -D convertToWT=%s -D WT=%s -D dstT=%s -D convertToDstT=%s"
" -D %s -D srcT1=%s -D dstT1=%s -D CN=%d", (int)lt2[0], (int)lt2[1],
row_kernel.cols / 2, col_kernel.cols / 2,
ocl::kernelToStr(row_kernel, CV_32F, "KERNEL_MATRIX_X").c_str(),
ocl::kernelToStr(col_kernel, CV_32F, "KERNEL_MATRIX_Y").c_str(),
ocl::typeToStr(stype), ocl::convertTypeStr(sdepth, wdepth, cn, cvt[0]),
ocl::typeToStr(CV_MAKE_TYPE(wdepth, cn)), ocl::typeToStr(dtype),
ocl::convertTypeStr(wdepth, ddepth, cn, cvt[1]), borderMap[borderType],
ocl::typeToStr(sdepth), ocl::typeToStr(ddepth), cn);
ocl::Kernel k("sep_filter", ocl::imgproc::filterSep_singlePass_oclsrc, opts);
if (k.empty())
return false;
UMat src = _src.getUMat();
_dst.create(size, dtype);
UMat dst = _dst.getUMat();
int src_offset_x = static_cast<int>((src_offset % src_step) / esz);
int src_offset_y = static_cast<int>(src_offset / src_step);
src.locateROI(wholeSize, origin);
k.args(ocl::KernelArg::PtrReadOnly(src), (int)src_step, src_offset_x, src_offset_y,
wholeSize.height, wholeSize.width, ocl::KernelArg::WriteOnly(dst),
static_cast<float>(delta));
return k.run(2, gt2, lt2, false);
} }
static bool ocl_sepFilter2D( InputArray _src, OutputArray _dst, int ddepth, static bool ocl_sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
InputArray _kernelX, InputArray _kernelY, Point anchor, InputArray _kernelX, InputArray _kernelY, Point anchor,
double delta, int borderType ) double delta, int borderType )
{ {
if (abs(delta)> FLT_MIN) const ocl::Device & d = ocl::Device::getDefault();
return false; Size imgSize = _src.size();
int type = _src.type(); int type = _src.type(), sdepth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
if ( !( (type == CV_8UC1 || type == CV_8UC4 || type == CV_32FC1 || type == CV_32FC4) && if (cn > 4)
(ddepth == CV_32F || ddepth == CV_16S || ddepth == CV_8U || ddepth < 0) ) )
return false; return false;
int cn = CV_MAT_CN(type);
Mat kernelX = _kernelX.getMat().reshape(1, 1); Mat kernelX = _kernelX.getMat().reshape(1, 1);
if (1 != (kernelX.cols % 2)) if (kernelX.cols % 2 != 1)
return false; return false;
Mat kernelY = _kernelY.getMat().reshape(1, 1); Mat kernelY = _kernelY.getMat().reshape(1, 1);
if (1 != (kernelY.cols % 2)) if (kernelY.cols % 2 != 1)
return false; return false;
int sdepth = CV_MAT_DEPTH(type); if (ddepth < 0)
if( anchor.x < 0 )
anchor.x = kernelX.cols >> 1;
if( anchor.y < 0 )
anchor.y = kernelY.cols >> 1;
if( ddepth < 0 )
ddepth = sdepth; ddepth = sdepth;
CV_OCL_RUN_(kernelY.cols <= 21 && kernelX.cols <= 21 &&
imgSize.width > optimizedSepFilterLocalSize + (kernelX.cols >> 1) &&
imgSize.height > optimizedSepFilterLocalSize + (kernelY.cols >> 1) &&
(!(borderType & BORDER_ISOLATED) || _src.offset() == 0) && anchor == Point(-1, -1) &&
(d.isIntel() || (d.isAMD() && !d.hostUnifiedMemory())),
ocl_sepFilter2D_SinglePass(_src, _dst, kernelX, kernelY, delta,
borderType & ~BORDER_ISOLATED, ddepth), true)
if (anchor.x < 0)
anchor.x = kernelX.cols >> 1;
if (anchor.y < 0)
anchor.y = kernelY.cols >> 1;
UMat src = _src.getUMat(); UMat src = _src.getUMat();
Size srcWholeSize; Point srcOffset; Size srcWholeSize; Point srcOffset;
src.locateROI(srcWholeSize, srcOffset); src.locateROI(srcWholeSize, srcOffset);
if ( (0 != (srcOffset.x % 4)) ||
(0 != (src.cols % 4)) || bool fast8uc1 = type == CV_8UC1 && srcOffset.x % 4 == 0 &&
(0 != ((src.step / src.elemSize()) % 4)) src.cols % 4 == 0 && src.step % 4 == 0;
)
return false;
Size srcSize = src.size(); Size srcSize = src.size();
Size bufSize(srcSize.width, srcSize.height + kernelY.cols - 1); Size bufSize(srcSize.width, srcSize.height + kernelY.cols - 1);
UMat buf; buf.create(bufSize, CV_MAKETYPE(CV_32F, cn)); UMat buf(bufSize, CV_32FC(cn));
if (!ocl_sepRowFilter2D(src, buf, kernelX, anchor.x, borderType, false)) if (!ocl_sepRowFilter2D(src, buf, kernelX, anchor.x, borderType, ddepth, fast8uc1))
return false; return false;
_dst.create(srcSize, CV_MAKETYPE(ddepth, cn)); _dst.create(srcSize, CV_MAKETYPE(ddepth, cn));
UMat dst = _dst.getUMat(); UMat dst = _dst.getUMat();
return ocl_sepColFilter2D(buf, dst, kernelY, anchor.y, false);
return ocl_sepColFilter2D(buf, dst, kernelY, delta, anchor.y);
} }
#endif #endif

View File

@ -1917,71 +1917,73 @@ class IPPresizeInvoker :
public ParallelLoopBody public ParallelLoopBody
{ {
public: public:
IPPresizeInvoker(Mat &_src, Mat &_dst, double _inv_scale_x, double _inv_scale_y, int _mode, bool *_ok) : IPPresizeInvoker(const Mat & _src, Mat & _dst, double _inv_scale_x, double _inv_scale_y, int _mode, bool *_ok) :
ParallelLoopBody(), src(_src), dst(_dst), inv_scale_x(_inv_scale_x), inv_scale_y(_inv_scale_y), mode(_mode), ok(_ok) ParallelLoopBody(), src(_src), dst(_dst), inv_scale_x(_inv_scale_x), inv_scale_y(_inv_scale_y), mode(_mode), ok(_ok)
{ {
*ok = true; *ok = true;
IppiSize srcSize, dstSize; IppiSize srcSize, dstSize;
int type = src.type(); int type = src.type();
int specSize = 0, initSize = 0; int specSize = 0, initSize = 0;
srcSize.width = src.cols; srcSize.width = src.cols;
srcSize.height = src.rows; srcSize.height = src.rows;
dstSize.width = dst.cols; dstSize.width = dst.cols;
dstSize.height = dst.rows; dstSize.height = dst.rows;
switch (type) switch (type)
{ {
case CV_8UC1: SET_IPP_RESIZE_PTR(8u,C1); break; case CV_8UC1: SET_IPP_RESIZE_PTR(8u,C1); break;
case CV_8UC3: SET_IPP_RESIZE_PTR(8u,C3); break; case CV_8UC3: SET_IPP_RESIZE_PTR(8u,C3); break;
case CV_8UC4: SET_IPP_RESIZE_PTR(8u,C4); break; case CV_8UC4: SET_IPP_RESIZE_PTR(8u,C4); break;
case CV_16UC1: SET_IPP_RESIZE_PTR(16u,C1); break; case CV_16UC1: SET_IPP_RESIZE_PTR(16u,C1); break;
case CV_16UC3: SET_IPP_RESIZE_PTR(16u,C3); break; case CV_16UC3: SET_IPP_RESIZE_PTR(16u,C3); break;
case CV_16UC4: SET_IPP_RESIZE_PTR(16u,C4); break; case CV_16UC4: SET_IPP_RESIZE_PTR(16u,C4); break;
case CV_16SC1: SET_IPP_RESIZE_PTR(16s,C1); break; case CV_16SC1: SET_IPP_RESIZE_PTR(16s,C1); break;
case CV_16SC3: SET_IPP_RESIZE_PTR(16s,C3); break; case CV_16SC3: SET_IPP_RESIZE_PTR(16s,C3); break;
case CV_16SC4: SET_IPP_RESIZE_PTR(16s,C4); break; case CV_16SC4: SET_IPP_RESIZE_PTR(16s,C4); break;
case CV_32FC1: SET_IPP_RESIZE_PTR(32f,C1); break; case CV_32FC1: SET_IPP_RESIZE_PTR(32f,C1); break;
case CV_32FC3: SET_IPP_RESIZE_PTR(32f,C3); break; case CV_32FC3: SET_IPP_RESIZE_PTR(32f,C3); break;
case CV_32FC4: SET_IPP_RESIZE_PTR(32f,C4); break; case CV_32FC4: SET_IPP_RESIZE_PTR(32f,C4); break;
case CV_64FC1: SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(64f,C1); break; case CV_64FC1: SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(64f,C1); break;
case CV_64FC3: SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(64f,C3); break; case CV_64FC3: SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(64f,C3); break;
case CV_64FC4: SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(64f,C4); break; case CV_64FC4: SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(64f,C4); break;
default: { *ok = false; return;} break; default: { *ok = false; return; } break;
} }
} }
~IPPresizeInvoker() ~IPPresizeInvoker()
{ {
} }
virtual void operator() (const Range& range) const virtual void operator() (const Range& range) const
{ {
if (*ok == false) return; if (*ok == false)
return;
int cn = src.channels(); int cn = src.channels();
int dsty = min(cvRound(range.start * inv_scale_y), dst.rows); int dsty = min(cvRound(range.start * inv_scale_y), dst.rows);
int dstwidth = min(cvRound(src.cols * inv_scale_x), dst.cols); int dstwidth = min(cvRound(src.cols * inv_scale_x), dst.cols);
int dstheight = min(cvRound(range.end * inv_scale_y), dst.rows); int dstheight = min(cvRound(range.end * inv_scale_y), dst.rows);
IppiPoint dstOffset = { 0, dsty }, srcOffset = {0, 0}; IppiPoint dstOffset = { 0, dsty }, srcOffset = {0, 0};
IppiSize dstSize = { dstwidth, dstheight - dsty }; IppiSize dstSize = { dstwidth, dstheight - dsty };
int bufsize = 0, itemSize = (int)src.elemSize1(); int bufsize = 0, itemSize = (int)src.elemSize1();
CHECK_IPP_STATUS(getBufferSizeFunc(pSpec, dstSize, cn, &bufsize)); CHECK_IPP_STATUS(getBufferSizeFunc(pSpec, dstSize, cn, &bufsize));
CHECK_IPP_STATUS(getSrcOffsetFunc(pSpec, dstOffset, &srcOffset)); CHECK_IPP_STATUS(getSrcOffsetFunc(pSpec, dstOffset, &srcOffset));
Ipp8u* pSrc = (Ipp8u*)src.data + (int)src.step[0] * srcOffset.y + srcOffset.x * cn * itemSize; Ipp8u* pSrc = (Ipp8u*)src.data + (int)src.step[0] * srcOffset.y + srcOffset.x * cn * itemSize;
Ipp8u* pDst = (Ipp8u*)dst.data + (int)dst.step[0] * dstOffset.y + dstOffset.x * cn * itemSize; Ipp8u* pDst = (Ipp8u*)dst.data + (int)dst.step[0] * dstOffset.y + dstOffset.x * cn * itemSize;
AutoBuffer<uchar> buf(bufsize + 64); AutoBuffer<uchar> buf(bufsize + 64);
uchar* bufptr = alignPtr((uchar*)buf, 32); uchar* bufptr = alignPtr((uchar*)buf, 32);
if( func( pSrc, (int)src.step[0], pDst, (int)dst.step[0], dstOffset, dstSize, ippBorderRepl, 0, pSpec, bufptr ) < 0 )
*ok = false;
}
if( func( pSrc, (int)src.step[0], pDst, (int)dst.step[0], dstOffset, dstSize, ippBorderRepl, 0, pSpec, bufptr ) < 0 )
*ok = false;
}
private: private:
Mat &src; Mat & src;
Mat &dst; Mat & dst;
double inv_scale_x; double inv_scale_x;
double inv_scale_y; double inv_scale_y;
void *pSpec; void *pSpec;
@ -1993,12 +1995,13 @@ private:
bool *ok; bool *ok;
const IPPresizeInvoker& operator= (const IPPresizeInvoker&); const IPPresizeInvoker& operator= (const IPPresizeInvoker&);
}; };
#endif #endif
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
static void ocl_computeResizeAreaTabs(int ssize, int dsize, double scale, int * const map_tab, static void ocl_computeResizeAreaTabs(int ssize, int dsize, double scale, int * const map_tab,
float * const alpha_tab, int * const ofs_tab) float * const alpha_tab, int * const ofs_tab)
{ {
int k = 0, dx = 0; int k = 0, dx = 0;
for ( ; dx < dsize; dx++) for ( ; dx < dsize; dx++)
@ -2049,8 +2052,16 @@ static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
{ {
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
double inv_fx = 1. / fx, inv_fy = 1. / fy; double inv_fx = 1.0 / fx, inv_fy = 1.0 / fy;
float inv_fxf = (float)inv_fx, inv_fyf = (float)inv_fy; float inv_fxf = (float)inv_fx, inv_fyf = (float)inv_fy;
int iscale_x = saturate_cast<int>(inv_fx), iscale_y = saturate_cast<int>(inv_fx);
bool is_area_fast = std::abs(inv_fx - iscale_x) < DBL_EPSILON &&
std::abs(inv_fy - iscale_y) < DBL_EPSILON;
// in case of scale_x && scale_y is equal to 2
// INTER_AREA (fast) also is equal to INTER_LINEAR
if( interpolation == INTER_LINEAR && is_area_fast && iscale_x == 2 && iscale_y == 2 )
/*interpolation = INTER_AREA*/(void)0; // INTER_AREA is slower
if( !(cn <= 4 && if( !(cn <= 4 &&
(interpolation == INTER_NEAREST || interpolation == INTER_LINEAR || (interpolation == INTER_NEAREST || interpolation == INTER_LINEAR ||
@ -2061,39 +2072,105 @@ static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
_dst.create(dsize, type); _dst.create(dsize, type);
UMat dst = _dst.getUMat(); UMat dst = _dst.getUMat();
Size ssize = src.size();
ocl::Kernel k; ocl::Kernel k;
size_t globalsize[] = { dst.cols, dst.rows }; size_t globalsize[] = { dst.cols, dst.rows };
if (interpolation == INTER_LINEAR) if (interpolation == INTER_LINEAR)
{ {
int wdepth = std::max(depth, CV_32S);
int wtype = CV_MAKETYPE(wdepth, cn);
char buf[2][32]; char buf[2][32];
k.create("resizeLN", ocl::imgproc::resize_oclsrc,
format("-D INTER_LINEAR -D depth=%d -D PIXTYPE=%s -D PIXTYPE1=%s " // integer path is slower because of CPU part, so it's disabled
"-D WORKTYPE=%s -D convertToWT=%s -D convertToDT=%s -D cn=%d", if (depth == CV_8U && ((void)0, 0))
depth, ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype), {
ocl::convertTypeStr(depth, wdepth, cn, buf[0]), AutoBuffer<uchar> _buffer((dsize.width + dsize.height)*(sizeof(int) + sizeof(short)*2));
ocl::convertTypeStr(wdepth, depth, cn, buf[1]), int* xofs = (int*)(uchar*)_buffer, * yofs = xofs + dsize.width;
cn)); short* ialpha = (short*)(yofs + dsize.height), * ibeta = ialpha + dsize.width*2;
float fxx, fyy;
int sx, sy;
for (int dx = 0; dx < dsize.width; dx++)
{
fxx = (float)((dx+0.5)*inv_fx - 0.5);
sx = cvFloor(fxx);
fxx -= sx;
if (sx < 0)
fxx = 0, sx = 0;
if (sx >= ssize.width-1)
fxx = 0, sx = ssize.width-1;
xofs[dx] = sx;
ialpha[dx*2 + 0] = saturate_cast<short>((1.f - fxx) * INTER_RESIZE_COEF_SCALE);
ialpha[dx*2 + 1] = saturate_cast<short>(fxx * INTER_RESIZE_COEF_SCALE);
}
for (int dy = 0; dy < dsize.height; dy++)
{
fyy = (float)((dy+0.5)*inv_fy - 0.5);
sy = cvFloor(fyy);
fyy -= sy;
yofs[dy] = sy;
ibeta[dy*2 + 0] = saturate_cast<short>((1.f - fyy) * INTER_RESIZE_COEF_SCALE);
ibeta[dy*2 + 1] = saturate_cast<short>(fyy * INTER_RESIZE_COEF_SCALE);
}
int wdepth = std::max(depth, CV_32S), wtype = CV_MAKETYPE(wdepth, cn);
UMat coeffs;
Mat(1, static_cast<int>(_buffer.size()), CV_8UC1, (uchar *)_buffer).copyTo(coeffs);
k.create("resizeLN", ocl::imgproc::resize_oclsrc,
format("-D INTER_LINEAR_INTEGER -D depth=%d -D T=%s -D T1=%s "
"-D WT=%s -D convertToWT=%s -D convertToDT=%s -D cn=%d "
"-D INTER_RESIZE_COEF_BITS=%d",
depth, ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype),
ocl::convertTypeStr(depth, wdepth, cn, buf[0]),
ocl::convertTypeStr(wdepth, depth, cn, buf[1]),
cn, INTER_RESIZE_COEF_BITS));
if (k.empty())
return false;
k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst),
ocl::KernelArg::PtrReadOnly(coeffs));
}
else
{
int wdepth = std::max(depth, CV_32S), wtype = CV_MAKETYPE(wdepth, cn);
k.create("resizeLN", ocl::imgproc::resize_oclsrc,
format("-D INTER_LINEAR -D depth=%d -D T=%s -D T1=%s "
"-D WT=%s -D convertToWT=%s -D convertToDT=%s -D cn=%d "
"-D INTER_RESIZE_COEF_BITS=%d",
depth, ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype),
ocl::convertTypeStr(depth, wdepth, cn, buf[0]),
ocl::convertTypeStr(wdepth, depth, cn, buf[1]),
cn, INTER_RESIZE_COEF_BITS));
if (k.empty())
return false;
k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst),
(float)inv_fx, (float)inv_fy);
}
} }
else if (interpolation == INTER_NEAREST) else if (interpolation == INTER_NEAREST)
{ {
k.create("resizeNN", ocl::imgproc::resize_oclsrc, k.create("resizeNN", ocl::imgproc::resize_oclsrc,
format("-D INTER_NEAREST -D PIXTYPE=%s -D PIXTYPE1=%s -D cn=%d", format("-D INTER_NEAREST -D T=%s -D T1=%s -D cn=%d",
ocl::memopTypeToStr(type), ocl::memopTypeToStr(depth), cn)); ocl::memopTypeToStr(type), ocl::memopTypeToStr(depth), cn));
if (k.empty())
return false;
k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst),
(float)inv_fx, (float)inv_fy);
} }
else if (interpolation == INTER_AREA) else if (interpolation == INTER_AREA)
{ {
int iscale_x = saturate_cast<int>(inv_fx);
int iscale_y = saturate_cast<int>(inv_fy);
bool is_area_fast = std::abs(inv_fx - iscale_x) < DBL_EPSILON &&
std::abs(inv_fy - iscale_y) < DBL_EPSILON;
int wdepth = std::max(depth, is_area_fast ? CV_32S : CV_32F); int wdepth = std::max(depth, is_area_fast ? CV_32S : CV_32F);
int wtype = CV_MAKE_TYPE(wdepth, cn); int wtype = CV_MAKE_TYPE(wdepth, cn);
char cvt[2][40]; char cvt[2][40];
String buildOption = format("-D INTER_AREA -D PIXTYPE=%s -D PIXTYPE1=%s -D WTV=%s -D convertToWTV=%s -D cn=%d", String buildOption = format("-D INTER_AREA -D T=%s -D T1=%s -D WTV=%s -D convertToWTV=%s -D cn=%d",
ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype), ocl::typeToStr(type), ocl::typeToStr(depth), ocl::typeToStr(wtype),
ocl::convertTypeStr(depth, wdepth, cn, cvt[0]), cn); ocl::convertTypeStr(depth, wdepth, cn, cvt[0]), cn);
@ -2103,7 +2180,7 @@ static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
if (is_area_fast) if (is_area_fast)
{ {
int wdepth2 = std::max(CV_32F, depth), wtype2 = CV_MAKE_TYPE(wdepth2, cn); int wdepth2 = std::max(CV_32F, depth), wtype2 = CV_MAKE_TYPE(wdepth2, cn);
buildOption = buildOption + format(" -D convertToPIXTYPE=%s -D WT2V=%s -D convertToWT2V=%s -D INTER_AREA_FAST" buildOption = buildOption + format(" -D convertToT=%s -D WT2V=%s -D convertToWT2V=%s -D INTER_AREA_FAST"
" -D XSCALE=%d -D YSCALE=%d -D SCALE=%ff", " -D XSCALE=%d -D YSCALE=%d -D SCALE=%ff",
ocl::convertTypeStr(wdepth2, depth, cn, cvt[0]), ocl::convertTypeStr(wdepth2, depth, cn, cvt[0]),
ocl::typeToStr(wtype2), ocl::convertTypeStr(wdepth, wdepth2, cn, cvt[1]), ocl::typeToStr(wtype2), ocl::convertTypeStr(wdepth, wdepth2, cn, cvt[1]),
@ -2126,12 +2203,11 @@ static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
} }
else else
{ {
buildOption = buildOption + format(" -D convertToPIXTYPE=%s", ocl::convertTypeStr(wdepth, depth, cn, cvt[0])); buildOption = buildOption + format(" -D convertToT=%s", ocl::convertTypeStr(wdepth, depth, cn, cvt[0]));
k.create("resizeAREA", ocl::imgproc::resize_oclsrc, buildOption); k.create("resizeAREA", ocl::imgproc::resize_oclsrc, buildOption);
if (k.empty()) if (k.empty())
return false; return false;
Size ssize = src.size();
int xytab_size = (ssize.width + ssize.height) << 1; int xytab_size = (ssize.width + ssize.height) << 1;
int tabofs_size = dsize.height + dsize.width + 2; int tabofs_size = dsize.height + dsize.width + 2;
@ -2161,11 +2237,6 @@ static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
return k.run(2, globalsize, NULL, false); return k.run(2, globalsize, NULL, false);
} }
if( k.empty() )
return false;
k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst),
(float)inv_fx, (float)inv_fy);
return k.run(2, globalsize, 0, false); return k.run(2, globalsize, 0, false);
} }

View File

@ -42,7 +42,6 @@
#include "precomp.hpp" #include "precomp.hpp"
#include <limits.h> #include <limits.h>
#include <stdio.h>
#include "opencl_kernels.hpp" #include "opencl_kernels.hpp"
/****************************************************************************************\ /****************************************************************************************\
@ -1291,9 +1290,10 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, Mat kernel,
{ {
CV_Assert(op == MORPH_ERODE || op == MORPH_DILATE); CV_Assert(op == MORPH_ERODE || op == MORPH_DILATE);
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0; bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
if (_src.depth() == CV_64F && !doubleSupport) if (depth == CV_64F && !doubleSupport)
return false; return false;
UMat kernel8U; UMat kernel8U;
@ -1324,13 +1324,14 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, Mat kernel,
return false; return false;
static const char * const op2str[] = { "ERODE", "DILATE" }; static const char * const op2str[] = { "ERODE", "DILATE" };
String buildOptions = format("-D RADIUSX=%d -D RADIUSY=%d -D LSIZE0=%d -D LSIZE1=%d -D %s%s%s -D GENTYPE=%s -D DEPTH_%d", String buildOptions = format("-D RADIUSX=%d -D RADIUSY=%d -D LSIZE0=%d -D LSIZE1=%d -D %s%s%s"
anchor.x, anchor.y, (int)localThreads[0], (int)localThreads[1], op2str[op], " -D T=%s -D DEPTH_%d -D cn=%d -D T1=%s", anchor.x, anchor.y,
(int)localThreads[0], (int)localThreads[1], op2str[op],
doubleSupport ? " -D DOUBLE_SUPPORT" : "", rectKernel ? " -D RECTKERNEL" : "", doubleSupport ? " -D DOUBLE_SUPPORT" : "", rectKernel ? " -D RECTKERNEL" : "",
ocl::typeToStr(_src.type()), _src.depth() ); ocl::typeToStr(_src.type()), _src.depth(), cn, ocl::typeToStr(depth));
std::vector<ocl::Kernel> kernels; std::vector<ocl::Kernel> kernels;
for (int i = 0; i<iterations; i++) for (int i = 0; i < iterations; i++)
{ {
ocl::Kernel k("morph", ocl::imgproc::morph_oclsrc, buildOptions); ocl::Kernel k("morph", ocl::imgproc::morph_oclsrc, buildOptions);
if (k.empty()) if (k.empty())
@ -1341,38 +1342,35 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, Mat kernel,
_dst.create(src.size(), src.type()); _dst.create(src.size(), src.type());
UMat dst = _dst.getUMat(); UMat dst = _dst.getUMat();
if( iterations== 1 && src.u != dst.u) if (iterations == 1 && src.u != dst.u)
{ {
Size wholesize; Size wholesize;
Point ofs; Point ofs;
src.locateROI(wholesize, ofs); src.locateROI(wholesize, ofs);
int wholecols = wholesize.width, wholerows = wholesize.height; int wholecols = wholesize.width, wholerows = wholesize.height;
int idxArg = 0; kernels[0].args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnlyNoSize(dst),
idxArg = kernels[0].set(idxArg, ocl::KernelArg::ReadOnlyNoSize(src)); ofs.x, ofs.y, src.cols, src.rows, ocl::KernelArg::PtrReadOnly(kernel8U),
idxArg = kernels[0].set(idxArg, ocl::KernelArg::WriteOnlyNoSize(dst)); wholecols, wholerows);
idxArg = kernels[0].set(idxArg, ofs.x);
idxArg = kernels[0].set(idxArg, ofs.y);
idxArg = kernels[0].set(idxArg, src.cols);
idxArg = kernels[0].set(idxArg, src.rows);
idxArg = kernels[0].set(idxArg, ocl::KernelArg::PtrReadOnly(kernel8U));
idxArg = kernels[0].set(idxArg, wholecols);
idxArg = kernels[0].set(idxArg, wholerows);
return kernels[0].run(2, globalThreads, localThreads, false); return kernels[0].run(2, globalThreads, localThreads, false);
} }
for(int i = 0; i< iterations; i++) for (int i = 0; i < iterations; i++)
{ {
UMat source; UMat source;
Size wholesize; Size wholesize;
Point ofs; Point ofs;
if( i == 0)
if (i == 0)
{ {
int cols = src.cols, rows = src.rows; int cols = src.cols, rows = src.rows;
src.locateROI(wholesize,ofs); src.locateROI(wholesize,ofs);
src.adjustROI(ofs.y, wholesize.height - rows - ofs.y, ofs.x, wholesize.width - cols - ofs.x); src.adjustROI(ofs.y, wholesize.height - rows - ofs.y, ofs.x, wholesize.width - cols - ofs.x);
src.copyTo(source); if(src.u != dst.u)
source = src;
else
src.copyTo(source);
src.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x); src.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x);
source.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x); source.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x);
} }
@ -1385,20 +1383,11 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, Mat kernel,
dst.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x); dst.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x);
source.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x); source.adjustROI(-ofs.y, -wholesize.height + rows + ofs.y, -ofs.x, -wholesize.width + cols + ofs.x);
} }
source.locateROI(wholesize, ofs); source.locateROI(wholesize, ofs);
int wholecols = wholesize.width, wholerows = wholesize.height;
int idxArg = 0; kernels[i].args(ocl::KernelArg::ReadOnlyNoSize(source), ocl::KernelArg::WriteOnlyNoSize(dst),
idxArg = kernels[i].set(idxArg, ocl::KernelArg::ReadOnlyNoSize(source)); ofs.x, ofs.y, source.cols, source.rows, ocl::KernelArg::PtrReadOnly(kernel8U),
idxArg = kernels[i].set(idxArg, ocl::KernelArg::WriteOnlyNoSize(dst)); wholesize.width, wholesize.height);
idxArg = kernels[i].set(idxArg, ofs.x);
idxArg = kernels[i].set(idxArg, ofs.y);
idxArg = kernels[i].set(idxArg, source.cols);
idxArg = kernels[i].set(idxArg, source.rows);
idxArg = kernels[i].set(idxArg, ocl::KernelArg::PtrReadOnly(kernel8U));
idxArg = kernels[i].set(idxArg, wholecols);
idxArg = kernels[i].set(idxArg, wholerows);
if (!kernels[i].run(2, globalThreads, localThreads, false)) if (!kernels[i].run(2, globalThreads, localThreads, false))
return false; return false;
@ -1414,7 +1403,7 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
int borderType, const Scalar& borderValue ) int borderType, const Scalar& borderValue )
{ {
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
int src_type = _src.type(), dst_type = _dst.type(), int src_type = _src.type(),
src_cn = CV_MAT_CN(src_type), src_depth = CV_MAT_DEPTH(src_type); src_cn = CV_MAT_CN(src_type), src_depth = CV_MAT_DEPTH(src_type);
#endif #endif
@ -1427,13 +1416,13 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
return; return;
#endif #endif
if( iterations == 0 || kernel.rows*kernel.cols == 1 ) if (iterations == 0 || kernel.rows*kernel.cols == 1)
{ {
_src.copyTo(_dst); _src.copyTo(_dst);
return; return;
} }
if( !kernel.data ) if (!kernel.data)
{ {
kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2)); kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));
anchor = Point(iterations, iterations); anchor = Point(iterations, iterations);
@ -1449,8 +1438,7 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
iterations = 1; iterations = 1;
} }
CV_OCL_RUN(_dst.isUMat() && _src.size() == _dst.size() && src_type == dst_type && CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2 && src_cn <= 4 &&
_src.dims() <= 2 && (src_cn == 1 || src_cn == 4) &&
(src_depth == CV_8U || src_depth == CV_32F || src_depth == CV_64F ) && (src_depth == CV_8U || src_depth == CV_32F || src_depth == CV_64F ) &&
borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue() && borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue() &&
(op == MORPH_ERODE || op == MORPH_DILATE), (op == MORPH_ERODE || op == MORPH_DILATE),

View File

@ -32,6 +32,28 @@
// or tort (including negligence or otherwise) arising in any way out of // 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. // the use of this software, even if advised of the possibility of such damage.
#if cn != 3
#define loadpix(addr) *(__global const uchar_t *)(addr)
#define storepix(val, addr) *(__global uchar_t *)(addr) = val
#define TSIZE cn
#else
#define loadpix(addr) vload3(0, (__global const uchar *)(addr))
#define storepix(val, addr) vstore3(val, 0, (__global uchar *)(addr))
#define TSIZE 3
#endif
#if cn == 1
#define SUM(a) a
#elif cn == 2
#define SUM(a) a.x + a.y
#elif cn == 3
#define SUM(a) a.x + a.y + a.z
#elif cn == 4
#define SUM(a) a.x + a.y + a.z + a.w
#else
#error "cn should be <= 4"
#endif
__kernel void bilateral(__global const uchar * src, int src_step, int src_offset, __kernel void bilateral(__global const uchar * src, int src_step, int src_offset,
__global uchar * dst, int dst_step, int dst_offset, int dst_rows, int dst_cols, __global uchar * dst, int dst_step, int dst_offset, int dst_rows, int dst_cols,
__constant float * color_weight, __constant float * space_weight, __constant int * space_ofs) __constant float * color_weight, __constant float * space_weight, __constant int * space_ofs)
@ -41,19 +63,23 @@ __kernel void bilateral(__global const uchar * src, int src_step, int src_offset
if (y < dst_rows && x < dst_cols) if (y < dst_rows && x < dst_cols)
{ {
int src_index = mad24(y + radius, src_step, x + radius + src_offset); int src_index = mad24(y + radius, src_step, mad24(x + radius, TSIZE, src_offset));
int dst_index = mad24(y, dst_step, x + dst_offset); int dst_index = mad24(y, dst_step, mad24(x, TSIZE, dst_offset));
float sum = 0.f, wsum = 0.f;
int val0 = convert_int(src[src_index]); float_t sum = (float_t)(0.0f);
float wsum = 0.0f;
int_t val0 = convert_int_t(loadpix(src + src_index));
#pragma unroll #pragma unroll
for (int k = 0; k < maxk; k++ ) for (int k = 0; k < maxk; k++ )
{ {
int val = convert_int(src[src_index + space_ofs[k]]); int_t val = convert_int_t(loadpix(src + src_index + space_ofs[k]));
float w = space_weight[k] * color_weight[abs(val - val0)]; uint_t diff = abs(val - val0);
sum += (float)(val) * w; float w = space_weight[k] * color_weight[SUM(diff)];
sum += convert_float_t(val) * (float_t)(w);
wsum += w; wsum += w;
} }
dst[dst_index] = convert_uchar_rtz(sum / wsum + 0.5f);
storepix(convert_uchar_t(sum / (float_t)(wsum)), dst + dst_index);
} }
} }

View File

@ -47,6 +47,18 @@
#endif #endif
#endif #endif
#if cn != 3
#define loadpix(addr) *(__global const ST *)(addr)
#define storepix(val, addr) *(__global DT *)(addr) = val
#define SRCSIZE (int)sizeof(ST)
#define DSTSIZE (int)sizeof(DT)
#else
#define loadpix(addr) vload3(0, (__global const ST1 *)(addr))
#define storepix(val, addr) vstore3(val, 0, (__global DT1 *)(addr))
#define SRCSIZE (int)sizeof(ST1)*cn
#define DSTSIZE (int)sizeof(DT1)*cn
#endif
#ifdef BORDER_CONSTANT #ifdef BORDER_CONSTANT
#elif defined BORDER_REPLICATE #elif defined BORDER_REPLICATE
#define EXTRAPOLATE(x, y, minX, minY, maxX, maxY) \ #define EXTRAPOLATE(x, y, minX, minY, maxX, maxY) \
@ -123,8 +135,8 @@ inline WT readSrcPixel(int2 pos, __global const uchar * srcptr, int src_step, co
if (pos.x >= 0 && pos.y >= 0 && pos.x < srcCoords.x2 && pos.y < srcCoords.y2) if (pos.x >= 0 && pos.y >= 0 && pos.x < srcCoords.x2 && pos.y < srcCoords.y2)
#endif #endif
{ {
int src_index = mad24(pos.y, src_step, pos.x * (int)sizeof(ST)); int src_index = mad24(pos.y, src_step, pos.x * SRCSIZE);
WT value = convertToWT(*(__global const ST *)(srcptr + src_index)); WT value = convertToWT(loadpix(srcptr + src_index));
return PROCESS_ELEM(value); return PROCESS_ELEM(value);
} }
@ -143,8 +155,8 @@ inline WT readSrcPixel(int2 pos, __global const uchar * srcptr, int src_step, co
#endif #endif
srcCoords.x2, srcCoords.y2); srcCoords.x2, srcCoords.y2);
int src_index = mad24(selected_row, src_step, selected_col * (int)sizeof(ST)); int src_index = mad24(selected_row, src_step, selected_col * SRCSIZE);
WT value = convertToWT(*(__global const ST *)(srcptr + src_index)); WT value = convertToWT(loadpix(srcptr + src_index));
return PROCESS_ELEM(value); return PROCESS_ELEM(value);
#endif #endif
@ -180,7 +192,7 @@ __kernel void boxFilter(__global const uchar * srcptr, int src_step, int srcOffs
sumOfCols[local_id] = tmp_sum; sumOfCols[local_id] = tmp_sum;
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
int dst_index = mad24(y, dst_step, x * (int)sizeof(DT) + dst_offset); int dst_index = mad24(y, dst_step, mad24(x, DSTSIZE, dst_offset));
__global DT * dst = (__global DT *)(dstptr + dst_index); __global DT * dst = (__global DT *)(dstptr + dst_index);
int sy_index = 0; // current index in data[] array int sy_index = 0; // current index in data[] array
@ -196,10 +208,11 @@ __kernel void boxFilter(__global const uchar * srcptr, int src_step, int srcOffs
total_sum += sumOfCols[local_id + sx - ANCHOR_X]; total_sum += sumOfCols[local_id + sx - ANCHOR_X];
#ifdef NORMALIZE #ifdef NORMALIZE
dst[0] = convertToDT((WT)(alpha) * total_sum); DT dstval = convertToDT((WT)(alpha) * total_sum);
#else #else
dst[0] = convertToDT(total_sum); DT dstval = convertToDT(total_sum);
#endif #endif
storepix(dstval, dst);
} }
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);

View File

@ -43,6 +43,18 @@
// //
//M*/ //M*/
#ifdef OP_SOBEL
#if cn != 3
#define loadpix(addr) convertToIntT(*(__global const ucharT *)(addr))
#define storepix(val, addr) *(__global shortT *)(addr) = convertToShortT(val)
#define shortSize (int)sizeof(shortT)
#else
#define loadpix(addr) convertToIntT(vload3(0, (__global const uchar *)(addr)))
#define storepix(val, addr) vstore3(convertToShortT(val), 0, (__global short *)(addr))
#define shortSize (int)sizeof(short) * cn
#endif
// Smoothing perpendicular to the derivative direction with a triangle filter // Smoothing perpendicular to the derivative direction with a triangle filter
// only support 3x3 Sobel kernel // only support 3x3 Sobel kernel
// h (-1) = 1, h (0) = 2, h (1) = 1 // h (-1) = 1, h (0) = 2, h (1) = 1
@ -54,11 +66,9 @@
// dx_buf output dx buffer // dx_buf output dx buffer
// dy_buf output dy buffer // dy_buf output dy buffer
__kernel void __attribute__((reqd_work_group_size(16, 16, 1))) __kernel void calcSobelRowPass(__global const uchar * src, int src_step, int src_offset, int rows, int cols,
calcSobelRowPass __global uchar * dx_buf, int dx_buf_step, int dx_buf_offset,
(__global const uchar * src, int src_step, int src_offset, int rows, int cols, __global uchar * dy_buf, int dy_buf_step, int dy_buf_offset)
__global uchar * dx_buf, int dx_buf_step, int dx_buf_offset,
__global uchar * dy_buf, int dy_buf_step, int dy_buf_offset)
{ {
int gidx = get_global_id(0); int gidx = get_global_id(0);
int gidy = get_global_id(1); int gidy = get_global_id(1);
@ -66,34 +76,39 @@ calcSobelRowPass
int lidx = get_local_id(0); int lidx = get_local_id(0);
int lidy = get_local_id(1); int lidy = get_local_id(1);
__local int smem[16][18]; __local intT smem[16][18];
smem[lidy][lidx + 1] = src[mad24(src_step, min(gidy, rows - 1), gidx + src_offset)]; smem[lidy][lidx + 1] = loadpix(src + mad24(src_step, min(gidy, rows - 1), mad24(gidx, cn, src_offset)));
if (lidx == 0) if (lidx == 0)
{ {
smem[lidy][0] = src[mad24(src_step, min(gidy, rows - 1), max(gidx - 1, 0) + src_offset)]; smem[lidy][0] = loadpix(src + mad24(src_step, min(gidy, rows - 1), mad24(max(gidx - 1, 0), cn, src_offset)));
smem[lidy][17] = src[mad24(src_step, min(gidy, rows - 1), min(gidx + 16, cols - 1) + src_offset)]; smem[lidy][17] = loadpix(src + mad24(src_step, min(gidy, rows - 1), mad24(min(gidx + 16, cols - 1), cn, src_offset)));
} }
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
if (gidy < rows && gidx < cols) if (gidy < rows && gidx < cols)
{ {
*(__global short *)(dx_buf + mad24(gidy, dx_buf_step, gidx * (int)sizeof(short) + dx_buf_offset)) = storepix(smem[lidy][lidx + 2] - smem[lidy][lidx],
smem[lidy][lidx + 2] - smem[lidy][lidx]; dx_buf + mad24(gidy, dx_buf_step, mad24(gidx, shortSize, dx_buf_offset)));
*(__global short *)(dy_buf + mad24(gidy, dy_buf_step, gidx * (int)sizeof(short) + dy_buf_offset)) = storepix(mad24(2, smem[lidy][lidx + 1], smem[lidy][lidx] + smem[lidy][lidx + 2]),
smem[lidy][lidx] + 2 * smem[lidy][lidx + 1] + smem[lidy][lidx + 2]; dy_buf + mad24(gidy, dy_buf_step, mad24(gidx, shortSize, dy_buf_offset)));
} }
} }
inline int calc(short x, short y) #elif defined OP_MAG_BUF || defined OP_MAG
inline intT calc(shortT x, shortT y)
{ {
#ifdef L2GRAD #ifdef L2GRAD
return x * x + y * y; intT intx = convertToIntT(x), inty = convertToIntT(y);
return intx * intx + inty * inty;
#else #else
return (x >= 0 ? x : -x) + (y >= 0 ? y : -y); return convertToIntT( (x >= (shortT)(0) ? x : -x) + (y >= (shortT)(0) ? y : -y) );
#endif #endif
} }
#ifdef OP_MAG
// calculate the magnitude of the filter pass combining both x and y directions // calculate the magnitude of the filter pass combining both x and y directions
// This is the non-buffered version(non-3x3 sobel) // This is the non-buffered version(non-3x3 sobel)
// //
@ -112,18 +127,43 @@ __kernel void calcMagnitude(__global const uchar * dxptr, int dx_step, int dx_of
if (y < rows && x < cols) if (y < rows && x < cols)
{ {
int dx_index = mad24(dx_step, y, x * (int)sizeof(short) + dx_offset); int dx_index = mad24(dx_step, y, mad24(x, (int)sizeof(short) * cn, dx_offset));
int dy_index = mad24(dy_step, y, x * (int)sizeof(short) + dy_offset); int dy_index = mad24(dy_step, y, mad24(x, (int)sizeof(short) * cn, dy_offset));
int mag_index = mad24(mag_step, y + 1, (x + 1) * (int)sizeof(int) + mag_offset); int mag_index = mad24(mag_step, y + 1, mad24(x + 1, (int)sizeof(int), mag_offset));
__global const short * dx = (__global const short *)(dxptr + dx_index); __global short * dx = (__global short *)(dxptr + dx_index);
__global const short * dy = (__global const short *)(dyptr + dy_index); __global short * dy = (__global short *)(dyptr + dy_index);
__global int * mag = (__global int *)(magptr + mag_index); __global int * mag = (__global int *)(magptr + mag_index);
mag[0] = calc(dx[0], dy[0]); int cmag = calc(dx[0], dy[0]);
#if cn > 1
short cx = dx[0], cy = dy[0];
int pmag;
#pragma unroll
for (int i = 1; i < cn; ++i)
{
pmag = calc(dx[i], dy[i]);
if (pmag > cmag)
cmag = pmag, cx = dx[i], cy = dy[i];
}
dx[0] = cx, dy[0] = cy;
#endif
mag[0] = cmag;
} }
} }
#elif defined OP_MAG_BUF
#if cn != 3
#define loadpix(addr) *(__global const shortT *)(addr)
#define shortSize (int)sizeof(shortT)
#else
#define loadpix(addr) vload3(0, (__global const short *)(addr))
#define shortSize (int)sizeof(short)*cn
#endif
// calculate the magnitude of the filter pass combining both x and y directions // calculate the magnitude of the filter pass combining both x and y directions
// This is the buffered version(3x3 sobel) // This is the buffered version(3x3 sobel)
// //
@ -132,59 +172,64 @@ __kernel void calcMagnitude(__global const uchar * dxptr, int dx_step, int dx_of
// dx direvitive in x direction output // dx direvitive in x direction output
// dy direvitive in y direction output // dy direvitive in y direction output
// mag magnitude direvitive of xy output // mag magnitude direvitive of xy output
__kernel void __attribute__((reqd_work_group_size(16, 16, 1))) __kernel void calcMagnitude_buf(__global const uchar * dx_buf, int dx_buf_step, int dx_buf_offset,
calcMagnitude_buf __global const uchar * dy_buf, int dy_buf_step, int dy_buf_offset,
(__global const short * dx_buf, int dx_buf_step, int dx_buf_offset, __global uchar * dx, int dx_step, int dx_offset,
__global const short * dy_buf, int dy_buf_step, int dy_buf_offset, __global uchar * dy, int dy_step, int dy_offset,
__global short * dx, int dx_step, int dx_offset, __global uchar * mag, int mag_step, int mag_offset, int rows, int cols)
__global short * dy, int dy_step, int dy_offset,
__global int * mag, int mag_step, int mag_offset,
int rows, int cols)
{ {
dx_buf_step /= sizeof(*dx_buf);
dx_buf_offset /= sizeof(*dx_buf);
dy_buf_step /= sizeof(*dy_buf);
dy_buf_offset /= sizeof(*dy_buf);
dx_step /= sizeof(*dx);
dx_offset /= sizeof(*dx);
dy_step /= sizeof(*dy);
dy_offset /= sizeof(*dy);
mag_step /= sizeof(*mag);
mag_offset /= sizeof(*mag);
int gidx = get_global_id(0); int gidx = get_global_id(0);
int gidy = get_global_id(1); int gidy = get_global_id(1);
int lidx = get_local_id(0); int lidx = get_local_id(0);
int lidy = get_local_id(1); int lidy = get_local_id(1);
__local short sdx[18][16]; __local shortT sdx[18][16];
__local short sdy[18][16]; __local shortT sdy[18][16];
sdx[lidy + 1][lidx] = dx_buf[gidx + min(gidy, rows - 1) * dx_buf_step + dx_buf_offset]; sdx[lidy + 1][lidx] = loadpix(dx_buf + mad24(min(gidy, rows - 1), dx_buf_step, mad24(gidx, shortSize, dx_buf_offset)));
sdy[lidy + 1][lidx] = dy_buf[gidx + min(gidy, rows - 1) * dy_buf_step + dy_buf_offset]; sdy[lidy + 1][lidx] = loadpix(dy_buf + mad24(min(gidy, rows - 1), dy_buf_step, mad24(gidx, shortSize, dy_buf_offset)));
if (lidy == 0) if (lidy == 0)
{ {
sdx[0][lidx] = dx_buf[gidx + min(max(gidy - 1, 0), rows - 1) * dx_buf_step + dx_buf_offset]; sdx[0][lidx] = loadpix(dx_buf + mad24(clamp(gidy - 1, 0, rows - 1), dx_buf_step, mad24(gidx, shortSize, dx_buf_offset)));
sdx[17][lidx] = dx_buf[gidx + min(gidy + 16, rows - 1) * dx_buf_step + dx_buf_offset]; sdx[17][lidx] = loadpix(dx_buf + mad24(min(gidy + 16, rows - 1), dx_buf_step, mad24(gidx, shortSize, dx_buf_offset)));
sdy[0][lidx] = dy_buf[gidx + min(max(gidy - 1, 0), rows - 1) * dy_buf_step + dy_buf_offset]; sdy[0][lidx] = loadpix(dy_buf + mad24(clamp(gidy - 1, 0, rows - 1), dy_buf_step, mad24(gidx, shortSize, dy_buf_offset)));
sdy[17][lidx] = dy_buf[gidx + min(gidy + 16, rows - 1) * dy_buf_step + dy_buf_offset]; sdy[17][lidx] = loadpix(dy_buf + mad24(min(gidy + 16, rows - 1), dy_buf_step, mad24(gidx, shortSize, dy_buf_offset)));
} }
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
if (gidx < cols && gidy < rows) if (gidx < cols && gidy < rows)
{ {
short x = sdx[lidy][lidx] + 2 * sdx[lidy + 1][lidx] + sdx[lidy + 2][lidx]; shortT x = sdx[lidy + 1][lidx] * (shortT)(2) + sdx[lidy][lidx] + sdx[lidy + 2][lidx];
short y = -sdy[lidy][lidx] + sdy[lidy + 2][lidx]; shortT y = -sdy[lidy][lidx] + sdy[lidy + 2][lidx];
dx[gidx + gidy * dx_step + dx_offset] = x; #if cn == 1
dy[gidx + gidy * dy_step + dy_offset] = y; *(__global short *)(dx + mad24(gidy, dx_step, mad24(gidx, shortSize, dx_offset))) = x;
*(__global short *)(dy + mad24(gidy, dy_step, mad24(gidx, shortSize, dy_offset))) = y;
mag[(gidx + 1) + (gidy + 1) * mag_step + mag_offset] = calc(x, y); *(__global int *)(mag + mad24(gidy + 1, mag_step, mad24(gidx + 1, (int)sizeof(int), mag_offset))) = calc(x, y);
#elif cn == 3
intT magv = calc(x, y);
short cx = x.x, cy = y.x;
int cmag = magv.x;
if (cmag < magv.y)
cx = x.y, cy = y.y, cmag = magv.y;
if (cmag < magv.z)
cx = x.z, cy = y.z, cmag = magv.z;
*(__global short *)(dx + mad24(gidy, dx_step, mad24(gidx, shortSize, dx_offset))) = cx;
*(__global short *)(dy + mad24(gidy, dy_step, mad24(gidx, shortSize, dy_offset))) = cy;
*(__global int *)(mag + mad24(gidy + 1, mag_step, mad24(gidx + 1, (int)sizeof(int), mag_offset))) = cmag;
#endif
} }
} }
#endif
#elif defined OP_MAP
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// 0.4142135623730950488016887242097 is tan(22.5) // 0.4142135623730950488016887242097 is tan(22.5)
@ -208,13 +253,11 @@ calcMagnitude_buf
// mag magnitudes calculated from calcMagnitude function // mag magnitudes calculated from calcMagnitude function
// map output containing raw edge types // map output containing raw edge types
__kernel void __attribute__((reqd_work_group_size(16,16,1))) __kernel void calcMap(__global const uchar * dx, int dx_step, int dx_offset,
calcMap( __global const uchar * dy, int dy_step, int dy_offset,
__global const uchar * dx, int dx_step, int dx_offset, __global const uchar * mag, int mag_step, int mag_offset,
__global const uchar * dy, int dy_step, int dy_offset, __global uchar * map, int map_step, int map_offset,
__global const uchar * mag, int mag_step, int mag_offset, int rows, int cols, int low_thresh, int high_thresh)
__global uchar * map, int map_step, int map_offset,
int rows, int cols, int low_thresh, int high_thresh)
{ {
__local int smem[18][18]; __local int smem[18][18];
@ -227,7 +270,7 @@ calcMap(
int grp_idx = get_global_id(0) & 0xFFFFF0; int grp_idx = get_global_id(0) & 0xFFFFF0;
int grp_idy = get_global_id(1) & 0xFFFFF0; int grp_idy = get_global_id(1) & 0xFFFFF0;
int tid = lidx + lidy * 16; int tid = mad24(lidy, 16, lidx);
int lx = tid % 18; int lx = tid % 18;
int ly = tid / 18; int ly = tid / 18;
@ -250,8 +293,8 @@ calcMap(
if (m > low_thresh) if (m > low_thresh)
{ {
short xs = *(__global const short *)(dx + mad24(gidy, dx_step, dx_offset + (int)sizeof(short) * gidx)); short xs = *(__global const short *)(dx + mad24(gidy, dx_step, mad24(gidx, (int)sizeof(short) * cn, dx_offset)));
short ys = *(__global const short *)(dy + mad24(gidy, dy_step, dy_offset + (int)sizeof(short) * gidx)); short ys = *(__global const short *)(dy + mad24(gidy, dy_step, mad24(gidx, (int)sizeof(short) * cn, dy_offset)));
int x = abs(xs), y = abs(ys); int x = abs(xs), y = abs(ys);
int tg22x = x * TG22; int tg22x = x * TG22;
@ -278,13 +321,15 @@ calcMap(
} }
} }
} }
*(__global int *)(map + mad24(map_step, gidy + 1, (gidx + 1) * (int)sizeof(int) + map_offset)) = edge_type; *(__global int *)(map + mad24(map_step, gidy + 1, mad24(gidx + 1, (int)sizeof(int), + map_offset))) = edge_type;
} }
} }
#undef CANNY_SHIFT #undef CANNY_SHIFT
#undef TG22 #undef TG22
#elif defined OP_HYST_LOCAL
struct PtrStepSz struct PtrStepSz
{ {
__global uchar * ptr; __global uchar * ptr;
@ -312,11 +357,9 @@ inline void set(struct PtrStepSz data, int y, int x, int value)
// stack the potiential edge points found in this kernel call // stack the potiential edge points found in this kernel call
// counter the number of potiential edge points // counter the number of potiential edge points
__kernel void __attribute__((reqd_work_group_size(16,16,1))) __kernel void edgesHysteresisLocal(__global uchar * map_ptr, int map_step, int map_offset,
edgesHysteresisLocal __global ushort2 * st, __global unsigned int * counter,
(__global uchar * map_ptr, int map_step, int map_offset, int rows, int cols)
__global ushort2 * st, __global unsigned int * counter,
int rows, int cols)
{ {
struct PtrStepSz map = { map_ptr + map_offset, map_step, rows + 1, cols + 1 }; struct PtrStepSz map = { map_ptr + map_offset, map_step, rows + 1, cols + 1 };
@ -402,6 +445,8 @@ edgesHysteresisLocal
} }
} }
#elif defined OP_HYST_GLOBAL
__constant int c_dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; __constant int c_dx[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
__constant int c_dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; __constant int c_dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
@ -409,10 +454,9 @@ __constant int c_dy[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
#define stack_size 512 #define stack_size 512
#define map_index mad24(map_step, pos.y, pos.x * (int)sizeof(int)) #define map_index mad24(map_step, pos.y, pos.x * (int)sizeof(int))
__kernel void __attribute__((reqd_work_group_size(128, 1, 1))) __kernel void edgesHysteresisGlobal(__global uchar * map, int map_step, int map_offset,
edgesHysteresisGlobal(__global uchar * map, int map_step, int map_offset, __global ushort2 * st1, __global ushort2 * st2, __global int * counter,
__global ushort2 * st1, __global ushort2 * st2, __global int * counter, int rows, int cols, int count)
int rows, int cols, int count)
{ {
map += map_offset; map += map_offset;
@ -492,6 +536,8 @@ edgesHysteresisGlobal(__global uchar * map, int map_step, int map_offset,
#undef map_index #undef map_index
#undef stack_size #undef stack_size
#elif defined OP_EDGES
// Get the edge result. egde type of value 2 will be marked as an edge point and set to 255. Otherwise 0. // Get the edge result. egde type of value 2 will be marked as an edge point and set to 255. Otherwise 0.
// map edge type mappings // map edge type mappings
// dst edge output // dst edge output
@ -504,7 +550,7 @@ __kernel void getEdges(__global const uchar * mapptr, int map_step, int map_offs
if (y < rows && x < cols) if (y < rows && x < cols)
{ {
int map_index = mad24(map_step, y + 1, (x + 1) * (int)sizeof(int) + map_offset); int map_index = mad24(map_step, y + 1, mad24(x + 1, (int)sizeof(int), map_offset));
int dst_index = mad24(dst_step, y, x + dst_offset); int dst_index = mad24(dst_step, y, x + dst_offset);
__global const int * map = (__global const int *)(mapptr + map_index); __global const int * map = (__global const int *)(mapptr + map_index);
@ -512,3 +558,5 @@ __kernel void getEdges(__global const uchar * mapptr, int map_step, int map_offs
dst[dst_index] = (uchar)(-(map[0] >> 1)); dst[dst_index] = (uchar)(-(map[0] >> 1));
} }
} }
#endif

View File

@ -122,7 +122,7 @@
} }
#ifdef BORDER_REFLECT #ifdef BORDER_REFLECT
#define EXTRAPOLATE(x, y, minX, minY, maxX, maxY) EXTRAPOLATE_(x, y, minX, minY, maxX, maxY, 0) #define EXTRAPOLATE(x, y, minX, minY, maxX, maxY) EXTRAPOLATE_(x, y, minX, minY, maxX, maxY, 0)
#elif defined(BORDER_REFLECT_101) #elif defined(BORDER_REFLECT_101) || defined(BORDER_REFLECT101)
#define EXTRAPOLATE(x, y, minX, minY, maxX, maxY) EXTRAPOLATE_(x, y, minX, minY, maxX, maxY, 1) #define EXTRAPOLATE(x, y, minX, minY, maxX, maxY) EXTRAPOLATE_(x, y, minX, minY, maxX, maxY, 1)
#endif #endif
#else #else
@ -142,109 +142,49 @@
} }
#endif #endif
#if USE_DOUBLE #ifdef DOUBLE_SUPPORT
#ifdef cl_amd_fp64 #ifdef cl_amd_fp64
#pragma OPENCL EXTENSION cl_amd_fp64:enable #pragma OPENCL EXTENSION cl_amd_fp64:enable
#elif defined (cl_khr_fp64) #elif defined (cl_khr_fp64)
#pragma OPENCL EXTENSION cl_khr_fp64:enable #pragma OPENCL EXTENSION cl_khr_fp64:enable
#endif #endif
#define FPTYPE double
#define CONVERT_TO_FPTYPE CAT(convert_double, VEC_SIZE)
#else
#define FPTYPE float
#define CONVERT_TO_FPTYPE CAT(convert_float, VEC_SIZE)
#endif #endif
#if DATA_DEPTH == 0 #if cn != 3
#define BASE_TYPE uchar #define loadpix(addr) *(__global const srcT *)(addr)
#elif DATA_DEPTH == 1 #define storepix(val, addr) *(__global dstT *)(addr) = val
#define BASE_TYPE char #define SRCSIZE (int)sizeof(srcT)
#elif DATA_DEPTH == 2 #define DSTSIZE (int)sizeof(dstT)
#define BASE_TYPE ushort
#elif DATA_DEPTH == 3
#define BASE_TYPE short
#elif DATA_DEPTH == 4
#define BASE_TYPE int
#elif DATA_DEPTH == 5
#define BASE_TYPE float
#elif DATA_DEPTH == 6
#define BASE_TYPE double
#else #else
#error data_depth #define loadpix(addr) vload3(0, (__global const srcT1 *)(addr))
#define storepix(val, addr) vstore3(val, 0, (__global dstT1 *)(addr))
#define SRCSIZE (int)sizeof(srcT1) * cn
#define DSTSIZE (int)sizeof(dstT1) * cn
#endif #endif
#define __CAT(x, y) x##y #define noconvert
#define CAT(x, y) __CAT(x, y)
#define uchar1 uchar
#define char1 char
#define ushort1 ushort
#define short1 short
#define int1 int
#define float1 float
#define double1 double
#define convert_uchar1_sat_rte convert_uchar_sat_rte
#define convert_char1_sat_rte convert_char_sat_rte
#define convert_ushort1_sat_rte convert_ushort_sat_rte
#define convert_short1_sat_rte convert_short_sat_rte
#define convert_int1_sat_rte convert_int_sat_rte
#define convert_float1
#define convert_double1
#if DATA_DEPTH == 5 || DATA_DEPTH == 6
#define CONVERT_TO_TYPE CAT(CAT(convert_, BASE_TYPE), VEC_SIZE)
#else
#define CONVERT_TO_TYPE CAT(CAT(CAT(convert_, BASE_TYPE), VEC_SIZE), _sat_rte)
#endif
#define VEC_SIZE DATA_CHAN
#define VEC_TYPE CAT(BASE_TYPE, VEC_SIZE)
#define TYPE VEC_TYPE
#define SCALAR_TYPE CAT(FPTYPE, VEC_SIZE)
#define INTERMEDIATE_TYPE CAT(FPTYPE, VEC_SIZE)
struct RectCoords struct RectCoords
{ {
int x1, y1, x2, y2; int x1, y1, x2, y2;
}; };
//#define DEBUG inline WT readSrcPixel(int2 pos, __global const uchar * srcptr, int src_step, const struct RectCoords srcCoords)
#ifdef DEBUG
#define DEBUG_ONLY(x) x
#define ASSERT(condition) do { if (!(condition)) { printf("BUG in boxFilter kernel (global=%d,%d): " #condition "\n", get_global_id(0), get_global_id(1)); } } while (0)
#else
#define DEBUG_ONLY(x) (void)0
#define ASSERT(condition) (void)0
#endif
inline INTERMEDIATE_TYPE readSrcPixel(int2 pos, __global const uchar* srcptr, int srcstep, const struct RectCoords srcCoords
#ifdef BORDER_CONSTANT
, SCALAR_TYPE borderValue
#endif
)
{ {
#ifdef BORDER_ISOLATED #ifdef BORDER_ISOLATED
if(pos.x >= srcCoords.x1 && pos.y >= srcCoords.y1 && pos.x < srcCoords.x2 && pos.y < srcCoords.y2) if (pos.x >= srcCoords.x1 && pos.y >= srcCoords.y1 && pos.x < srcCoords.x2 && pos.y < srcCoords.y2)
#else #else
if(pos.x >= 0 && pos.y >= 0 && pos.x < srcCoords.x2 && pos.y < srcCoords.y2) if (pos.x >= 0 && pos.y >= 0 && pos.x < srcCoords.x2 && pos.y < srcCoords.y2)
#endif #endif
{ {
//__global TYPE* ptr = (__global TYPE*)((__global char*)src + pos.x * sizeof(TYPE) + pos.y * srcStepBytes); return convertToWT(loadpix(srcptr + mad24(pos.y, src_step, pos.x * SRCSIZE)));
__global TYPE* ptr = (__global TYPE*)(srcptr + pos.y * srcstep + pos.x * sizeof(TYPE));
return CONVERT_TO_FPTYPE(*ptr);
} }
else else
{ {
#ifdef BORDER_CONSTANT #ifdef BORDER_CONSTANT
return borderValue; return (WT)(0);
#else #else
int selected_col = pos.x; int selected_col = pos.x, selected_row = pos.y;
int selected_row = pos.y;
EXTRAPOLATE(selected_col, selected_row, EXTRAPOLATE(selected_col, selected_row,
#ifdef BORDER_ISOLATED #ifdef BORDER_ISOLATED
@ -255,68 +195,43 @@ inline INTERMEDIATE_TYPE readSrcPixel(int2 pos, __global const uchar* srcptr, in
srcCoords.x2, srcCoords.y2 srcCoords.x2, srcCoords.y2
); );
// debug border mapping return convertToWT(loadpix(srcptr + mad24(selected_row, src_step, selected_col * SRCSIZE)));
//printf("pos=%d,%d --> %d, %d\n", pos.x, pos.y, selected_col, selected_row);
pos = (int2)(selected_col, selected_row);
if(pos.x >= 0 && pos.y >= 0 && pos.x < srcCoords.x2 && pos.y < srcCoords.y2)
{
//__global TYPE* ptr = (__global TYPE*)((__global char*)src + pos.x * sizeof(TYPE) + pos.y * srcStepBytes);
__global TYPE* ptr = (__global TYPE*)(srcptr + pos.y * srcstep + pos.x * sizeof(TYPE));
return CONVERT_TO_FPTYPE(*ptr);
}
else
{
// for debug only
DEBUG_ONLY(printf("BUG in boxFilter kernel\n"));
return (FPTYPE)(0.0f);
}
#endif #endif
} }
} }
// INPUT PARAMETER: BLOCK_SIZE_Y (via defines) #define DIG(a) a,
__constant WT1 kernelData[] = { COEFF };
__kernel __kernel void filter2D(__global const uchar * srcptr, int src_step, int srcOffsetX, int srcOffsetY, int srcEndX, int srcEndY,
__attribute__((reqd_work_group_size(LOCAL_SIZE, 1, 1))) __global uchar * dstptr, int dst_step, int dst_offset, int rows, int cols, float delta)
void filter2D(__global const uchar* srcptr, int srcstep, int srcOffsetX, int srcOffsetY, int srcEndX, int srcEndY,
__global uchar* dstptr, int dststep, int dstoffset,
int rows, int cols,
#ifdef BORDER_CONSTANT
SCALAR_TYPE borderValue,
#endif
__constant FPTYPE* kernelData // transposed: [KERNEL_SIZE_X][KERNEL_SIZE_Y2_ALIGNED]
)
{ {
const struct RectCoords srcCoords = {srcOffsetX, srcOffsetY, srcEndX, srcEndY}; // for non-isolated border: offsetX, offsetY, wholeX, wholeY const struct RectCoords srcCoords = { srcOffsetX, srcOffsetY, srcEndX, srcEndY }; // for non-isolated border: offsetX, offsetY, wholeX, wholeY
const int local_id = get_local_id(0); int local_id = get_local_id(0);
const int x = local_id + (LOCAL_SIZE - (KERNEL_SIZE_X - 1)) * get_group_id(0) - ANCHOR_X; int x = local_id + (LOCAL_SIZE - (KERNEL_SIZE_X - 1)) * get_group_id(0) - ANCHOR_X;
const int y = get_global_id(1) * BLOCK_SIZE_Y; int y = get_global_id(1) * BLOCK_SIZE_Y;
INTERMEDIATE_TYPE data[KERNEL_SIZE_Y]; WT data[KERNEL_SIZE_Y];
__local INTERMEDIATE_TYPE sumOfCols[LOCAL_SIZE]; __local WT sumOfCols[LOCAL_SIZE];
int2 srcPos = (int2)(srcCoords.x1 + x, srcCoords.y1 + y - ANCHOR_Y); int2 srcPos = (int2)(srcCoords.x1 + x, srcCoords.y1 + y - ANCHOR_Y);
int2 pos = (int2)(x, y); int2 pos = (int2)(x, y);
__global TYPE* dstPtr = (__global TYPE*)((__global char*)dstptr + pos.y * dststep + dstoffset + pos.x * sizeof(TYPE)); // Pointer can be out of bounds! __global dstT * dst = (__global dstT *)(dstptr + mad24(pos.y, dst_step, mad24(pos.x, DSTSIZE, dst_offset))); // Pointer can be out of bounds!
bool writeResult = ((local_id >= ANCHOR_X) && (local_id < LOCAL_SIZE - (KERNEL_SIZE_X - 1 - ANCHOR_X)) && bool writeResult = local_id >= ANCHOR_X && local_id < LOCAL_SIZE - (KERNEL_SIZE_X - 1 - ANCHOR_X) &&
(pos.x >= 0) && (pos.x < cols)); pos.x >= 0 && pos.x < cols;
#if BLOCK_SIZE_Y > 1 #if BLOCK_SIZE_Y > 1
bool readAllpixels = true; bool readAllpixels = true;
int sy_index = 0; // current index in data[] array int sy_index = 0; // current index in data[] array
dstRowsMax = min(rows, pos.y + BLOCK_SIZE_Y); dstRowsMax = min(rows, pos.y + BLOCK_SIZE_Y);
for (; for ( ;
pos.y < dstRowsMax; pos.y < dstRowsMax;
pos.y++, pos.y++, dst = (__global dstT *)((__global uchar *)dst + dst_step))
dstPtr = (__global TYPE*)((__global char*)dstptr + dststep))
#endif #endif
{ {
ASSERT(pos.y < dstRowsMax);
for ( for (
#if BLOCK_SIZE_Y > 1 #if BLOCK_SIZE_Y > 1
int sy = readAllpixels ? 0 : -1; sy < (readAllpixels ? KERNEL_SIZE_Y : 0); int sy = readAllpixels ? 0 : -1; sy < (readAllpixels ? KERNEL_SIZE_Y : 0);
@ -325,27 +240,21 @@ void filter2D(__global const uchar* srcptr, int srcstep, int srcOffsetX, int src
#endif #endif
sy++, srcPos.y++) sy++, srcPos.y++)
{ {
data[sy + sy_index] = readSrcPixel(srcPos, srcptr, srcstep, srcCoords data[sy + sy_index] = readSrcPixel(srcPos, srcptr, src_step, srcCoords);
#ifdef BORDER_CONSTANT
, borderValue
#endif
);
} }
INTERMEDIATE_TYPE total_sum = 0; WT total_sum = 0;
for (int sx = 0; sx < KERNEL_SIZE_X; sx++) for (int sx = 0; sx < KERNEL_SIZE_X; sx++)
{ {
{ {
__constant FPTYPE* k = &kernelData[KERNEL_SIZE_Y2_ALIGNED * sx __constant WT1 * k = &kernelData[KERNEL_SIZE_Y2_ALIGNED * sx
#if BLOCK_SIZE_Y > 1 #if BLOCK_SIZE_Y > 1
+ KERNEL_SIZE_Y - sy_index + KERNEL_SIZE_Y - sy_index
#endif #endif
]; ];
INTERMEDIATE_TYPE tmp_sum = 0; WT tmp_sum = 0;
for (int sy = 0; sy < KERNEL_SIZE_Y; sy++) for (int sy = 0; sy < KERNEL_SIZE_Y; sy++)
{
tmp_sum += data[sy] * k[sy]; tmp_sum += data[sy] * k[sy];
}
sumOfCols[local_id] = tmp_sum; sumOfCols[local_id] = tmp_sum;
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
@ -359,14 +268,12 @@ void filter2D(__global const uchar* srcptr, int srcstep, int srcOffsetX, int src
} }
if (writeResult) if (writeResult)
{ storepix(convertToDstT(total_sum + (WT)(delta)), dst);
*dstPtr = CONVERT_TO_TYPE(total_sum);
}
#if BLOCK_SIZE_Y > 1 #if BLOCK_SIZE_Y > 1
readAllpixels = false; readAllpixels = false;
#if BLOCK_SIZE_Y > KERNEL_SIZE_Y #if BLOCK_SIZE_Y > KERNEL_SIZE_Y
sy_index = (sy_index + 1 <= KERNEL_SIZE_Y) ? sy_index + 1 : 1; sy_index = sy_index + 1 <= KERNEL_SIZE_Y ? sy_index + 1 : 1;
#else #else
sy_index++; sy_index++;
#endif #endif

View File

@ -34,47 +34,36 @@
// //
// //
#ifdef DOUBLE_SUPPORT
#ifdef cl_amd_fp64
#pragma OPENCL EXTENSION cl_amd_fp64:enable
#elif defined (cl_khr_fp64)
#pragma OPENCL EXTENSION cl_khr_fp64:enable
#endif
#endif
#define READ_TIMES_COL ((2*(RADIUSY+LSIZE1)-1)/LSIZE1) #define READ_TIMES_COL ((2*(RADIUSY+LSIZE1)-1)/LSIZE1)
#define RADIUS 1 #define RADIUS 1
#if CN ==1
#define ALIGN (((RADIUS)+3)>>2<<2)
#elif CN==2
#define ALIGN (((RADIUS)+1)>>1<<1)
#elif CN==3
#define ALIGN (((RADIUS)+3)>>2<<2)
#elif CN==4
#define ALIGN (RADIUS)
#define READ_TIMES_ROW ((2*(RADIUS+LSIZE0)-1)/LSIZE0)
#endif
#define noconvert #define noconvert
/********************************************************************************** #if CN != 3
These kernels are written for separable filters such as Sobel, Scharr, GaussianBlur. #define loadpix(addr) *(__global const srcT *)(addr)
Now(6/29/2011) the kernels only support 8U data type and the anchor of the convovle #define storepix(val, addr) *(__global dstT *)(addr) = val
kernel must be in the center. ROI is not supported either. #define SRCSIZE (int)sizeof(srcT)
Each kernels read 4 elements(not 4 pixels), save them to LDS and read the data needed #define DSTSIZE (int)sizeof(dstT)
from LDS to calculate the result. #else
The length of the convovle kernel supported is only related to the MAX size of LDS, #define loadpix(addr) vload3(0, (__global const srcT1 *)(addr))
which is HW related. #define storepix(val, addr) vstore3(val, 0, (__global dstT1 *)(addr))
Niko #define SRCSIZE (int)sizeof(srcT1)*3
6/29/2011 #define DSTSIZE (int)sizeof(dstT1)*3
The info above maybe obsolete. #endif
***********************************************************************************/
#define DIG(a) a, #define DIG(a) a,
__constant float mat_kernel[] = { COEFF }; __constant float mat_kernel[] = { COEFF };
__kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void col_filter __kernel void col_filter(__global const uchar * src, int src_step, int src_offset, int src_whole_rows, int src_whole_cols,
(__global const GENTYPE_SRC * restrict src, __global uchar * dst, int dst_step, int dst_offset, int dst_rows, int dst_cols, float delta)
const int src_step_in_pixel,
const int src_whole_cols,
const int src_whole_rows,
__global GENTYPE_DST * dst,
const int dst_offset_in_pixel,
const int dst_step_in_pixel,
const int dst_cols,
const int dst_rows)
{ {
int x = get_global_id(0); int x = get_global_id(0);
int y = get_global_id(1); int y = get_global_id(1);
@ -82,38 +71,38 @@ __kernel __attribute__((reqd_work_group_size(LSIZE0,LSIZE1,1))) void col_filter
int l_x = get_local_id(0); int l_x = get_local_id(0);
int l_y = get_local_id(1); int l_y = get_local_id(1);
int start_addr = mad24(y, src_step_in_pixel, x); int start_addr = mad24(y, src_step, x * SRCSIZE);
int end_addr = mad24(src_whole_rows - 1, src_step_in_pixel, src_whole_cols); int end_addr = mad24(src_whole_rows - 1, src_step, src_whole_cols * SRCSIZE);
int i; srcT sum, temp[READ_TIMES_COL];
GENTYPE_SRC sum, temp[READ_TIMES_COL]; __local srcT LDS_DAT[LSIZE1 * READ_TIMES_COL][LSIZE0 + 1];
__local GENTYPE_SRC LDS_DAT[LSIZE1 * READ_TIMES_COL][LSIZE0 + 1];
//read pixels from src // read pixels from src
for(i = 0;i<READ_TIMES_COL;i++) for (int i = 0; i < READ_TIMES_COL; ++i)
{ {
int current_addr = start_addr+i*LSIZE1*src_step_in_pixel; int current_addr = mad24(i, LSIZE1 * src_step, start_addr);
current_addr = current_addr < end_addr ? current_addr : 0; current_addr = current_addr < end_addr ? current_addr : 0;
temp[i] = src[current_addr]; temp[i] = loadpix(src + current_addr);
}
//save pixels to lds
for(i = 0;i<READ_TIMES_COL;i++)
{
LDS_DAT[l_y+i*LSIZE1][l_x] = temp[i];
} }
// save pixels to lds
for (int i = 0; i < READ_TIMES_COL; ++i)
LDS_DAT[mad24(i, LSIZE1, l_y)][l_x] = temp[i];
barrier(CLK_LOCAL_MEM_FENCE); barrier(CLK_LOCAL_MEM_FENCE);
//read pixels from lds and calculate the result
sum = LDS_DAT[l_y+RADIUSY][l_x]*mat_kernel[RADIUSY]; // read pixels from lds and calculate the result
for(i=1;i<=RADIUSY;i++) sum = LDS_DAT[l_y + RADIUSY][l_x] * mat_kernel[RADIUSY];
for (int i = 1; i <= RADIUSY; ++i)
{ {
temp[0]=LDS_DAT[l_y+RADIUSY-i][l_x]; temp[0] = LDS_DAT[l_y + RADIUSY - i][l_x];
temp[1]=LDS_DAT[l_y+RADIUSY+i][l_x]; temp[1] = LDS_DAT[l_y + RADIUSY + i][l_x];
sum += temp[0] * mat_kernel[RADIUSY-i]+temp[1] * mat_kernel[RADIUSY+i]; sum += mad(temp[0], mat_kernel[RADIUSY - i], temp[1] * mat_kernel[RADIUSY + i]);
} }
//write the result to dst
if((x<dst_cols) & (y<dst_rows)) // write the result to dst
if (x < dst_cols && y < dst_rows)
{ {
start_addr = mad24(y, dst_step_in_pixel, x + dst_offset_in_pixel); start_addr = mad24(y, dst_step, mad24(DSTSIZE, x, dst_offset));
dst[start_addr] = convert_to_DST(sum); storepix(convertToDstT(sum + (srcT)(delta)), dst + start_addr);
} }
} }

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