IPP for OpenCV 2017u2 initial enabling patch;

This commit is contained in:
Pavel Vlasov 2017-04-13 15:50:23 +03:00
parent 1c728258e0
commit 35c7216846
27 changed files with 2087 additions and 1848 deletions

42
3rdparty/ippicv/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,42 @@
# ----------------------------------------------------------------------------
# CMake file for IPP IW. See root CMakeLists.txt
#
# ----------------------------------------------------------------------------
project(${IPP_IW_LIBRARY})
ocv_include_directories(${IPP_INCLUDE_DIRS} ${IPP_IW_PATH}/include)
add_definitions(-DIW_BUILD)
if(HAVE_IPP_ICV_ONLY)
add_definitions(-DICV_BASE)
endif()
file(GLOB lib_srcs ${IPP_IW_PATH}/src/*.c)
file(GLOB lib_hdrs ${IPP_IW_PATH}/include/*.h ${IPP_IW_PATH}/include/iw/*.h ${IPP_IW_PATH}/include/iw++/*.hpp)
# ----------------------------------------------------------------------------------
# Define the library target:
# ----------------------------------------------------------------------------------
add_library(${IPP_IW_LIBRARY} STATIC ${lib_srcs} ${lib_hdrs})
if(UNIX)
if(CMAKE_COMPILER_IS_GNUCXX OR CV_ICC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wno-unused-function")
endif()
endif()
set_target_properties(${IPP_IW_LIBRARY}
PROPERTIES OUTPUT_NAME ${IPP_IW_LIBRARY}
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
COMPILE_PDB_NAME ${IPP_IW_LIBRARY}
COMPILE_PDB_NAME_DEBUG "${IPP_IW_LIBRARY}${OPENCV_DEBUG_POSTFIX}"
ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}
)
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(${IPP_IW_LIBRARY} PROPERTIES FOLDER "3rdparty")
endif()
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(${IPP_IW_LIBRARY} EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()

View File

@ -2,23 +2,38 @@ function(download_ippicv root_var)
set(${root_var} "" PARENT_SCOPE)
# Commit SHA in the opencv_3rdparty repo
set(IPPICV_COMMIT "81a676001ca8075ada498583e4166079e5744668")
set(IPPICV_COMMIT "a62e20676a60ee0ad6581e217fe7e4bada3b95db")
# Define actual ICV versions
if(APPLE)
set(OPENCV_ICV_NAME "ippicv_macosx_20151201.tgz")
set(OPENCV_ICV_HASH "4ff1fde9a7cfdfe7250bfcd8334e0f2f")
set(OPENCV_ICV_PLATFORM "macosx")
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_osx")
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_mac")
if(X86_64)
set(OPENCV_ICV_NAME "ippicv_2017u2_mac_intel64_20170418.tgz")
set(OPENCV_ICV_HASH "0c25953c99dbb499ff502485a9356d8d")
else()
set(OPENCV_ICV_NAME "ippicv_2017u2_mac_ia32_20170418.tgz")
set(OPENCV_ICV_HASH "5f225948f3f64067c681293c098d50d8")
endif()
elseif((UNIX AND NOT ANDROID) OR (UNIX AND ANDROID_ABI MATCHES "x86"))
set(OPENCV_ICV_NAME "ippicv_linux_20151201.tgz")
set(OPENCV_ICV_HASH "808b791a6eac9ed78d32a7666804320e")
set(OPENCV_ICV_PLATFORM "linux")
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_lnx")
if(X86_64)
set(OPENCV_ICV_NAME "ippicv_2017u2_lnx_intel64_20170418.tgz")
set(OPENCV_ICV_HASH "87cbdeb627415d8e4bc811156289fa3a")
else()
set(OPENCV_ICV_NAME "ippicv_2017u2_lnx_ia32_20170406.tgz")
set(OPENCV_ICV_HASH "f2cece00d802d4dea86df52ed095257e")
endif()
elseif(WIN32 AND NOT ARM)
set(OPENCV_ICV_NAME "ippicv_windows_20151201.zip")
set(OPENCV_ICV_HASH "04e81ce5d0e329c3fbc606ae32cad44d")
set(OPENCV_ICV_PLATFORM "windows")
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_win")
if(X86_64)
set(OPENCV_ICV_NAME "ippicv_2017u2_win_intel64_20170418.zip")
set(OPENCV_ICV_HASH "75060a0c662c0800f48995b7e9b085f6")
else()
set(OPENCV_ICV_NAME "ippicv_2017u2_win_ia32_20170418.zip")
set(OPENCV_ICV_HASH "60fcf3ccd9a2ebc9e432ffb5cb91638b")
endif()
else()
return()
endif()

View File

@ -270,6 +270,7 @@ OCV_OPTION(BUILD_JPEG "Build libjpeg from source" WIN32 O
OCV_OPTION(BUILD_PNG "Build libpng from source" WIN32 OR ANDROID OR APPLE )
OCV_OPTION(BUILD_OPENEXR "Build openexr from source" (WIN32 OR ANDROID OR APPLE) AND NOT WINRT)
OCV_OPTION(BUILD_TBB "Download and build TBB from source" ANDROID )
OCV_OPTION(BUILD_IPP_IW "Build IPP IW from source" NOT MINGW IF (X86_64 OR X86) AND NOT WINRT )
# OpenCV installation options
# ===================================================
@ -1238,17 +1239,27 @@ status("")
status(" Other third-party libraries:")
if(WITH_IPP AND HAVE_IPP)
status(" Use IPP:" "${IPP_VERSION_STR} [${IPP_VERSION_MAJOR}.${IPP_VERSION_MINOR}.${IPP_VERSION_BUILD}]")
status(" at:" "${IPP_ROOT_DIR}")
status(" Use Intel IPP:" "${IPP_VERSION_STR} [${IPP_VERSION_MAJOR}.${IPP_VERSION_MINOR}.${IPP_VERSION_BUILD}]")
status(" at:" "${IPP_ROOT_DIR}")
if(NOT HAVE_IPP_ICV_ONLY)
status(" linked:" BUILD_WITH_DYNAMIC_IPP THEN "dynamic" ELSE "static")
status(" linked:" BUILD_WITH_DYNAMIC_IPP THEN "dynamic" ELSE "static")
endif()
if(HAVE_IPP_IW)
if(BUILD_IPP_IW)
status(" Use Intel IPP IW:" "build (${IW_VERSION_MAJOR}.${IW_VERSION_MINOR}.${IW_VERSION_UPDATE})")
else()
status(" Use Intel IPP IW:" "prebuilt binaries (${IW_VERSION_MAJOR}.${IW_VERSION_MINOR}.${IW_VERSION_UPDATE})")
endif()
else()
status(" Use Intel IPP IW:" NO)
endif()
else()
status(" Use IPP:" WITH_IPP AND NOT HAVE_IPP THEN "IPP not found or implicitly disabled" ELSE NO)
status(" Use Intel IPP:" WITH_IPP AND NOT HAVE_IPP THEN "IPP not found or implicitly disabled" ELSE NO)
status(" Use Intel IPP IW:" WITH_IPP AND NOT HAVE_IPP AND HAVE_IPP_IW THEN "IPP not found or implicitly disabled" ELSE NO)
endif()
if(DEFINED WITH_IPP_A)
status(" Use IPP Async:" HAVE_IPP_A THEN "YES" ELSE NO)
status(" Use Intel IPP Async:" HAVE_IPP_A THEN "YES" ELSE NO)
endif(DEFINED WITH_IPP_A)
if(DEFINED WITH_VA)

View File

@ -35,7 +35,7 @@ unset(IPP_VERSION_MINOR)
unset(IPP_VERSION_BUILD)
if (X86 AND UNIX AND NOT APPLE AND NOT ANDROID AND BUILD_SHARED_LIBS)
message(STATUS "On 32-bit Linux IPP can not currently be used with dynamic libs because of linker errors. Set BUILD_SHARED_LIBS=OFF")
message(STATUS "On 32-bit Linux Intel IPP can not currently be used with dynamic libs because of linker errors. Set BUILD_SHARED_LIBS=OFF")
return()
endif()
@ -47,14 +47,14 @@ if(CMAKE_CL_64)
set(IPP_X64 1)
endif()
# This function detects IPP version by analyzing .h file
# This function detects Intel IPP version by analyzing .h file
macro(ipp_get_version VERSION_FILE)
unset(_VERSION_STR)
unset(_MAJOR)
unset(_MINOR)
unset(_BUILD)
# read IPP version info from file
# read Intel IPP version info from file
file(STRINGS ${VERSION_FILE} STR1 REGEX "IPP_VERSION_MAJOR")
file(STRINGS ${VERSION_FILE} STR2 REGEX "IPP_VERSION_MINOR")
file(STRINGS ${VERSION_FILE} STR3 REGEX "IPP_VERSION_BUILD")
@ -96,29 +96,29 @@ macro(ipp_detect_version)
elseif(EXISTS ${IPP_ROOT_DIR}/include/ipp.h)
# nothing
else()
_ipp_not_supported("Can't resolve IPP directory: ${IPP_ROOT_DIR}")
_ipp_not_supported("Can't resolve Intel IPP directory: ${IPP_ROOT_DIR}")
endif()
ipp_get_version(${IPP_INCLUDE_DIRS}/ippversion.h)
ocv_assert(IPP_VERSION_STR VERSION_GREATER "1.0")
message(STATUS "found IPP${__msg}: ${_MAJOR}.${_MINOR}.${_BUILD} [${IPP_VERSION_STR}]")
message(STATUS "found Intel IPP${__msg}: ${_MAJOR}.${_MINOR}.${_BUILD} [${IPP_VERSION_STR}]")
message(STATUS "at: ${IPP_ROOT_DIR}")
if(${IPP_VERSION_STR} VERSION_LESS "7.0")
_ipp_not_supported("IPP ${IPP_VERSION_STR} is not supported")
_ipp_not_supported("Intel IPP ${IPP_VERSION_STR} is not supported")
endif()
set(HAVE_IPP 1)
macro(_ipp_set_library_dir DIR)
if(NOT EXISTS ${DIR})
_ipp_not_supported("IPP library directory not found")
_ipp_not_supported("Intel IPP library directory not found")
endif()
set(IPP_LIBRARY_DIR ${DIR})
endmacro()
if(APPLE)
if(APPLE AND NOT HAVE_IPP_ICV_ONLY)
_ipp_set_library_dir(${IPP_ROOT_DIR}/lib)
elseif(IPP_X64)
_ipp_set_library_dir(${IPP_ROOT_DIR}/lib/intel64)
@ -127,7 +127,7 @@ macro(ipp_detect_version)
endif()
macro(_ipp_add_library name)
# dynamic linking is only supported for standalone version of IPP
# dynamic linking is only supported for standalone version of Intel IPP
if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV_ONLY)
if (WIN32)
set(IPP_LIB_PREFIX ${CMAKE_IMPORT_LIBRARY_PREFIX})
@ -142,7 +142,7 @@ macro(ipp_detect_version)
endif ()
if (EXISTS ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV_ONLY)
# When using dynamic libraries from standalone IPP it is your responsibility to install those on the target system
# When using dynamic libraries from standalone Intel IPP it is your responsibility to install those on the target system
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
else ()
add_library(ipp${name} STATIC IMPORTED)
@ -161,33 +161,32 @@ macro(ipp_detect_version)
endif()
endif()
else()
message(STATUS "Can't find IPP library: ${name} at ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}")
message(STATUS "Can't find Intel IPP library: ${name} at ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}")
endif()
endmacro()
set(IPP_PREFIX "ipp")
if(${IPP_VERSION_STR} VERSION_LESS "8.0")
if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV_ONLY)
set(IPP_SUFFIX "") # dynamic not threaded libs suffix IPP 7.x
set(IPP_SUFFIX "") # dynamic not threaded libs suffix Intel IPP 7.x
else ()
set(IPP_SUFFIX "_l") # static not threaded libs suffix IPP 7.x
set(IPP_SUFFIX "_l") # static not threaded libs suffix Intel IPP 7.x
endif ()
else ()
if(WIN32)
if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV_ONLY)
set(IPP_SUFFIX "") # dynamic not threaded libs suffix IPP 8.x for Windows
set(IPP_SUFFIX "") # dynamic not threaded libs suffix Intel IPP 8.x for Windows
else ()
set(IPP_SUFFIX "mt") # static not threaded libs suffix IPP 8.x for Windows
set(IPP_SUFFIX "mt") # static not threaded libs suffix Intel IPP 8.x for Windows
endif ()
else()
set(IPP_SUFFIX "") # static not threaded libs suffix IPP 8.x for Linux/OS X
set(IPP_SUFFIX "") # static not threaded libs suffix Intel IPP 8.x for Linux/OS X
endif()
endif()
if(HAVE_IPP_ICV_ONLY)
_ipp_add_library(icv)
else()
_ipp_add_library(m)
_ipp_add_library(cv)
_ipp_add_library(i)
_ipp_add_library(cc)
@ -201,7 +200,7 @@ macro(ipp_detect_version)
get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../compiler/lib REALPATH)
endif()
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR})
_ipp_not_supported("IPP configuration error: can't find Intel compiler library dir ${INTEL_COMPILER_LIBRARY_DIR}")
_ipp_not_supported("Intel IPP configuration error: can't find Intel compiler library dir ${INTEL_COMPILER_LIBRARY_DIR}")
endif()
if(NOT APPLE)
if(IPP_X64)
@ -231,7 +230,7 @@ macro(ipp_detect_version)
endif()
endif()
#message(STATUS "IPP libs: ${IPP_LIBRARIES}")
#message(STATUS "Intel IPP libs: ${IPP_LIBRARIES}")
endmacro()
# OPENCV_IPP_PATH is an environment variable for internal usage only, do not use it
@ -240,12 +239,6 @@ if(DEFINED ENV{OPENCV_IPP_PATH} AND NOT DEFINED IPPROOT)
endif()
if(NOT DEFINED IPPROOT)
if(IOS AND NOT x86_64)
# 2016/10: There is an issue with MacOS binary .a file.
# It is fat multiarch library, and can't be "merged" multiple times.
# So try to ignore i386 version
return()
endif()
include("${OpenCV_SOURCE_DIR}/3rdparty/ippicv/ippicv.cmake")
download_ippicv(IPPROOT)
if(NOT IPPROOT)
@ -261,7 +254,7 @@ endif()
if(WIN32 AND MINGW AND NOT IPP_VERSION_MAJOR LESS 7)
# Since IPP built with Microsoft compiler and /GS option
# Since Intel IPP built with Microsoft compiler and /GS option
# ======================================================
# From Windows SDK 7.1
# (usually in "C:\Program Files\Microsoft Visual Studio 10.0\VC\lib"),

154
cmake/OpenCVFindIPPIW.cmake Normal file
View File

@ -0,0 +1,154 @@
#
# The script to detect Intel(R) Integrated Performance Primitives Integration Wrappers (IPP IW)
# installation/package
#
#
# On return this will define:
#
# HAVE_IPP_IW - True if Intel IPP found
# IPP_IW_PATH - Root of Intel IPP IW directory
# IPP_IW_LIBRARIES - Intel IPP IW libraries
# IPP_IW_INCLUDES - Intel IPP IW include folder
#
unset(HAVE_IPP_IW CACHE)
unset(IPP_IW_PATH)
unset(IPP_IW_LIBRARIES)
unset(IPP_IW_INCLUDES)
unset(IW_CONFIG_DEBUG)
#set(IW_CONFIG_DEBUG 1)
if(NOT HAVE_IPP)
return()
endif()
macro(ippiw_debugmsg MESSAGE)
if(DEFINED IW_CONFIG_DEBUG)
message(STATUS "${MESSAGE}")
endif()
endmacro()
# This function detects Intel IPP IW version by analyzing .h file
macro(ippiw_setup PATH BUILD)
set(FILE "${PATH}/include/iw/iw_version.h")
ippiw_debugmsg("Checking path: ${PATH}")
if(EXISTS "${FILE}")
ippiw_debugmsg("vfile\tok")
file(STRINGS "${FILE}" IW_VERSION_MAJOR REGEX "IW_VERSION_MAJOR")
file(STRINGS "${FILE}" IW_VERSION_MINOR REGEX "IW_VERSION_MINOR")
file(STRINGS "${FILE}" IW_VERSION_UPDATE REGEX "IW_VERSION_UPDATE")
file(STRINGS "${FILE}" IW_MIN_COMPATIBLE_IPP_MAJOR REGEX "IW_MIN_COMPATIBLE_IPP_MAJOR")
file(STRINGS "${FILE}" IW_MIN_COMPATIBLE_IPP_MINOR REGEX "IW_MIN_COMPATIBLE_IPP_MINOR")
file(STRINGS "${FILE}" IW_MIN_COMPATIBLE_IPP_UPDATE REGEX "IW_MIN_COMPATIBLE_IPP_UPDATE")
string(REGEX MATCH "[0-9]+" IW_MIN_COMPATIBLE_IPP_MAJOR ${IW_MIN_COMPATIBLE_IPP_MAJOR})
string(REGEX MATCH "[0-9]+" IW_MIN_COMPATIBLE_IPP_MINOR ${IW_MIN_COMPATIBLE_IPP_MINOR})
string(REGEX MATCH "[0-9]+" IW_MIN_COMPATIBLE_IPP_UPDATE ${IW_MIN_COMPATIBLE_IPP_UPDATE})
string(REGEX MATCH "[0-9]+" IW_VERSION_MAJOR ${IW_VERSION_MAJOR})
string(REGEX MATCH "[0-9]+" IW_VERSION_MINOR ${IW_VERSION_MINOR})
string(REGEX MATCH "[0-9]+" IW_VERSION_UPDATE ${IW_VERSION_UPDATE})
math(EXPR IPP_VERSION_EXP "${IPP_VERSION_MAJOR}*10000 + ${IPP_VERSION_MINOR}*100 + ${IPP_VERSION_BUILD}")
math(EXPR IW_MIN_COMPATIBLE_IPP_EXP "${IW_MIN_COMPATIBLE_IPP_MAJOR}*10000 + ${IW_MIN_COMPATIBLE_IPP_MINOR}*100 + ${IW_MIN_COMPATIBLE_IPP_UPDATE}")
if((IPP_VERSION_EXP GREATER IW_MIN_COMPATIBLE_IPP_EXP) OR (IPP_VERSION_EXP EQUAL IW_MIN_COMPATIBLE_IPP_EXP))
ippiw_debugmsg("version\tok")
if(${BUILD})
# check sources
if(EXISTS "${PATH}/src/iw_core.c")
ippiw_debugmsg("sources\tok")
set(IPP_IW_PATH "${PATH}")
message(STATUS "found Intel IPP IW sources: ${IW_VERSION_MAJOR}.${IW_VERSION_MINOR}.${IW_VERSION_UPDATE}")
message(STATUS "at: ${IPP_IW_PATH}")
set(IPP_IW_LIBRARY ippiw)
set(IPP_IW_INCLUDES "${IPP_IW_PATH}/include")
set(IPP_IW_LIBRARIES ${IPP_IW_LIBRARY})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OpenCV_SOURCE_DIR}/3rdparty/ippicv/CMakeLists.txt" "${IPP_IW_PATH}/")
add_subdirectory("${IPP_IW_PATH}/" ${OpenCV_BINARY_DIR}/3rdparty/ippiw)
set(HAVE_IPP_IW 1)
return()
endif()
else()
# check binaries
if(IPP_X64)
set(FILE "${PATH}/lib/intel64/${CMAKE_STATIC_LIBRARY_PREFIX}ipp_iw${CMAKE_STATIC_LIBRARY_SUFFIX}")
else()
set(FILE "${PATH}/lib/ia32/${CMAKE_STATIC_LIBRARY_PREFIX}ipp_iw${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()
if(EXISTS ${FILE})
ippiw_debugmsg("binaries\tok (64=${IPP_X64})")
set(IPP_IW_PATH "${PATH}")
message(STATUS "found Intel IPP IW binaries: ${IW_VERSION_MAJOR}.${IW_VERSION_MINOR}.${IW_VERSION_UPDATE}")
message(STATUS "at: ${IPP_IW_PATH}")
set(IPP_IW_INCLUDES "${IPP_IW_PATH}/include")
set(IPP_IW_LIBRARIES ${FILE})
set(HAVE_IPP_IW 1)
set(BUILD_IPP_IW 0)
return()
endif()
endif()
endif()
endif()
set(HAVE_IPP_IW 0)
endmacro()
# check os and architecture
if(APPLE)
set(IW_PACKAGE_SUBDIR "ippiw_mac")
elseif((UNIX AND NOT ANDROID) OR (UNIX AND ANDROID_ABI MATCHES "x86"))
set(IW_PACKAGE_SUBDIR "ippiw_lnx")
elseif(WIN32 AND NOT ARM)
set(IW_PACKAGE_SUBDIR "ippiw_win")
else()
message(SEND_ERROR "Improper system for Intel IPP Integrations Wrappers. This message shouldn't appera. Check Intel IPP configurations steps")
return()
endif()
# check build options first
if(BUILD_IPP_IW)
# custom path
if(DEFINED IPPIWROOT)
ippiw_setup("${IPPIWROOT}/" 1)
message(STATUS "Can't find Intel IPP IW sources at: ${IPPIWROOT}")
endif()
# local sources
ippiw_setup("${OpenCV_SOURCE_DIR}/3rdparty/ippiw" 1)
# Package sources
ippiw_setup("${IPPROOT}/../${IW_PACKAGE_SUBDIR}/" 1)
endif()
# custom binaries
if(DEFINED IPPIWROOT)
ippiw_setup("${IPPIWROOT}/" 0)
message(STATUS "Can't find Intel IPP IW sources at: ${IPPIWROOT}")
endif()
# check binaries in IPP folder
ippiw_setup("${IPPROOT}/" 0)
# check binaries near IPP folder
ippiw_setup("${IPPROOT}/../${IW_PACKAGE_SUBDIR}/" 0)
# take Intel IPP IW from ICV package
if(NOT HAVE_IPP_ICV_ONLY AND BUILD_IPP_IW)
message(STATUS "Cannot find Intel IPP IW. Checking \"Intel IPP for OpenCV\" package")
set(TEMP_ROOT 0)
include("${OpenCV_SOURCE_DIR}/3rdparty/ippicv/ippicv.cmake")
download_ippicv(TEMP_ROOT)
# Package sources. Only sources are compatible with regular Intel IPP
ippiw_setup("${TEMP_ROOT}/../${IW_PACKAGE_SUBDIR}/" 1)
endif()
set(HAVE_IPP_IW 0)
message(STATUS "Cannot find Intel IPP Integration Wrappers, optimizations will be limited. Use IPPIWROOT to set custom location")
return()

View File

@ -36,6 +36,11 @@ endif(WITH_TBB)
if(WITH_IPP)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIPP.cmake")
if(HAVE_IPP)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIPPIW.cmake")
if(HAVE_IPP_IW)
ocv_include_directories(${IPP_IW_INCLUDES})
list(APPEND OPENCV_LINKER_LIBS ${IPP_IW_LIBRARIES})
endif()
ocv_include_directories(${IPP_INCLUDE_DIRS})
list(APPEND OPENCV_LINKER_LIBS ${IPP_LIBRARIES})
endif()

View File

@ -101,6 +101,7 @@
/* Intel Integrated Performance Primitives */
#cmakedefine HAVE_IPP
#cmakedefine HAVE_IPP_ICV_ONLY
#cmakedefine HAVE_IPP_IW
/* Intel IPP Async */
#cmakedefine HAVE_IPP_A

View File

@ -1705,43 +1705,37 @@ void filterSpecklesImpl(cv::Mat& img, int newVal, int maxSpeckleSize, int maxDif
}
#ifdef HAVE_IPP
static bool ipp_filterSpeckles(Mat &img, int maxSpeckleSize, int newVal, int maxDiff)
static bool ipp_filterSpeckles(Mat &img, int maxSpeckleSize, int newVal, int maxDiff, Mat &buffer)
{
#if IPP_VERSION_X100 >= 810
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 810
int type = img.type();
Ipp32s bufsize = 0;
IppiSize roisize = { img.cols, img.rows };
IppDataType datatype = type == CV_8UC1 ? ipp8u : ipp16s;
Ipp8u *pBuffer = NULL;
IppStatus status = ippStsNoErr;
IppDataType dataType = ippiGetDataType(img.depth());
IppiSize size = ippiSize(img.size());
int bufferSize;
if(ippiMarkSpecklesGetBufferSize(roisize, datatype, CV_MAT_CN(type), &bufsize) < 0)
if(img.channels() != 1)
return false;
pBuffer = (Ipp8u*)ippMalloc(bufsize);
if(!pBuffer && bufsize)
if(dataType != ipp8u && dataType != ipp16s)
return false;
if (type == CV_8UC1)
{
status = CV_INSTRUMENT_FUN_IPP(ippiMarkSpeckles_8u_C1IR, img.ptr<Ipp8u>(), (int)img.step, roisize,
(Ipp8u)newVal, maxSpeckleSize, (Ipp8u)maxDiff, ippiNormL1, pBuffer);
}
else
{
status = CV_INSTRUMENT_FUN_IPP(ippiMarkSpeckles_16s_C1IR, img.ptr<Ipp16s>(), (int)img.step, roisize,
(Ipp16s)newVal, maxSpeckleSize, (Ipp16s)maxDiff, ippiNormL1, pBuffer);
}
if(pBuffer) ippFree(pBuffer);
if(ippiMarkSpecklesGetBufferSize(size, dataType, 1, &bufferSize) < 0)
return false;
if (status >= 0)
return true;
if(bufferSize && (buffer.empty() || (int)(buffer.step*buffer.rows) < bufferSize))
buffer.create(1, (int)bufferSize, CV_8U);
switch(dataType)
{
case ipp8u: return CV_INSTRUMENT_FUN_IPP(ippiMarkSpeckles_8u_C1IR, img.ptr<Ipp8u>(), (int)img.step, size, (Ipp8u)newVal, maxSpeckleSize, (Ipp8u)maxDiff, ippiNormL1, buffer.ptr<Ipp8u>()) >= 0;
case ipp16s: return CV_INSTRUMENT_FUN_IPP(ippiMarkSpeckles_16s_C1IR, img.ptr<Ipp16s>(), (int)img.step, size, (Ipp16s)newVal, maxSpeckleSize, (Ipp16s)maxDiff, ippiNormL1, buffer.ptr<Ipp8u>()) >= 0;
default: return false;
}
#else
CV_UNUSED(img); CV_UNUSED(maxSpeckleSize); CV_UNUSED(newVal); CV_UNUSED(maxDiff);
#endif
CV_UNUSED(img); CV_UNUSED(maxSpeckleSize); CV_UNUSED(newVal); CV_UNUSED(maxDiff); CV_UNUSED(buffer);
return false;
#endif
}
#endif
@ -1759,7 +1753,7 @@ void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSi
int newVal = cvRound(_newval), maxDiff = cvRound(_maxDiff);
CV_IPP_RUN(IPP_VERSION_X100 >= 810 && !__buf.needed() && (type == CV_8UC1 || type == CV_16SC1), ipp_filterSpeckles(img, maxSpeckleSize, newVal, maxDiff));
CV_IPP_RUN_FAST(ipp_filterSpeckles(img, maxSpeckleSize, newVal, maxDiff, _buf));
if (type == CV_8UC1)
filterSpecklesImpl<uchar>(img, newVal, maxSpeckleSize, maxDiff, _buf);

View File

@ -671,7 +671,11 @@ namespace cudev
namespace ipp
{
#if OPENCV_ABI_COMPATIBILITY > 300
CV_EXPORTS unsigned long long getIppFeatures();
#else
CV_EXPORTS int getIppFeatures();
#endif
CV_EXPORTS void setIppStatus(int status, const char * const funcname = NULL, const char * const filename = NULL,
int line = 0);
CV_EXPORTS int getIppStatus();

View File

@ -185,28 +185,78 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un
* Structures and macros for integration with IPP *
\****************************************************************************************/
#ifdef HAVE_IPP
#include "ipp.h"
// Temporary disabled named IPP region. Accuracy
#define IPP_DISABLE_PYRAMIDS_UP 1 // Different results
#define IPP_DISABLE_PYRAMIDS_DOWN 1 // Different results
#define IPP_DISABLE_PYRAMIDS_BUILD 1 // Different results
#define IPP_DISABLE_WARPAFFINE 1 // Different results
#define IPP_DISABLE_WARPPERSPECTIVE 1 // Different results
#define IPP_DISABLE_REMAP 1 // Different results
#define IPP_DISABLE_MORPH_ADV 1 // mask flipping in IPP
#define IPP_DISABLE_SORT_IDX 0 // different order in index tables
#define IPP_DISABLE_YUV_RGB 1 // accuracy difference
#define IPP_DISABLE_RGB_YUV 1 // breaks OCL accuracy tests
#define IPP_DISABLE_RGB_HSV 1 // breaks OCL accuracy tests
#define IPP_DISABLE_RGB_LAB 1 // breaks OCL accuracy tests
#define IPP_DISABLE_LAB_RGB 1 // breaks OCL accuracy tests
#define IPP_DISABLE_RGB_XYZ 1 // big accuracy difference
#define IPP_DISABLE_XYZ_RGB 1 // big accuracy difference
#define IPP_DISABLE_HAAR 1 // improper integration/results
#define IPP_DISABLE_HOUGH 1 // improper integration/results
#define IPP_DISABLE_RESIZE_8U 1 // Incompatible accuracy
#define IPP_DISABLE_RESIZE_NEAREST 1 // Accuracy mismatch (max diff 1)
#define IPP_DISABLE_RESIZE_AREA 1 // Accuracy mismatch (max diff 1)
// Temporary disabled named IPP region. Performance
#define IPP_DISABLE_PERF_COPYMAKE 1 // performance variations
#define IPP_DISABLE_PERF_LUT 1 // there are no performance benefits (PR #2653)
#define IPP_DISABLE_PERF_TRUE_DIST_MT 1 // cv::distanceTransform OpenCV MT performance is better
#define IPP_DISABLE_PERF_CANNY_MT 1 // cv::Canny OpenCV MT performance is better
#define IPP_DISABLE_PERF_HISTU32F_SSE42 1 // cv::calcHist optimizations problem
#define IPP_DISABLE_PERF_MORPH_SSE42 1 // cv::erode, cv::dilate optimizations problem
#define IPP_DISABLE_PERF_MAG_SSE42 1 // cv::magnitude optimizations problem
#define IPP_DISABLE_PERF_BOX16S_SSE42 1 // cv::boxFilter optimizations problem
#define IPP_DISABLE_BLOCK 0 // legacy switch
#ifdef HAVE_IPP
#include "ippversion.h"
#ifndef IPP_VERSION_UPDATE // prior to 7.1
#define IPP_VERSION_UPDATE 0
#endif
#define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR*10 + IPP_VERSION_UPDATE)
// General define for ipp function disabling
#define IPP_DISABLE_BLOCK 0
#ifdef HAVE_IPP_ICV_ONLY
#define ICV_BASE
#if IPP_VERSION_X100 >= 201700
#include "ippicv.h"
#else
#include "ipp.h"
#endif
#else
#include "ipp.h"
#endif
#ifdef HAVE_IPP_IW
#include "iw++/iw.hpp"
#endif
#ifdef CV_MALLOC_ALIGN
#undef CV_MALLOC_ALIGN
#endif
#define CV_MALLOC_ALIGN 32 // required for AVX optimization
#if IPP_VERSION_X100 >= 201700
#define CV_IPP_MALLOC(SIZE) ippMalloc_L(SIZE)
#else
#define CV_IPP_MALLOC(SIZE) ippMalloc((int)SIZE)
#endif
#define setIppErrorStatus() cv::ipp::setIppStatus(-1, CV_Func, __FILE__, __LINE__)
static inline IppiSize ippiSize(int width, int height)
static inline IppiSize ippiSize(size_t width, size_t height)
{
IppiSize size = { width, height };
IppiSize size = { (int)width, (int)height };
return size;
}
@ -216,6 +266,20 @@ static inline IppiSize ippiSize(const cv::Size & _size)
return size;
}
#if IPP_VERSION_X100 >= 201700
static inline IppiSizeL ippiSizeL(size_t width, size_t height)
{
IppiSizeL size = { (IppSizeL)width, (IppSizeL)height };
return size;
}
static inline IppiSizeL ippiSizeL(const cv::Size & _size)
{
IppiSizeL size = { _size.width, _size.height };
return size;
}
#endif
static inline IppiPoint ippiPoint(const cv::Point & _point)
{
IppiPoint point = { _point.x, _point.y };
@ -230,34 +294,177 @@ static inline IppiPoint ippiPoint(int x, int y)
static inline IppiBorderType ippiGetBorderType(int borderTypeNI)
{
return borderTypeNI == cv::BORDER_CONSTANT ? ippBorderConst :
borderTypeNI == cv::BORDER_WRAP ? ippBorderWrap :
borderTypeNI == cv::BORDER_REPLICATE ? ippBorderRepl :
borderTypeNI == cv::BORDER_REFLECT_101 ? ippBorderMirror :
borderTypeNI == cv::BORDER_REFLECT ? ippBorderMirrorR : (IppiBorderType)-1;
return borderTypeNI == cv::BORDER_CONSTANT ? ippBorderConst :
borderTypeNI == cv::BORDER_TRANSPARENT ? ippBorderTransp :
borderTypeNI == cv::BORDER_REPLICATE ? ippBorderRepl :
borderTypeNI == cv::BORDER_REFLECT_101 ? ippBorderMirror :
(IppiBorderType)-1;
}
static inline IppiMaskSize ippiGetMaskSize(int kx, int ky)
{
return (kx == 1 && ky == 3) ? ippMskSize1x3 :
(kx == 1 && ky == 5) ? ippMskSize1x5 :
(kx == 3 && ky == 1) ? ippMskSize3x1 :
(kx == 3 && ky == 3) ? ippMskSize3x3 :
(kx == 5 && ky == 1) ? ippMskSize5x1 :
(kx == 5 && ky == 5) ? ippMskSize5x5 :
(IppiMaskSize)-1;
}
static inline IppDataType ippiGetDataType(int depth)
{
depth = CV_MAT_DEPTH(depth);
return depth == CV_8U ? ipp8u :
depth == CV_8S ? ipp8s :
depth == CV_16U ? ipp16u :
depth == CV_16S ? ipp16s :
depth == CV_32S ? ipp32s :
depth == CV_32F ? ipp32f :
depth == CV_64F ? ipp64f : (IppDataType)-1;
depth == CV_64F ? ipp64f :
(IppDataType)-1;
}
// IPP temporary buffer hepler
#ifdef HAVE_IPP_IW
static inline IwiDerivativeType ippiGetDerivType(int dx, int dy, bool nvert)
{
return (dx == 1 && dy == 0) ? ((nvert)?iwiDerivNVerFirst:iwiDerivVerFirst) :
(dx == 0 && dy == 1) ? iwiDerivHorFirst :
(dx == 2 && dy == 0) ? iwiDerivVerSecond :
(dx == 0 && dy == 2) ? iwiDerivHorSecond :
(IwiDerivativeType)-1;
}
static inline void ippiGetImage(const cv::Mat &src, ::ipp::IwiImage &dst)
{
::ipp::IwiBorderSize inMemBorder;
if(src.isSubmatrix()) // already have physical border
{
cv::Size origSize;
cv::Point offset;
src.locateROI(origSize, offset);
inMemBorder.borderLeft = (Ipp32u)offset.x;
inMemBorder.borderTop = (Ipp32u)offset.y;
inMemBorder.borderRight = (Ipp32u)(origSize.width - src.cols - offset.x);
inMemBorder.borderBottom = (Ipp32u)(origSize.height - src.rows - offset.y);
}
dst.Init(ippiSize(src.size()), ippiGetDataType(src.depth()), src.channels(), inMemBorder, (void*)src.ptr(), src.step);
}
static inline ::ipp::IwiImage ippiGetImage(const cv::Mat &src)
{
::ipp::IwiImage image;
ippiGetImage(src, image);
return image;
}
static inline IppiBorderType ippiGetBorder(::ipp::IwiImage &image, int ocvBorderType, IppiBorderSize &borderSize)
{
int inMemFlags = 0;
IppiBorderType border = ippiGetBorderType(ocvBorderType & ~cv::BORDER_ISOLATED);
if((int)border == -1)
return (IppiBorderType)0;
if(!(ocvBorderType & cv::BORDER_ISOLATED))
{
if(image.m_inMemSize.borderLeft)
{
if(image.m_inMemSize.borderLeft >= borderSize.borderLeft)
inMemFlags |= ippBorderInMemLeft;
else
return (IppiBorderType)0;
}
else
borderSize.borderLeft = 0;
if(image.m_inMemSize.borderTop)
{
if(image.m_inMemSize.borderTop >= borderSize.borderTop)
inMemFlags |= ippBorderInMemTop;
else
return (IppiBorderType)0;
}
else
borderSize.borderTop = 0;
if(image.m_inMemSize.borderRight)
{
if(image.m_inMemSize.borderRight >= borderSize.borderRight)
inMemFlags |= ippBorderInMemRight;
else
return (IppiBorderType)0;
}
else
borderSize.borderRight = 0;
if(image.m_inMemSize.borderBottom)
{
if(image.m_inMemSize.borderBottom >= borderSize.borderBottom)
inMemFlags |= ippBorderInMemBottom;
else
return (IppiBorderType)0;
}
else
borderSize.borderBottom = 0;
}
else
borderSize.borderLeft = borderSize.borderRight = borderSize.borderTop = borderSize.borderBottom = 0;
return (IppiBorderType)(border|inMemFlags);
}
static inline ::ipp::IwValue ippiGetValue(const cv::Scalar &scalar)
{
return ::ipp::IwValue(scalar[0], scalar[1], scalar[2], scalar[3]);
}
static inline int ippiSuggestThreadsNum(const ::ipp::IwiImage &image, double multiplier)
{
int threads = cv::getNumThreads();
if(image.m_size.height > threads)
{
size_t opMemory = (int)(image.m_step*image.m_size.height*multiplier);
int l2cache = 0;
#if IPP_VERSION_X100 >= 201700
ippGetL2CacheSize(&l2cache);
#endif
if(!l2cache)
l2cache = 1 << 18;
return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
}
return 1;
}
#endif
static inline int ippiSuggestThreadsNum(const cv::Mat &image, double multiplier)
{
int threads = cv::getNumThreads();
if(image.rows > threads)
{
size_t opMemory = (int)(image.total()*multiplier);
int l2cache = 0;
#if IPP_VERSION_X100 >= 201700
ippGetL2CacheSize(&l2cache);
#endif
if(!l2cache)
l2cache = 1 << 18;
return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
}
return 1;
}
// IPP temporary buffer helper
template<typename T>
class IppAutoBuffer
{
public:
IppAutoBuffer() { m_pBuffer = NULL; }
IppAutoBuffer(int size) { Alloc(size); }
~IppAutoBuffer() { Release(); }
T* Alloc(int size) { m_pBuffer = (T*)ippMalloc(size); return m_pBuffer; }
void Release() { if(m_pBuffer) ippFree(m_pBuffer); }
IppAutoBuffer() { m_size = 0; m_pBuffer = NULL; }
IppAutoBuffer(size_t size) { m_size = 0; m_pBuffer = NULL; allocate(size); }
~IppAutoBuffer() { deallocate(); }
T* allocate(size_t size) { if(m_size < size) { deallocate(); m_pBuffer = (T*)CV_IPP_MALLOC(size); m_size = size; } return m_pBuffer; }
void deallocate() { if(m_pBuffer) { ippFree(m_pBuffer); m_pBuffer = NULL; } m_size = 0; }
inline T* get() { return (T*)m_pBuffer;}
inline operator T* () { return (T*)m_pBuffer;}
inline operator const T* () const { return (const T*)m_pBuffer;}
private:
@ -265,9 +472,17 @@ private:
IppAutoBuffer(IppAutoBuffer &) {}
IppAutoBuffer& operator =(const IppAutoBuffer &) {return *this;}
T* m_pBuffer;
size_t m_size;
T* m_pBuffer;
};
// Extracts border interpolation type without flags
#if IPP_VERSION_MAJOR >= 2017
#define IPP_BORDER_INTER(BORDER) (IppiBorderType)((BORDER)&0xF|((((BORDER)&ippBorderInMem) == ippBorderInMem)?ippBorderInMem:0));
#else
#define IPP_BORDER_INTER(BORDER) (IppiBorderType)((BORDER)&0xF);
#endif
#else
#define IPP_VERSION_X100 0
#endif

View File

@ -139,7 +139,7 @@ OCL_PERF_TEST_P(CopyToFixture, CopyToWithMaskUninit,
dst.release();
startTimer();
src.copyTo(dst, mask);
cv::ocl::finish();
cvtest::ocl::perf::safeFinish();
stopTimer();
}

View File

@ -5512,7 +5512,7 @@ public:
size_t elemSize1 = dst.elemSize1();
CV_DbgAssert(elemSize1 == 1);
lutBuffer = (uchar*)ippMalloc(256 * (int)elemSize1 * 4);
lutBuffer = (uchar*)CV_IPP_MALLOC(256 * (int)elemSize1 * 4);
lutTable[0] = lutBuffer + 0;
lutTable[1] = lutBuffer + 1 * 256 * elemSize1;
lutTable[2] = lutBuffer + 2 * 256 * elemSize1;

View File

@ -298,13 +298,7 @@ void Mat::copyTo( OutputArray _dst ) const
const uchar* sptr = data;
uchar* dptr = dst.data;
CV_IPP_RUN(
(size_t)cols*elemSize() <= (size_t)INT_MAX &&
(size_t)step <= (size_t)INT_MAX &&
(size_t)dst.step <= (size_t)INT_MAX
,
CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C1R, sptr, (int)step, dptr, (int)dst.step, ippiSize((int)(cols*elemSize()), rows)) >= 0
)
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C1R_L, sptr, (int)step, dptr, (int)dst.step, ippiSizeL((int)(cols*elemSize()), rows)) >= 0)
Size sz = getContinuousSize(*this, dst);
size_t len = sz.width*elemSize();

View File

@ -1580,13 +1580,13 @@ public:
return;
}
IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)ippMalloc( sizeSpec );
IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)CV_IPP_MALLOC( sizeSpec );
if ( sizeInit > 0 )
pMemInit = (Ipp8u*)ippMalloc( sizeInit );
pMemInit = (Ipp8u*)CV_IPP_MALLOC( sizeInit );
if ( sizeBuffer > 0 )
pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
pBuffer = (Ipp8u*)CV_IPP_MALLOC( sizeBuffer );
status = ippiDFTInit_C_32fc( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
@ -1661,13 +1661,13 @@ public:
return;
}
IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)ippMalloc( sizeSpec );
IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)CV_IPP_MALLOC( sizeSpec );
if ( sizeInit > 0 )
pMemInit = (Ipp8u*)ippMalloc( sizeInit );
pMemInit = (Ipp8u*)CV_IPP_MALLOC( sizeInit );
if ( sizeBuffer > 0 )
pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
pBuffer = (Ipp8u*)CV_IPP_MALLOC( sizeBuffer );
status = ippiDFTInit_R_32f( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
@ -1767,13 +1767,13 @@ static bool ippi_DFT_C_32F(const uchar * src, size_t src_step, uchar * dst, size
if ( status < 0 )
return false;
IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)ippMalloc( sizeSpec );
IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)CV_IPP_MALLOC( sizeSpec );
if ( sizeInit > 0 )
pMemInit = (Ipp8u*)ippMalloc( sizeInit );
pMemInit = (Ipp8u*)CV_IPP_MALLOC( sizeInit );
if ( sizeBuffer > 0 )
pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
pBuffer = (Ipp8u*)CV_IPP_MALLOC( sizeBuffer );
status = ippiDFTInit_C_32fc( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
@ -1823,13 +1823,13 @@ static bool ippi_DFT_R_32F(const uchar * src, size_t src_step, uchar * dst, size
if ( status < 0 )
return false;
IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)ippMalloc( sizeSpec );
IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)CV_IPP_MALLOC( sizeSpec );
if ( sizeInit > 0 )
pMemInit = (Ipp8u*)ippMalloc( sizeInit );
pMemInit = (Ipp8u*)CV_IPP_MALLOC( sizeInit );
if ( sizeBuffer > 0 )
pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
pBuffer = (Ipp8u*)CV_IPP_MALLOC( sizeBuffer );
status = ippiDFTInit_R_32f( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
@ -3852,20 +3852,20 @@ public:
return;
}
pDCTSpec = (Ipp8u*)ippMalloc(specSize);
pDCTSpec = (Ipp8u*)CV_IPP_MALLOC(specSize);
if(!pDCTSpec && specSize)
{
*ok = false;
return;
}
pBuffer = (Ipp8u*)ippMalloc(bufferSize);
pBuffer = (Ipp8u*)CV_IPP_MALLOC(bufferSize);
if(!pBuffer && bufferSize)
{
*ok = false;
IPP_RETURN
}
pInitBuf = (Ipp8u*)ippMalloc(initSize);
pInitBuf = (Ipp8u*)CV_IPP_MALLOC(initSize);
if(!pInitBuf && initSize)
{
*ok = false;
@ -3981,17 +3981,17 @@ static bool ippi_DCT_32f(const uchar * src, size_t src_step, uchar * dst, size_t
if(ippDctGetSize(srcRoiSize, &specSize, &initSize, &bufferSize) < 0)
return false;
pDCTSpec = (Ipp8u*)ippMalloc(specSize);
pDCTSpec = (Ipp8u*)CV_IPP_MALLOC(specSize);
if(!pDCTSpec && specSize)
return false;
pBuffer = (Ipp8u*)ippMalloc(bufferSize);
pBuffer = (Ipp8u*)CV_IPP_MALLOC(bufferSize);
if(!pBuffer && bufferSize)
{
IPP_RELEASE
return false;
}
pInitBuf = (Ipp8u*)ippMalloc(initSize);
pInitBuf = (Ipp8u*)CV_IPP_MALLOC(initSize);
if(!pInitBuf && initSize)
{
IPP_RELEASE

View File

@ -3955,50 +3955,6 @@ void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype)
namespace cv
{
#ifdef HAVE_IPP
#define USE_IPP_SORT
typedef IppStatus (CV_STDCALL * IppSortFunc)(void *, int);
typedef IppSortFunc IppFlipFunc;
static IppSortFunc getSortFunc(int depth, bool sortDescending)
{
if (!sortDescending)
return depth == CV_8U ? (IppSortFunc)ippsSortAscend_8u_I :
#if IPP_DISABLE_BLOCK
depth == CV_16U ? (IppSortFunc)ippsSortAscend_16u_I :
depth == CV_16S ? (IppSortFunc)ippsSortAscend_16s_I :
depth == CV_32S ? (IppSortFunc)ippsSortAscend_32s_I :
depth == CV_32F ? (IppSortFunc)ippsSortAscend_32f_I :
depth == CV_64F ? (IppSortFunc)ippsSortAscend_64f_I :
#endif
0;
else
return depth == CV_8U ? (IppSortFunc)ippsSortDescend_8u_I :
#if IPP_DISABLE_BLOCK
depth == CV_16U ? (IppSortFunc)ippsSortDescend_16u_I :
depth == CV_16S ? (IppSortFunc)ippsSortDescend_16s_I :
depth == CV_32S ? (IppSortFunc)ippsSortDescend_32s_I :
depth == CV_32F ? (IppSortFunc)ippsSortDescend_32f_I :
depth == CV_64F ? (IppSortFunc)ippsSortDescend_64f_I :
#endif
0;
}
static IppFlipFunc getFlipFunc(int depth)
{
CV_SUPPRESS_DEPRECATED_START
return
depth == CV_8U || depth == CV_8S ? (IppFlipFunc)ippsFlip_8u_I :
depth == CV_16U || depth == CV_16S ? (IppFlipFunc)ippsFlip_16u_I :
depth == CV_32S || depth == CV_32F ? (IppFlipFunc)ippsFlip_32f_I :
depth == CV_64F ? (IppFlipFunc)ippsFlip_64f_I : 0;
CV_SUPPRESS_DEPRECATED_END
}
#endif
template<typename T> static void sort_( const Mat& src, Mat& dst, int flags )
{
AutoBuffer<T> buf;
@ -4017,17 +3973,6 @@ template<typename T> static void sort_( const Mat& src, Mat& dst, int flags )
}
bptr = (T*)buf;
#ifdef USE_IPP_SORT
int depth = src.depth();
IppSortFunc ippSortFunc = 0;
IppFlipFunc ippFlipFunc = 0;
CV_IPP_CHECK()
{
ippSortFunc = getSortFunc(depth, sortDescending);
ippFlipFunc = getFlipFunc(depth);
}
#endif
for( int i = 0; i < n; i++ )
{
T* ptr = bptr;
@ -4047,41 +3992,12 @@ template<typename T> static void sort_( const Mat& src, Mat& dst, int flags )
ptr[j] = src.ptr<T>(j)[i];
}
#ifdef USE_IPP_SORT
if (!ippSortFunc || CV_INSTRUMENT_FUN_IPP(ippSortFunc, ptr, len) < 0)
#endif
std::sort( ptr, ptr + len );
if( sortDescending )
{
#ifdef USE_IPP_SORT
if (depth == CV_8U)
setIppErrorStatus();
#endif
std::sort( ptr, ptr + len );
if( sortDescending )
{
#ifdef USE_IPP_SORT
if (!ippFlipFunc || CV_INSTRUMENT_FUN_IPP(ippFlipFunc, ptr, len) < 0)
#endif
{
#ifdef USE_IPP_SORT
setIppErrorStatus();
#endif
for( int j = 0; j < len/2; j++ )
std::swap(ptr[j], ptr[len-1-j]);
}
#ifdef USE_IPP_SORT
else
{
CV_IMPL_ADD(CV_IMPL_IPP);
}
#endif
}
for( int j = 0; j < len/2; j++ )
std::swap(ptr[j], ptr[len-1-j]);
}
#ifdef USE_IPP_SORT
else
{
CV_IMPL_ADD(CV_IMPL_IPP);
}
#endif
if( !sortRows )
for( int j = 0; j < len; j++ )
@ -4089,6 +4005,94 @@ template<typename T> static void sort_( const Mat& src, Mat& dst, int flags )
}
}
#ifdef HAVE_IPP
typedef IppStatus (CV_STDCALL *IppSortFunc)(void *pSrcDst, int len, Ipp8u *pBuffer);
static IppSortFunc getSortFunc(int depth, bool sortDescending)
{
if (!sortDescending)
return depth == CV_8U ? (IppSortFunc)ippsSortRadixAscend_8u_I :
depth == CV_16U ? (IppSortFunc)ippsSortRadixAscend_16u_I :
depth == CV_16S ? (IppSortFunc)ippsSortRadixAscend_16s_I :
depth == CV_32S ? (IppSortFunc)ippsSortRadixAscend_32s_I :
depth == CV_32F ? (IppSortFunc)ippsSortRadixAscend_32f_I :
depth == CV_64F ? (IppSortFunc)ippsSortRadixAscend_64f_I :
0;
else
return depth == CV_8U ? (IppSortFunc)ippsSortRadixDescend_8u_I :
depth == CV_16U ? (IppSortFunc)ippsSortRadixDescend_16u_I :
depth == CV_16S ? (IppSortFunc)ippsSortRadixDescend_16s_I :
depth == CV_32S ? (IppSortFunc)ippsSortRadixDescend_32s_I :
depth == CV_32F ? (IppSortFunc)ippsSortRadixDescend_32f_I :
depth == CV_64F ? (IppSortFunc)ippsSortRadixDescend_64f_I :
0;
}
static bool ipp_sort(const Mat& src, Mat& dst, int flags)
{
CV_INSTRUMENT_REGION_IPP()
bool sortRows = (flags & 1) == CV_SORT_EVERY_ROW;
bool sortDescending = (flags & CV_SORT_DESCENDING) != 0;
bool inplace = (src.data == dst.data);
int depth = src.depth();
IppDataType type = ippiGetDataType(depth);
IppSortFunc ippsSortRadix_I = getSortFunc(depth, sortDescending);
if(!ippsSortRadix_I)
return false;
if(sortRows)
{
AutoBuffer<Ipp8u> buffer;
int bufferSize;
if(ippsSortRadixGetBufferSize(src.cols, type, &bufferSize) < 0)
return false;
buffer.allocate(bufferSize);
if(!inplace)
src.copyTo(dst);
for(int i = 0; i < dst.rows; i++)
{
if(CV_INSTRUMENT_FUN_IPP(ippsSortRadix_I, (void*)dst.ptr(i), dst.cols, buffer) < 0)
return false;
}
}
else
{
AutoBuffer<Ipp8u> buffer;
int bufferSize;
if(ippsSortRadixGetBufferSize(src.rows, type, &bufferSize) < 0)
return false;
buffer.allocate(bufferSize);
Mat row(1, src.rows, src.type());
Mat srcSub;
Mat dstSub;
Rect subRect(0,0,1,src.rows);
for(int i = 0; i < src.cols; i++)
{
subRect.x = i;
srcSub = Mat(src, subRect);
dstSub = Mat(dst, subRect);
srcSub.copyTo(row);
if(CV_INSTRUMENT_FUN_IPP(ippsSortRadix_I, (void*)row.ptr(), dst.rows, buffer) < 0)
return false;
row = row.reshape(1, dstSub.rows);
row.copyTo(dstSub);
}
}
return true;
}
#endif
template<typename _Tp> class LessThanIdx
{
public:
@ -4097,30 +4101,6 @@ public:
const _Tp* arr;
};
#if defined USE_IPP_SORT && IPP_DISABLE_BLOCK
typedef IppStatus (CV_STDCALL *IppSortIndexFunc)(void *, int *, int);
static IppSortIndexFunc getSortIndexFunc(int depth, bool sortDescending)
{
if (!sortDescending)
return depth == CV_8U ? (IppSortIndexFunc)ippsSortIndexAscend_8u_I :
depth == CV_16U ? (IppSortIndexFunc)ippsSortIndexAscend_16u_I :
depth == CV_16S ? (IppSortIndexFunc)ippsSortIndexAscend_16s_I :
depth == CV_32S ? (IppSortIndexFunc)ippsSortIndexAscend_32s_I :
depth == CV_32F ? (IppSortIndexFunc)ippsSortIndexAscend_32f_I :
depth == CV_64F ? (IppSortIndexFunc)ippsSortIndexAscend_64f_I : 0;
else
return depth == CV_8U ? (IppSortIndexFunc)ippsSortIndexDescend_8u_I :
depth == CV_16U ? (IppSortIndexFunc)ippsSortIndexDescend_16u_I :
depth == CV_16S ? (IppSortIndexFunc)ippsSortIndexDescend_16s_I :
depth == CV_32S ? (IppSortIndexFunc)ippsSortIndexDescend_32s_I :
depth == CV_32F ? (IppSortIndexFunc)ippsSortIndexDescend_32f_I :
depth == CV_64F ? (IppSortIndexFunc)ippsSortIndexDescend_64f_I : 0;
}
#endif
template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
{
AutoBuffer<T> buf;
@ -4142,17 +4122,6 @@ template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
T* bptr = (T*)buf;
int* _iptr = (int*)ibuf;
#if defined USE_IPP_SORT && IPP_DISABLE_BLOCK
int depth = src.depth();
IppSortIndexFunc ippFunc = 0;
IppFlipFunc ippFlipFunc = 0;
CV_IPP_CHECK()
{
ippFunc = getSortIndexFunc(depth, sortDescending);
ippFlipFunc = getFlipFunc(depth);
}
#endif
for( int i = 0; i < n; i++ )
{
T* ptr = bptr;
@ -4171,40 +4140,12 @@ template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
for( int j = 0; j < len; j++ )
iptr[j] = j;
#if defined USE_IPP_SORT && IPP_DISABLE_BLOCK
if (sortRows || !ippFunc || ippFunc(ptr, iptr, len) < 0)
#endif
std::sort( iptr, iptr + len, LessThanIdx<T>(ptr) );
if( sortDescending )
{
#if defined USE_IPP_SORT && IPP_DISABLE_BLOCK
setIppErrorStatus();
#endif
std::sort( iptr, iptr + len, LessThanIdx<T>(ptr) );
if( sortDescending )
{
#if defined USE_IPP_SORT && IPP_DISABLE_BLOCK
if (!ippFlipFunc || ippFlipFunc(iptr, len) < 0)
#endif
{
#if defined USE_IPP_SORT && IPP_DISABLE_BLOCK
setIppErrorStatus();
#endif
for( int j = 0; j < len/2; j++ )
std::swap(iptr[j], iptr[len-1-j]);
}
#if defined USE_IPP_SORT && IPP_DISABLE_BLOCK
else
{
CV_IMPL_ADD(CV_IMPL_IPP);
}
#endif
}
for( int j = 0; j < len/2; j++ )
std::swap(iptr[j], iptr[len-1-j]);
}
#if defined USE_IPP_SORT && IPP_DISABLE_BLOCK
else
{
CV_IMPL_ADD(CV_IMPL_IPP);
}
#endif
if( !sortRows )
for( int j = 0; j < len; j++ )
@ -4212,24 +4153,110 @@ template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
}
}
typedef void (*SortFunc)(const Mat& src, Mat& dst, int flags);
#ifdef HAVE_IPP
#if !IPP_DISABLE_SORT_IDX
typedef IppStatus (CV_STDCALL *IppSortIndexFunc)(const void* pSrc, Ipp32s srcStrideBytes, Ipp32s *pDstIndx, int len, Ipp8u *pBuffer);
static IppSortIndexFunc getSortIndexFunc(int depth, bool sortDescending)
{
if (!sortDescending)
return depth == CV_8U ? (IppSortIndexFunc)ippsSortRadixIndexAscend_8u :
depth == CV_16U ? (IppSortIndexFunc)ippsSortRadixIndexAscend_16u :
depth == CV_16S ? (IppSortIndexFunc)ippsSortRadixIndexAscend_16s :
depth == CV_32S ? (IppSortIndexFunc)ippsSortRadixIndexAscend_32s :
depth == CV_32F ? (IppSortIndexFunc)ippsSortRadixIndexAscend_32f :
0;
else
return depth == CV_8U ? (IppSortIndexFunc)ippsSortRadixIndexDescend_8u :
depth == CV_16U ? (IppSortIndexFunc)ippsSortRadixIndexDescend_16u :
depth == CV_16S ? (IppSortIndexFunc)ippsSortRadixIndexDescend_16s :
depth == CV_32S ? (IppSortIndexFunc)ippsSortRadixIndexDescend_32s :
depth == CV_32F ? (IppSortIndexFunc)ippsSortRadixIndexDescend_32f :
0;
}
static bool ipp_sortIdx( const Mat& src, Mat& dst, int flags )
{
CV_INSTRUMENT_REGION_IPP()
bool sortRows = (flags & 1) == CV_SORT_EVERY_ROW;
bool sortDescending = (flags & CV_SORT_DESCENDING) != 0;
int depth = src.depth();
IppDataType type = ippiGetDataType(depth);
Ipp32s elemSize = (Ipp32s)src.elemSize1();
IppSortIndexFunc ippsSortRadixIndex = getSortIndexFunc(depth, sortDescending);
if(!ippsSortRadixIndex)
return false;
if(sortRows)
{
AutoBuffer<Ipp8u> buffer;
int bufferSize;
if(ippsSortRadixIndexGetBufferSize(src.cols, type, &bufferSize) < 0)
return false;
buffer.allocate(bufferSize);
for(int i = 0; i < src.rows; i++)
{
if(CV_INSTRUMENT_FUN_IPP(ippsSortRadixIndex, (void*)src.ptr(i), elemSize, (Ipp32s*)dst.ptr(i), src.cols, buffer) < 0)
return false;
}
}
else
{
Mat dstRow(1, dst.rows, dst.type());
Mat dstSub;
Rect subRect(0,0,1,src.rows);
AutoBuffer<Ipp8u> buffer;
int bufferSize;
if(ippsSortRadixIndexGetBufferSize(src.rows, type, &bufferSize) < 0)
return false;
buffer.allocate(bufferSize);
Ipp32s pixStride = elemSize*dst.cols;
for(int i = 0; i < src.cols; i++)
{
subRect.x = i;
dstSub = Mat(dst, subRect);
if(CV_INSTRUMENT_FUN_IPP(ippsSortRadixIndex, (void*)src.ptr(0, i), pixStride, (Ipp32s*)dstRow.ptr(), src.rows, buffer) < 0)
return false;
dstRow = dstRow.reshape(1, dstSub.rows);
dstRow.copyTo(dstSub);
}
}
return true;
}
#endif
#endif
typedef void (*SortFunc)(const Mat& src, Mat& dst, int flags);
}
void cv::sort( InputArray _src, OutputArray _dst, int flags )
{
CV_INSTRUMENT_REGION()
Mat src = _src.getMat();
CV_Assert( src.dims <= 2 && src.channels() == 1 );
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
CV_IPP_RUN_FAST(ipp_sort(src, dst, flags));
static SortFunc tab[] =
{
sort_<uchar>, sort_<schar>, sort_<ushort>, sort_<short>,
sort_<int>, sort_<float>, sort_<double>, 0
};
Mat src = _src.getMat();
SortFunc func = tab[src.depth()];
CV_Assert( src.dims <= 2 && src.channels() == 1 && func != 0 );
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
CV_Assert( func != 0 );
func( src, dst, flags );
}
@ -4237,20 +4264,24 @@ void cv::sortIdx( InputArray _src, OutputArray _dst, int flags )
{
CV_INSTRUMENT_REGION()
static SortFunc tab[] =
{
sortIdx_<uchar>, sortIdx_<schar>, sortIdx_<ushort>, sortIdx_<short>,
sortIdx_<int>, sortIdx_<float>, sortIdx_<double>, 0
};
Mat src = _src.getMat();
SortFunc func = tab[src.depth()];
CV_Assert( src.dims <= 2 && src.channels() == 1 && func != 0 );
CV_Assert( src.dims <= 2 && src.channels() == 1 );
Mat dst = _dst.getMat();
if( dst.data == src.data )
_dst.release();
_dst.create( src.size(), CV_32S );
dst = _dst.getMat();
#if !IPP_DISABLE_SORT_IDX
CV_IPP_RUN_FAST(ipp_sortIdx(src, dst, flags));
#endif
static SortFunc tab[] =
{
sortIdx_<uchar>, sortIdx_<schar>, sortIdx_<ushort>, sortIdx_<short>,
sortIdx_<int>, sortIdx_<float>, sortIdx_<double>, 0
};
SortFunc func = tab[src.depth()];
CV_Assert( func != 0 );
func( src, dst, flags );
}

View File

@ -1738,19 +1738,19 @@ IntrumentationRegion::~IntrumentationRegion()
namespace ipp
{
#ifdef HAVE_IPP
struct IPPInitSingleton
{
public:
IPPInitSingleton()
{
useIPP = true;
ippStatus = 0;
funcname = NULL;
filename = NULL;
linen = 0;
ippFeatures = 0;
useIPP = true;
ippStatus = 0;
funcname = NULL;
filename = NULL;
linen = 0;
ippFeatures = 0;
#ifdef HAVE_IPP
const char* pIppEnv = getenv("OPENCV_IPP");
cv::String env = pIppEnv;
if(env.size())
@ -1783,7 +1783,7 @@ public:
}
IPP_INITIALIZER(ippFeatures)
#endif
ippFeatures = ippGetEnabledCpuFeatures();
}
bool useIPP;
@ -1792,18 +1792,27 @@ public:
const char *funcname;
const char *filename;
int linen;
int ippFeatures;
Ipp64u ippFeatures;
};
static IPPInitSingleton& getIPPSingleton()
{
CV_SINGLETON_LAZY_INIT_REF(IPPInitSingleton, new IPPInitSingleton())
}
#endif
#if OPENCV_ABI_COMPATIBILITY > 300
unsigned long long getIppFeatures()
#else
int getIppFeatures()
#endif
{
#ifdef HAVE_IPP
#if OPENCV_ABI_COMPATIBILITY > 300
return getIPPSingleton().ippFeatures;
#else
return (int)getIPPSingleton().ippFeatures;
#endif
#else
return 0;
#endif
@ -1811,20 +1820,32 @@ int getIppFeatures()
void setIppStatus(int status, const char * const _funcname, const char * const _filename, int _line)
{
#ifdef HAVE_IPP
getIPPSingleton().ippStatus = status;
getIPPSingleton().funcname = _funcname;
getIPPSingleton().filename = _filename;
getIPPSingleton().linen = _line;
#else
CV_UNUSED(status); CV_UNUSED(_funcname); CV_UNUSED(_filename); CV_UNUSED(_line);
#endif
}
int getIppStatus()
{
#ifdef HAVE_IPP
return getIPPSingleton().ippStatus;
#else
return 0;
#endif
}
String getIppErrorLocation()
{
#ifdef HAVE_IPP
return format("%s:%d %s", getIPPSingleton().filename ? getIPPSingleton().filename : "", getIPPSingleton().linen, getIPPSingleton().funcname ? getIPPSingleton().funcname : "");
#else
return String();
#endif
}
bool useIPP()

View File

@ -446,19 +446,23 @@ static ippiGeneralFunc ippiCopyP3C3RTab[] =
0, (ippiGeneralFunc)ippiCopy_32f_P3C3R, 0, 0
};
#if !IPP_DISABLE_RGB_XYZ
static ippiGeneralFunc ippiRGB2XYZTab[] =
{
(ippiGeneralFunc)ippiRGBToXYZ_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToXYZ_16u_C3R, 0,
0, (ippiGeneralFunc)ippiRGBToXYZ_32f_C3R, 0, 0
};
#endif
#if !IPP_DISABLE_XYZ_RGB
static ippiGeneralFunc ippiXYZ2RGBTab[] =
{
(ippiGeneralFunc)ippiXYZToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiXYZToRGB_16u_C3R, 0,
0, (ippiGeneralFunc)ippiXYZToRGB_32f_C3R, 0, 0
};
#endif
#if IPP_DISABLE_BLOCK
#if !IPP_DISABLE_RGB_HSV
static ippiGeneralFunc ippiRGB2HSVTab[] =
{
(ippiGeneralFunc)ippiRGBToHSV_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToHSV_16u_C3R, 0,
@ -484,13 +488,15 @@ static ippiGeneralFunc ippiHLS2RGBTab[] =
0, (ippiGeneralFunc)ippiHLSToRGB_32f_C3R, 0, 0
};
#if IPP_DISABLE_BLOCK
#if !IPP_DISABLE_RGB_LAB
static ippiGeneralFunc ippiRGBToLUVTab[] =
{
(ippiGeneralFunc)ippiRGBToLUV_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToLUV_16u_C3R, 0,
0, (ippiGeneralFunc)ippiRGBToLUV_32f_C3R, 0, 0
};
#endif
#if !IPP_DISABLE_LAB_RGB
static ippiGeneralFunc ippiLUVToRGBTab[] =
{
(ippiGeneralFunc)ippiLUVToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiLUVToRGB_16u_C3R, 0,
@ -8714,41 +8720,6 @@ void cvtBGRtoBGR5x5(const uchar * src_data, size_t src_step,
CALL_HAL(cvtBGRtoBGR5x5, cv_hal_cvtBGRtoBGR5x5, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, greenBits);
#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK // breaks OCL accuracy tests
CV_IPP_CHECK()
{
CV_SUPPRESS_DEPRECATED_START;
if (scn == 3 && greenBits == 6 && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R)))
return;
}
else if (scn == 4 && greenBits == 6 && !swapBlue)
{
if (CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(CV_8U, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[CV_8U],
(ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 0, 1, 2, CV_8U)))
return;
}
else if (scn == 3 && greenBits == 6 && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(CV_8U, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[CV_8U],
(ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, CV_8U)) )
return;
}
else if (scn == 4 && greenBits == 6 && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(CV_8U, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[CV_8U],
(ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, CV_8U)) )
return;
}
CV_SUPPRESS_DEPRECATED_END;
}
#endif
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB5x5(scn, swapBlue ? 2 : 0, greenBits));
}
@ -8762,41 +8733,6 @@ void cvtBGR5x5toBGR(const uchar * src_data, size_t src_step,
CALL_HAL(cvtBGR5x5toBGR, cv_hal_cvtBGR5x5toBGR, src_data, src_step, dst_data, dst_step, width, height, dcn, swapBlue, greenBits);
#if defined(HAVE_IPP) && IPP_VERSION_X100 < 900
CV_IPP_CHECK()
{
CV_SUPPRESS_DEPRECATED_START;
if (dcn == 3 && greenBits == 6 && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R)))
return;
}
else if (dcn == 3 && greenBits == 6 && swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R,
ippiSwapChannelsC3RTab[CV_8U], 2, 1, 0, CV_8U)))
return;
}
else if (dcn == 4 && greenBits == 6 && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R,
ippiSwapChannelsC3C4RTab[CV_8U], 0, 1, 2, CV_8U)))
return;
}
else if (dcn == 4 && greenBits == 6 && swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R,
ippiSwapChannelsC3C4RTab[CV_8U], 2, 1, 0, CV_8U)))
return;
}
CV_SUPPRESS_DEPRECATED_END;
}
#endif
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB5x52RGB(dcn, swapBlue ? 2 : 0, greenBits));
}
@ -8813,30 +8749,30 @@ void cvtBGRtoGray(const uchar * src_data, size_t src_step,
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
CV_IPP_CHECK()
{
if(depth == CV_32F && scn == 3 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPColor2GrayFunctor(ippiColor2GrayC3Tab[depth])) )
return;
}
else if(depth == CV_32F && scn == 3 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiRGB2GrayC3Tab[depth])) )
return;
}
else if(depth == CV_32F && scn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPColor2GrayFunctor(ippiColor2GrayC4Tab[depth])) )
return;
}
else if(depth == CV_32F && scn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiRGB2GrayC4Tab[depth])) )
return;
}
if(depth == CV_32F && scn == 3 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPColor2GrayFunctor(ippiColor2GrayC3Tab[depth])) )
return;
}
else if(depth == CV_32F && scn == 3 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiRGB2GrayC3Tab[depth])) )
return;
}
else if(depth == CV_32F && scn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPColor2GrayFunctor(ippiColor2GrayC4Tab[depth])) )
return;
}
else if(depth == CV_32F && scn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiRGB2GrayC4Tab[depth])) )
return;
}
}
#endif
@ -8862,18 +8798,18 @@ void cvtGraytoBGR(const uchar * src_data, size_t src_step,
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
CV_IPP_CHECK()
{
if(dcn == 3)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
if(dcn == 3)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGray2BGRFunctor(ippiCopyP3C3RTab[depth])) )
return;
}
else if(dcn == 4)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
return;
}
else if(dcn == 4)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGray2BGRAFunctor(ippiCopyP3C3RTab[depth], ippiSwapChannelsC3C4RTab[depth], depth)) )
return;
}
return;
}
}
#endif
@ -8919,37 +8855,39 @@ void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
CALL_HAL(cvtBGRtoYUV, cv_hal_cvtBGRtoYUV, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isCbCr);
#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK
#if defined(HAVE_IPP)
#if !IPP_DISABLE_RGB_YUV
CV_IPP_CHECK()
{
if (scn == 3 && depth == CV_8U && swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiRGBToYUV_8u_C3R)))
return;
}
else if (scn == 3 && depth == CV_8U && !swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth],
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth)))
return;
}
else if (scn == 4 && depth == CV_8U && swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 0, 1, 2, depth)))
return;
}
else if (scn == 4 && depth == CV_8U && !swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth)))
return;
}
if (scn == 3 && depth == CV_8U && swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiRGBToYUV_8u_C3R)))
return;
}
else if (scn == 3 && depth == CV_8U && !swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth],
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth)))
return;
}
else if (scn == 4 && depth == CV_8U && swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 0, 1, 2, depth)))
return;
}
else if (scn == 4 && depth == CV_8U && !swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
(ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth)))
return;
}
}
#endif
#endif
int blueIdx = swapBlue ? 2 : 0;
@ -8971,37 +8909,39 @@ void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
CALL_HAL(cvtYUVtoBGR, cv_hal_cvtYUVtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isCbCr);
#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK
#if defined(HAVE_IPP)
#if !IPP_DISABLE_YUV_RGB
CV_IPP_CHECK()
{
if (dcn == 3 && depth == CV_8U && swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R)))
return;
}
else if (dcn == 3 && depth == CV_8U && !swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)))
return;
}
else if (dcn == 4 && depth == CV_8U && swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)))
return;
}
else if (dcn == 4 && depth == CV_8U && !swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)))
return;
}
if (dcn == 3 && depth == CV_8U && swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R)))
return;
}
else if (dcn == 3 && depth == CV_8U && !swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)))
return;
}
else if (dcn == 4 && depth == CV_8U && swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)))
return;
}
else if (dcn == 4 && depth == CV_8U && !swapBlue && !isCbCr)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R,
ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)))
return;
}
}
#endif
#endif
int blueIdx = swapBlue ? 2 : 0;
@ -9023,33 +8963,35 @@ void cvtBGRtoXYZ(const uchar * src_data, size_t src_step,
CALL_HAL(cvtBGRtoXYZ, cv_hal_cvtBGRtoXYZ, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue);
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
#if !IPP_DISABLE_RGB_XYZ
CV_IPP_CHECK()
{
if(scn == 3 && depth != CV_32F && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 4 && depth != CV_32F && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 3 && depth != CV_32F && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiRGB2XYZTab[depth])) )
return;
}
else if(scn == 4 && depth != CV_32F && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 0, 1, 2, depth)) )
return;
}
if(scn == 3 && depth != CV_32F && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 4 && depth != CV_32F && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 3 && depth != CV_32F && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, scn), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiRGB2XYZTab[depth])) )
return;
}
else if(scn == 4 && depth != CV_32F && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 0, 1, 2, depth)) )
return;
}
}
#endif
#endif
int blueIdx = swapBlue ? 2 : 0;
@ -9071,33 +9013,35 @@ void cvtXYZtoBGR(const uchar * src_data, size_t src_step,
CALL_HAL(cvtXYZtoBGR, cv_hal_cvtXYZtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue);
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
#if !IPP_DISABLE_XYZ_RGB
CV_IPP_CHECK()
{
if(dcn == 3 && depth != CV_32F && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 4 && depth != CV_32F && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
if(dcn == 3 && depth != CV_32F && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiXYZ2RGBTab[depth])) )
return;
}
else if(dcn == 4 && depth != CV_32F && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
if(dcn == 3 && depth != CV_32F && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 4 && depth != CV_32F && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
if(dcn == 3 && depth != CV_32F && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiXYZ2RGBTab[depth])) )
return;
}
else if(dcn == 4 && depth != CV_32F && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
}
#endif
#endif
int blueIdx = swapBlue ? 2 : 0;
@ -9122,60 +9066,60 @@ void cvtBGRtoHSV(const uchar * src_data, size_t src_step,
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
CV_IPP_CHECK()
{
if (depth == CV_8U && isFullRange)
{
if (isHSV)
if(depth == CV_8U && isFullRange)
{
#if IPP_DISABLE_BLOCK // breaks OCL accuracy tests
if(scn == 3 && !swapBlue)
if (isHSV)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) )
return;
}
#if !IPP_DISABLE_RGB_HSV // breaks OCL accuracy tests
if(scn == 3 && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) )
return;
}
#endif
}
else
{
if(scn == 3 && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 4 && !swapBlue)
else
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 3 && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiRGB2HLSTab[depth])) )
return;
}
else if(scn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) )
return;
if(scn == 3 && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) )
return;
}
else if(scn == 3 && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiRGB2HLSTab[depth])) )
return;
}
else if(scn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) )
return;
}
}
}
}
}
#endif
int hrange = depth == CV_32F ? 360 : isFullRange ? 256 : 180;
@ -9209,63 +9153,63 @@ void cvtHSVtoBGR(const uchar * src_data, size_t src_step,
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
CV_IPP_CHECK()
{
if (depth == CV_8U && isFullRange)
{
if (isHSV)
if (depth == CV_8U && isFullRange)
{
if(dcn == 3 && !swapBlue)
if (isHSV)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
if(dcn == 3 && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 3 && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiHSV2RGBTab[depth])) )
return;
}
else if(dcn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
}
else if(dcn == 4 && !swapBlue)
else
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 3 && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiHSV2RGBTab[depth])) )
return;
}
else if(dcn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
if(dcn == 3 && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 3 && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiHLS2RGBTab[depth])) )
return;
}
else if(dcn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
}
}
else
{
if(dcn == 3 && !swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
else if(dcn == 3 && swapBlue)
{
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKETYPE(depth, 3), dst_data, dst_step, width, height,
IPPGeneralFunctor(ippiHLS2RGBTab[depth])) )
return;
}
else if(dcn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
}
}
}
#endif
@ -9297,72 +9241,72 @@ void cvtBGRtoLab(const uchar * src_data, size_t src_step,
CALL_HAL(cvtBGRtoLab, cv_hal_cvtBGRtoLab, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isLab, srgb);
#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK
#if defined(HAVE_IPP) && !IPP_DISABLE_RGB_LAB
CV_IPP_CHECK()
{
if (!srgb)
{
if (isLab)
if (!srgb)
{
if (scn == 3 && depth == CV_8U && !swapBlue)
if (isLab)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToLab_8u_C3R)))
return;
if (scn == 3 && depth == CV_8U && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToLab_8u_C3R)))
return;
}
else if (scn == 4 && depth == CV_8U && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
(ippiGeneralFunc)ippiBGRToLab_8u_C3R, 0, 1, 2, depth)))
return;
}
else if (scn == 3 && depth == CV_8U && swapBlue) // slower than OpenCV
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth],
(ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth)))
return;
}
else if (scn == 4 && depth == CV_8U && swapBlue) // slower than OpenCV
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
(ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth)))
return;
}
}
else if (scn == 4 && depth == CV_8U && !swapBlue)
else
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
(ippiGeneralFunc)ippiBGRToLab_8u_C3R, 0, 1, 2, depth)))
return;
}
else if (scn == 3 && depth == CV_8U && swapBlue) // slower than OpenCV
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth],
(ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth)))
return;
}
else if (scn == 4 && depth == CV_8U && swapBlue) // slower than OpenCV
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
(ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth)))
return;
if (scn == 3 && swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralFunctor(ippiRGBToLUVTab[depth])))
return;
}
else if (scn == 4 && swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
ippiRGBToLUVTab[depth], 0, 1, 2, depth)))
return;
}
else if (scn == 3 && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth],
ippiRGBToLUVTab[depth], 2, 1, 0, depth)))
return;
}
else if (scn == 4 && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
ippiRGBToLUVTab[depth], 2, 1, 0, depth)))
return;
}
}
}
else
{
if (scn == 3 && swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralFunctor(ippiRGBToLUVTab[depth])))
return;
}
else if (scn == 4 && swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
ippiRGBToLUVTab[depth], 0, 1, 2, depth)))
return;
}
else if (scn == 3 && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth],
ippiRGBToLUVTab[depth], 2, 1, 0, depth)))
return;
}
else if (scn == 4 && !swapBlue)
{
if (CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth],
ippiRGBToLUVTab[depth], 2, 1, 0, depth)))
return;
}
}
}
}
#endif
@ -9394,72 +9338,72 @@ void cvtLabtoBGR(const uchar * src_data, size_t src_step,
CALL_HAL(cvtLabtoBGR, cv_hal_cvtLabtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isLab, srgb);
#if defined(HAVE_IPP) && IPP_DISABLE_BLOCK
#if defined(HAVE_IPP) && !IPP_DISABLE_LAB_RGB
CV_IPP_CHECK()
{
if (!srgb)
{
if (isLab)
if (!srgb)
{
if( dcn == 3 && depth == CV_8U && !swapBlue)
if (isLab)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R)) )
return;
if( dcn == 3 && depth == CV_8U && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R)) )
return;
}
else if( dcn == 4 && depth == CV_8U && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R,
ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
if( dcn == 3 && depth == CV_8U && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R,
ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if( dcn == 4 && depth == CV_8U && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R,
ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
}
else if( dcn == 4 && depth == CV_8U && !swapBlue)
else
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R,
ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
if( dcn == 3 && depth == CV_8U && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R,
ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if( dcn == 4 && depth == CV_8U && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R,
ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
if( dcn == 3 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralFunctor(ippiLUVToRGBTab[depth])) )
return;
}
else if( dcn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth],
ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
if( dcn == 3 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth],
ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if( dcn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth],
ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
}
}
else
{
if( dcn == 3 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralFunctor(ippiLUVToRGBTab[depth])) )
return;
}
else if( dcn == 4 && swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth],
ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) )
return;
}
if( dcn == 3 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth],
ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) )
return;
}
else if( dcn == 4 && !swapBlue)
{
if( CvtColorIPPLoop(src_data, src_step, dst_data,dst_step, width, height,
IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth],
ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) )
return;
}
}
}
}
#endif
@ -9894,9 +9838,11 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
_dst.create(dstSz, CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
#ifdef HAVE_IPP
if (CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C1R, src.data, (int)src.step, dst.data, (int)dst.step,
ippiSize(dstSz.width, dstSz.height)) >= 0)
#if IPP_VERSION_X100 >= 201700
if (CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C1R_L, src.data, (IppSizeL)src.step, dst.data, (IppSizeL)dst.step,
ippiSizeL(dstSz.width, dstSz.height)) >= 0)
break;
#endif
#endif
src(Range(0, dstSz.height), Range::all()).copyTo(dst);
}

View File

@ -302,338 +302,91 @@ namespace cv
#ifdef HAVE_IPP
namespace cv
{
static bool IPPDerivScharr(InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, double scale, double delta, int borderType)
static bool ipp_Deriv(InputArray _src, OutputArray _dst, int dx, int dy, int ksize, double scale, double delta, int borderType)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 810
if ((0 > dx) || (0 > dy) || (1 != dx + dy))
return false;
if (fabs(delta) > FLT_EPSILON)
::ipp::IwiSize size(_src.size().width, _src.size().height);
IppDataType srcType = ippiGetDataType(_src.depth());
IppDataType dstType = ippiGetDataType(_dst.depth());
int channels = _src.channels();
bool useScale = false;
bool useScharr = false;
if(channels != _dst.channels() || channels > 1)
return false;
IppiBorderType ippiBorderType = ippiGetBorderType(borderType & (~BORDER_ISOLATED));
if ((int)ippiBorderType < 0)
if(fabs(delta) > FLT_EPSILON || fabs(scale-1) > FLT_EPSILON)
useScale = true;
if(ksize <= 0)
{
ksize = 3;
useScharr = true;
}
IppiMaskSize maskSize = ippiGetMaskSize(ksize, ksize);
if(maskSize < 0)
return false;
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0)
ddepth = sdepth;
int dtype = CV_MAKETYPE(ddepth, cn);
#if IPP_VERSION_X100 <= 201703
// Bug with mirror wrap
if(borderType == BORDER_REFLECT_101 && (ksize/2+1 > size.width || ksize/2+1 > size.height))
return false;
#endif
Mat src = _src.getMat();
if (0 == (BORDER_ISOLATED & borderType))
IwiDerivativeType derivType = ippiGetDerivType(dx, dy, (useScharr)?false:true);
if(derivType < 0)
return false;
// Acquire data and begin processing
try
{
Size size; Point offset;
src.locateROI(size, offset);
if (0 < offset.x)
ippiBorderType = (IppiBorderType)(ippiBorderType | ippBorderInMemLeft);
if (0 < offset.y)
ippiBorderType = (IppiBorderType)(ippiBorderType | ippBorderInMemTop);
if (offset.x + src.cols < size.width)
ippiBorderType = (IppiBorderType)(ippiBorderType | ippBorderInMemRight);
if (offset.y + src.rows < size.height)
ippiBorderType = (IppiBorderType)(ippiBorderType | ippBorderInMemBottom);
}
Mat src = _src.getMat();
Mat dst = _dst.getMat();
::ipp::IwiImage iwSrc = ippiGetImage(src);
::ipp::IwiImage iwDst = ippiGetImage(dst);
::ipp::IwiImage iwSrcProc = iwSrc;
::ipp::IwiImage iwDstProc = iwDst;
::ipp::IwiBorderSize borderSize(maskSize);
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
if(!ippBorder.m_borderType)
return false;
bool horz = (0 == dx) && (1 == dy);
IppiSize roiSize = {src.cols, src.rows};
_dst.create( _src.size(), dtype);
Mat dst = _dst.getMat();
IppStatus sts = ippStsErr;
if ((CV_8U == stype) && (CV_16S == dtype))
{
int bufferSize = 0; Ipp8u *pBuffer;
if (horz)
if(srcType == ipp8u && dstType == ipp8u)
{
if (0 > ippiFilterScharrHorizMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp8u, ipp16s, 1, &bufferSize))
return false;
pBuffer = ippsMalloc_8u(bufferSize);
if (NULL == pBuffer)
return false;
sts = CV_INSTRUMENT_FUN_IPP(ippiFilterScharrHorizMaskBorder_8u16s_C1R, src.ptr(), (int)src.step, dst.ptr<Ipp16s>(), (int)dst.step, roiSize, ippMskSize3x3, ippiBorderType, 0, pBuffer);
iwDstProc.Alloc(iwDst.m_size, ipp16s, channels);
useScale = true;
}
else if(srcType == ipp8u && dstType == ipp32f)
{
iwSrc -= borderSize;
iwSrcProc.Alloc(iwSrc.m_size, ipp32f, channels);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwSrc, &iwSrcProc, 1, 0, ippAlgHintFast);
iwSrcProc += borderSize;
}
if(useScharr)
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterScharr, &iwSrcProc, &iwDstProc, derivType, maskSize, ippBorder);
else
{
if (0 > ippiFilterScharrVertMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp8u, ipp16s, 1, &bufferSize))
return false;
pBuffer = ippsMalloc_8u(bufferSize);
if (NULL == pBuffer)
return false;
sts = CV_INSTRUMENT_FUN_IPP(ippiFilterScharrVertMaskBorder_8u16s_C1R, src.ptr(), (int)src.step, dst.ptr<Ipp16s>(), (int)dst.step, roiSize, ippMskSize3x3, ippiBorderType, 0, pBuffer);
}
ippsFree(pBuffer);
}
else if ((CV_16S == stype) && (CV_16S == dtype))
{
int bufferSize = 0; Ipp8u *pBuffer;
if (horz)
{
if (0 > ippiFilterScharrHorizMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp16s, ipp16s, 1, &bufferSize))
return false;
pBuffer = ippsMalloc_8u(bufferSize);
if (NULL == pBuffer)
return false;
sts = CV_INSTRUMENT_FUN_IPP(ippiFilterScharrHorizMaskBorder_16s_C1R, src.ptr<Ipp16s>(), (int)src.step, dst.ptr<Ipp16s>(), (int)dst.step, roiSize, ippMskSize3x3, ippiBorderType, 0, pBuffer);
}
else
{
if (0 > ippiFilterScharrVertMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp16s, ipp16s, 1, &bufferSize))
return false;
pBuffer = ippsMalloc_8u(bufferSize);
if (NULL == pBuffer)
return false;
sts = CV_INSTRUMENT_FUN_IPP(ippiFilterScharrVertMaskBorder_16s_C1R, src.ptr<Ipp16s>(), (int)src.step, dst.ptr<Ipp16s>(), (int)dst.step, roiSize, ippMskSize3x3, ippiBorderType, 0, pBuffer);
}
ippsFree(pBuffer);
}
else if ((CV_32F == stype) && (CV_32F == dtype))
{
int bufferSize = 0; Ipp8u *pBuffer;
if (horz)
{
if (0 > ippiFilterScharrHorizMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp32f, ipp32f, 1, &bufferSize))
return false;
pBuffer = ippsMalloc_8u(bufferSize);
if (NULL == pBuffer)
return false;
sts = CV_INSTRUMENT_FUN_IPP(ippiFilterScharrHorizMaskBorder_32f_C1R, src.ptr<Ipp32f>(), (int)src.step, dst.ptr<Ipp32f>(), (int)dst.step, roiSize, ippMskSize3x3, ippiBorderType, 0, pBuffer);
}
else
{
if (0 > ippiFilterScharrVertMaskBorderGetBufferSize(roiSize, ippMskSize3x3, ipp32f, ipp32f, 1, &bufferSize))
return false;
pBuffer = ippsMalloc_8u(bufferSize);
if (NULL == pBuffer)
return false;
sts = CV_INSTRUMENT_FUN_IPP(ippiFilterScharrVertMaskBorder_32f_C1R, src.ptr<Ipp32f>(), (int)src.step, dst.ptr<Ipp32f>(), (int)dst.step, roiSize, ippMskSize3x3, ippiBorderType, 0, pBuffer);
}
ippsFree(pBuffer);
if (sts < 0)
return false;;
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterSobel, &iwSrcProc, &iwDstProc, derivType, maskSize, ippBorder);
if (FLT_EPSILON < fabs(scale - 1.0))
sts = CV_INSTRUMENT_FUN_IPP(ippiMulC_32f_C1R, dst.ptr<Ipp32f>(), (int)dst.step, (Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, roiSize);
if(useScale)
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwDstProc, &iwDst, scale, delta, ippAlgHintFast);
}
return (0 <= sts);
catch (::ipp::IwException)
{
return false;
}
return true;
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(ddepth); CV_UNUSED(dx); CV_UNUSED(dy); CV_UNUSED(scale); CV_UNUSED(delta); CV_UNUSED(borderType);
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(dx); CV_UNUSED(dy); CV_UNUSED(ksize); CV_UNUSED(scale); CV_UNUSED(delta); CV_UNUSED(borderType);
return false;
#endif
}
static bool IPPDerivSobel(InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType)
{
CV_INSTRUMENT_REGION_IPP()
if (((borderType & ~BORDER_ISOLATED) != BORDER_REPLICATE) || ((3 != ksize) && (5 != ksize)))
return false;
if (fabs(delta) > FLT_EPSILON)
return false;
if (1 != _src.channels())
return false;
int bufSize = 0;
cv::AutoBuffer<char> buffer;
Mat src = _src.getMat(), dst = _dst.getMat();
if ((borderType & BORDER_ISOLATED) == 0 && src.isSubmatrix())
return false;
if ( ddepth < 0 )
ddepth = src.depth();
IppiSize roi = {src.cols, src.rows};
IppiMaskSize kernel = (IppiMaskSize)(ksize*10+ksize);
if (src.type() == CV_8U && dst.type() == CV_16S && scale == 1)
{
if ((dx == 1) && (dy == 0))
{
#if IPP_VERSION_X100 >= 900
if (0 > ippiFilterSobelNegVertBorderGetBufferSize(roi, kernel, ipp8u, ipp16s, 1,&bufSize))
return false;
buffer.allocate(bufSize);
#else
if (0 > ippiFilterSobelNegVertGetBufferSize_8u16s_C1R(roi, kernel,&bufSize))
return false;
buffer.allocate(bufSize);
#endif
if (0 > CV_INSTRUMENT_FUN_IPP(ippiFilterSobelNegVertBorder_8u16s_C1R, src.ptr<Ipp8u>(), (int)src.step,
dst.ptr<Ipp16s>(), (int)dst.step, roi, kernel,
ippBorderRepl, 0, (Ipp8u*)(char*)buffer))
return false;
return true;
}
if ((dx == 0) && (dy == 1))
{
#if IPP_VERSION_X100 >= 900
if (0 > ippiFilterSobelHorizBorderGetBufferSize(roi, kernel, ipp8u, ipp16s, 1,&bufSize))
return false;
buffer.allocate(bufSize);
#else
if (0 > ippiFilterSobelHorizGetBufferSize_8u16s_C1R(roi, kernel,&bufSize))
return false;
buffer.allocate(bufSize);
#endif
if (0 > CV_INSTRUMENT_FUN_IPP(ippiFilterSobelHorizBorder_8u16s_C1R, src.ptr<Ipp8u>(), (int)src.step,
dst.ptr<Ipp16s>(), (int)dst.step, roi, kernel,
ippBorderRepl, 0, (Ipp8u*)(char*)buffer))
return false;
return true;
}
if ((dx == 2) && (dy == 0))
{
#if IPP_VERSION_X100 >= 900
if (0 > ippiFilterSobelVertSecondBorderGetBufferSize(roi, kernel, ipp8u, ipp16s, 1,&bufSize))
return false;
buffer.allocate(bufSize);
#else
if (0 > ippiFilterSobelVertSecondGetBufferSize_8u16s_C1R(roi, kernel,&bufSize))
return false;
buffer.allocate(bufSize);
#endif
if (0 > CV_INSTRUMENT_FUN_IPP(ippiFilterSobelVertSecondBorder_8u16s_C1R, src.ptr<Ipp8u>(), (int)src.step,
dst.ptr<Ipp16s>(), (int)dst.step, roi, kernel,
ippBorderRepl, 0, (Ipp8u*)(char*)buffer))
return false;
return true;
}
if ((dx == 0) && (dy == 2))
{
#if IPP_VERSION_X100 >= 900
if (0 > ippiFilterSobelHorizSecondBorderGetBufferSize(roi, kernel, ipp8u, ipp16s, 1,&bufSize))
return false;
buffer.allocate(bufSize);
#else
if (0 > ippiFilterSobelHorizSecondGetBufferSize_8u16s_C1R(roi, kernel,&bufSize))
return false;
buffer.allocate(bufSize);
#endif
if (0 > CV_INSTRUMENT_FUN_IPP(ippiFilterSobelHorizSecondBorder_8u16s_C1R, src.ptr<Ipp8u>(), (int)src.step,
dst.ptr<Ipp16s>(), (int)dst.step, roi, kernel,
ippBorderRepl, 0, (Ipp8u*)(char*)buffer))
return false;
return true;
}
}
if (src.type() == CV_32F && dst.type() == CV_32F)
{
#if IPP_DISABLE_BLOCK
if ((dx == 1) && (dy == 0))
{
#if IPP_VERSION_X100 >= 900
if (0 > ippiFilterSobelNegVertBorderGetBufferSize(roi, kernel, ipp32f, ipp32f, 1,&bufSize))
return false;
buffer.allocate(bufSize);
#else
if (0 > ippiFilterSobelNegVertGetBufferSize_32f_C1R(roi, kernel, &bufSize))
return false;
buffer.allocate(bufSize);
#endif
if (0 > ippiFilterSobelNegVertBorder_32f_C1R(src.ptr<Ipp32f>(), (int)src.step,
dst.ptr<Ipp32f>(), (int)dst.step, roi, kernel,
ippBorderRepl, 0, (Ipp8u*)(char*)buffer))
return false;
if(scale != 1)
ippiMulC_32f_C1R(dst.ptr<Ipp32f>(), (int)dst.step, (Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows));
return true;
}
if ((dx == 0) && (dy == 1))
{
#if IPP_VERSION_X100 >= 900
if (0 > ippiFilterSobelHorizBorderGetBufferSize(roi, kernel, ipp32f, ipp32f, 1,&bufSize))
return false;
buffer.allocate(bufSize);
#else
if (0 > ippiFilterSobelHorizGetBufferSize_32f_C1R(roi, kernel,&bufSize))
return false;
buffer.allocate(bufSize);
#endif
if (0 > ippiFilterSobelHorizBorder_32f_C1R(src.ptr<Ipp32f>(), (int)src.step,
dst.ptr<Ipp32f>(), (int)dst.step, roi, kernel,
ippBorderRepl, 0, (Ipp8u*)(char*)buffer))
return false;
if(scale != 1)
ippiMulC_32f_C1R(dst.ptr<Ipp32f>(), (int)dst.step, (Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows));
return true;
}
#endif
if((dx == 2) && (dy == 0))
{
#if IPP_VERSION_X100 >= 900
if (0 > ippiFilterSobelVertSecondBorderGetBufferSize(roi, kernel, ipp32f, ipp32f, 1,&bufSize))
return false;
buffer.allocate(bufSize);
#else
if (0 > ippiFilterSobelVertSecondGetBufferSize_32f_C1R(roi, kernel,&bufSize))
return false;
buffer.allocate(bufSize);
#endif
if (0 > CV_INSTRUMENT_FUN_IPP(ippiFilterSobelVertSecondBorder_32f_C1R, src.ptr<Ipp32f>(), (int)src.step,
dst.ptr<Ipp32f>(), (int)dst.step, roi, kernel,
ippBorderRepl, 0, (Ipp8u*)(char*)buffer))
return false;
if(scale != 1)
CV_INSTRUMENT_FUN_IPP(ippiMulC_32f_C1R, dst.ptr<Ipp32f>(), (int)dst.step, (Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows));
return true;
}
if((dx == 0) && (dy == 2))
{
#if IPP_VERSION_X100 >= 900
if (0 > ippiFilterSobelHorizSecondBorderGetBufferSize(roi, kernel, ipp32f, ipp32f, 1,&bufSize))
return false;
buffer.allocate(bufSize);
#else
if (0 > ippiFilterSobelHorizSecondGetBufferSize_32f_C1R(roi, kernel,&bufSize))
return false;
buffer.allocate(bufSize);
#endif
if (0 > CV_INSTRUMENT_FUN_IPP(ippiFilterSobelHorizSecondBorder_32f_C1R, src.ptr<Ipp32f>(), (int)src.step,
dst.ptr<Ipp32f>(), (int)dst.step, roi, kernel,
ippBorderRepl, 0, (Ipp8u*)(char*)buffer))
return false;
if(scale != 1)
CV_INSTRUMENT_FUN_IPP(ippiMulC_32f_C1R, dst.ptr<Ipp32f>(), (int)dst.step, (Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, ippiSize(dst.cols*dst.channels(), dst.rows));
return true;
}
}
return false;
}
static bool ipp_sobel(InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType)
{
CV_INSTRUMENT_REGION_IPP()
if (ksize < 0)
{
if (IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType))
return true;
}
else if (0 < ksize)
{
if (IPPDerivSobel(_src, _dst, ddepth, dx, dy, ksize, scale, delta, borderType))
return true;
}
return false;
}
}
#endif
@ -722,7 +475,7 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
CV_OVX_RUN(true,
openvx_sobel(_src, _dst, dx, dy, ksize, scale, delta, borderType))
CV_IPP_RUN(!(ocl::useOpenCL() && _dst.isUMat()), ipp_sobel(_src, _dst, ddepth, dx, dy, ksize, scale, delta, borderType));
CV_IPP_RUN(!(ocl::useOpenCL() && _dst.isUMat()), ipp_Deriv(_src, _dst, dx, dy, ksize, scale, delta, borderType));
int ktype = std::max(CV_32F, std::max(ddepth, sdepth));
@ -766,7 +519,7 @@ void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
}
#endif
CV_IPP_RUN(!(ocl::useOpenCL() && _dst.isUMat()), IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType));
CV_IPP_RUN(!(ocl::useOpenCL() && _dst.isUMat()), ipp_Deriv(_src, _dst, dx, dy, 0, scale, delta, borderType));
int ktype = std::max(CV_32F, std::max(ddepth, sdepth));
@ -986,69 +739,71 @@ static bool ocl_Laplacian3_8UC1(InputArray _src, OutputArray _dst, int ddepth,
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_Laplacian(InputArray _src, OutputArray _dst, int ddepth, int ksize,
double scale, double delta, int borderType)
static bool ipp_Laplacian(InputArray _src, OutputArray _dst, int ksize, double scale, double delta, int borderType)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0)
ddepth = sdepth;
_dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );
::ipp::IwiSize size(_src.size().width, _src.size().height);
IppDataType srcType = ippiGetDataType(_src.depth());
IppDataType dstType = ippiGetDataType(_dst.depth());
int channels = _src.channels();
bool useScale = false;
int iscale = saturate_cast<int>(scale), idelta = saturate_cast<int>(delta);
bool floatScale = std::fabs(scale - iscale) > DBL_EPSILON, needScale = iscale != 1;
bool floatDelta = std::fabs(delta - idelta) > DBL_EPSILON, needDelta = delta != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
Mat src = _src.getMat(), dst = _dst.getMat();
if(channels != _dst.channels() || channels > 1)
return false;
if (src.data != dst.data)
if(fabs(delta) > FLT_EPSILON || fabs(scale-1) > FLT_EPSILON)
useScale = true;
IppiMaskSize maskSize = ippiGetMaskSize(ksize, ksize);
if(maskSize < 0)
return false;
// Acquire data and begin processing
try
{
Ipp32s bufsize;
IppStatus status = (IppStatus)-1;
IppiSize roisize = { src.cols, src.rows };
IppiMaskSize masksize = ksize == 3 ? ippMskSize3x3 : ippMskSize5x5;
IppiBorderType borderTypeIpp = ippiGetBorderType(borderTypeNI);
Mat src = _src.getMat();
Mat dst = _dst.getMat();
::ipp::IwiImage iwSrc = ippiGetImage(src);
::ipp::IwiImage iwDst = ippiGetImage(dst);
::ipp::IwiImage iwSrcProc = iwSrc;
::ipp::IwiImage iwDstProc = iwDst;
::ipp::IwiBorderSize borderSize(maskSize);
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
if(!ippBorder.m_borderType)
return false;
#define IPP_FILTER_LAPLACIAN(ippsrctype, ippdsttype, ippfavor) \
do \
{ \
if (borderTypeIpp >= 0 && ippiFilterLaplacianGetBufferSize_##ippfavor##_C1R(roisize, masksize, &bufsize) >= 0) \
{ \
Ipp8u * buffer = ippsMalloc_8u(bufsize); \
status = CV_INSTRUMENT_FUN_IPP(ippiFilterLaplacianBorder_##ippfavor##_C1R, src.ptr<ippsrctype>(), (int)src.step, dst.ptr<ippdsttype>(), \
(int)dst.step, roisize, masksize, borderTypeIpp, 0, buffer); \
ippsFree(buffer); \
} \
} while ((void)0, 0)
CV_SUPPRESS_DEPRECATED_START
if (sdepth == CV_8U && ddepth == CV_16S && !floatScale && !floatDelta)
if(srcType == ipp8u && dstType == ipp8u)
{
IPP_FILTER_LAPLACIAN(Ipp8u, Ipp16s, 8u16s);
if (needScale && status >= 0)
status = CV_INSTRUMENT_FUN_IPP(ippiMulC_16s_C1IRSfs, (Ipp16s)iscale, dst.ptr<Ipp16s>(), (int)dst.step, roisize, 0);
if (needDelta && status >= 0)
status = CV_INSTRUMENT_FUN_IPP(ippiAddC_16s_C1IRSfs, (Ipp16s)idelta, dst.ptr<Ipp16s>(), (int)dst.step, roisize, 0);
iwDstProc.Alloc(iwDst.m_size, ipp16s, channels);
useScale = true;
}
else if (sdepth == CV_32F && ddepth == CV_32F)
else if(srcType == ipp8u && dstType == ipp32f)
{
IPP_FILTER_LAPLACIAN(Ipp32f, Ipp32f, 32f);
if (needScale && status >= 0)
status = CV_INSTRUMENT_FUN_IPP(ippiMulC_32f_C1IR, (Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, roisize);
if (needDelta && status >= 0)
status = CV_INSTRUMENT_FUN_IPP(ippiAddC_32f_C1IR, (Ipp32f)delta, dst.ptr<Ipp32f>(), (int)dst.step, roisize);
iwSrc -= borderSize;
iwSrcProc.Alloc(iwSrc.m_size, ipp32f, channels);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwSrc, &iwSrcProc, 1, 0);
iwSrcProc += borderSize;
}
CV_SUPPRESS_DEPRECATED_END
if (status >= 0)
return true;
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterLaplacian, &iwSrcProc, &iwDstProc, maskSize, ippBorder);
if(useScale)
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwDstProc, &iwDst, scale, delta);
}
catch (::ipp::IwException ex)
{
return false;
}
#undef IPP_FILTER_LAPLACIAN
return true;
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(ksize); CV_UNUSED(scale); CV_UNUSED(delta); CV_UNUSED(borderType);
return false;
#endif
}
}
#endif
@ -1080,9 +835,7 @@ void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
ocl_Laplacian3_8UC1(_src, _dst, ddepth, kernel, delta, borderType));
}
CV_IPP_RUN((ksize == 3 || ksize == 5) && ((borderType & BORDER_ISOLATED) != 0 || !_src.isSubmatrix()) &&
((stype == CV_8UC1 && ddepth == CV_16S) || (ddepth == CV_32F && stype == CV_32FC1)) && (!cv::ocl::useOpenCL()),
ipp_Laplacian(_src, _dst, ddepth, ksize, scale, delta, borderType));
CV_IPP_RUN(!(cv::ocl::useOpenCL() && _dst.isUMat()), ipp_Laplacian(_src, _dst, ksize, scale, delta, borderType));
#ifdef HAVE_TEGRA_OPTIMIZATION

View File

@ -681,6 +681,8 @@ namespace cv
{
static void distanceTransform_L1_8U(InputArray _src, OutputArray _dst)
{
CV_INSTRUMENT_REGION()
Mat src = _src.getMat();
CV_Assert( src.type() == CV_8UC1);
@ -745,7 +747,9 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe
#ifdef HAVE_IPP
CV_IPP_CHECK()
{
if ((currentParallelFramework()==NULL) || (src.total()<(int)(1<<14)))
#if IPP_DISABLE_PERF_TRUE_DIST_MT
if(cv::getNumThreads()<=1 || (src.total()<(int)(1<<14)))
#endif
{
IppStatus status;
IppiSize roi = { src.cols, src.rows };
@ -755,7 +759,7 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe
status = ippiTrueDistanceTransformGetBufferSize_8u32f_C1R(roi, &bufSize);
if (status>=0)
{
pBuffer = (Ipp8u *)ippMalloc( bufSize );
pBuffer = (Ipp8u *)CV_IPP_MALLOC( bufSize );
status = CV_INSTRUMENT_FUN_IPP(ippiTrueDistanceTransform_8u32f_C1R, src.ptr<uchar>(), (int)src.step, dst.ptr<float>(), (int)dst.step, roi, pBuffer);
ippFree( pBuffer );
if (status>=0)

View File

@ -4635,7 +4635,7 @@ static bool ippFilter2D(int stype, int dtype,
int ddepth = CV_MAT_DEPTH(dtype);
int sdepth = CV_MAT_DEPTH(stype);
#if IPP_VERSION_X100 >= 201700 && IPP_VERSION_X100 < 201702 // IPP bug with 1x1 kernel
#if IPP_VERSION_X100 >= 201700 && IPP_VERSION_X100 <= 201702 // IPP bug with 1x1 kernel
if(kernel_width == 1 && kernel_height == 1)
return false;
#endif
@ -4662,6 +4662,7 @@ static bool ippFilter2D(int stype, int dtype,
Ipp32s bufsize = 0;
IppiSize dstRoiSize = { width, height };
IppStatus status;
status = ippiFilterBorderGetSize(kernelSize, dstRoiSize, dataType, kernelType, cn, &specSize, &bufsize);
if (status < 0)
return false;
@ -4670,7 +4671,7 @@ static bool ippFilter2D(int stype, int dtype,
size_t good_kernel_step = sizeof(kernel_type) * static_cast<size_t>(kernelSize.width);
#if IPP_VERSION_X100 >= 900
if (kernel_step != good_kernel_step) {
kernelBuffer.Alloc((int)good_kernel_step * kernelSize.height);
kernelBuffer.allocate((int)good_kernel_step * kernelSize.height);
status = trait::get_copy_fun()((kernel_type*)kernel_data, (int)kernel_step, kernelBuffer, (int)good_kernel_step, kernelSize);
if (status < 0)
return false;
@ -4683,8 +4684,8 @@ static bool ippFilter2D(int stype, int dtype,
flip(kernel, kerFlip, -1);
pKerBuffer = kernelBuffer;
#endif
spec.Alloc(specSize);
buffer.Alloc(bufsize);
spec.allocate(specSize);
buffer.allocate(bufsize);
status = trait::runInit(pKerBuffer, kernelSize, 0, dataType, cn, ippRndFinancial, spec);
if (status < 0) {
return false;

View File

@ -1178,86 +1178,150 @@ calcHist_8u( std::vector<uchar*>& _ptrs, const std::vector<int>& _deltas,
}
#ifdef HAVE_IPP
class IPPCalcHistInvoker :
public ParallelLoopBody
typedef IppStatus(CV_STDCALL * IppiHistogram_C1)(const void* pSrc, int srcStep,
IppiSize roiSize, Ipp32u* pHist, const IppiHistogramSpec* pSpec, Ipp8u* pBuffer);
static IppiHistogram_C1 getIppiHistogramFunction_C1(int type)
{
IppiHistogram_C1 ippFunction =
(type == CV_8UC1) ? (IppiHistogram_C1)ippiHistogram_8u_C1R :
#if IPP_VERSION_X100 >= 201700 || !(defined HAVE_IPP_ICV_ONLY)
(type == CV_16UC1) ? (IppiHistogram_C1)ippiHistogram_16u_C1R :
(type == CV_32FC1) ? (IppiHistogram_C1)ippiHistogram_32f_C1R :
#endif
NULL;
return ippFunction;
}
class ipp_calcHistParallelTLS
{
public:
IPPCalcHistInvoker(const Mat & _src, Mat & _hist, AutoBuffer<Ipp32f> & _levels, Ipp32s _histSize, Ipp32f _low, Ipp32f _high, bool * _ok) :
ParallelLoopBody(), src(&_src), hist(&_hist), levels(&_levels), histSize(_histSize), low(_low), high(_high), ok(_ok)
ipp_calcHistParallelTLS() {}
IppAutoBuffer<IppiHistogramSpec> spec;
IppAutoBuffer<Ipp8u> buffer;
IppAutoBuffer<Ipp32u> thist;
};
class ipp_calcHistParallel: public ParallelLoopBody
{
public:
ipp_calcHistParallel(const Mat &src, Mat &hist, Ipp32s histSize, const float *ranges, bool uniform, bool &ok):
ParallelLoopBody(), m_src(src), m_hist(hist), m_ok(ok)
{
*ok = true;
ok = true;
m_uniform = uniform;
m_ranges = ranges;
m_histSize = histSize;
m_type = ippiGetDataType(src.type());
m_levelsNum = histSize+1;
ippiHistogram_C1 = getIppiHistogramFunction_C1(src.type());
if(!ippiHistogram_C1)
{
ok = false;
return;
}
m_fullRoi = ippiSize(src.size());
m_bufferSize = 0;
m_specSize = 0;
if(ippiHistogramGetBufferSize(m_type, m_fullRoi, &m_levelsNum, 1, 1, &m_specSize, &m_bufferSize) < 0)
{
ok = false;
return;
}
hist.setTo(0);
}
virtual void operator() (const Range & range) const
{
Ipp32s levelNum = histSize + 1;
Mat phist(hist->size(), hist->type(), Scalar::all(0));
#if IPP_VERSION_X100 >= 900
IppiSize roi = {src->cols, range.end - range.start};
int bufferSize = 0;
int specSize = 0;
IppiHistogramSpec *pSpec = NULL;
Ipp8u *pBuffer = NULL;
CV_INSTRUMENT_REGION_IPP()
if(ippiHistogramGetBufferSize(ipp8u, roi, &levelNum, 1, 1, &specSize, &bufferSize) < 0)
if(!m_ok)
return;
ipp_calcHistParallelTLS *pTls = m_tls.get();
IppiSize roi = {m_src.cols, range.end - range.start };
bool mtLoop = false;
if(m_fullRoi.height != roi.height)
mtLoop = true;
if(!pTls->spec)
{
*ok = false;
pTls->spec.allocate(m_specSize);
if(!pTls->spec.get())
{
m_ok = false;
return;
}
pTls->buffer.allocate(m_bufferSize);
if(!pTls->buffer.get() && m_bufferSize)
{
m_ok = false;
return;
}
if(m_uniform)
{
if(ippiHistogramUniformInit(m_type, (Ipp32f*)&m_ranges[0], (Ipp32f*)&m_ranges[1], (Ipp32s*)&m_levelsNum, 1, pTls->spec) < 0)
{
m_ok = false;
return;
}
}
else
{
if(ippiHistogramInit(m_type, (const Ipp32f**)&m_ranges, (Ipp32s*)&m_levelsNum, 1, pTls->spec) < 0)
{
m_ok = false;
return;
}
}
pTls->thist.allocate(m_histSize*sizeof(Ipp32u));
}
if(CV_INSTRUMENT_FUN_IPP(ippiHistogram_C1, m_src.ptr(range.start), (int)m_src.step, roi, pTls->thist, pTls->spec, pTls->buffer) < 0)
{
m_ok = false;
return;
}
pBuffer = (Ipp8u*)ippMalloc(bufferSize);
if(!pBuffer && bufferSize)
if(mtLoop)
{
*ok = false;
return;
for(int i = 0; i < m_histSize; i++)
CV_XADD((int*)(m_hist.ptr(i)), *(int*)((Ipp32u*)pTls->thist + i));
}
pSpec = (IppiHistogramSpec*)ippMalloc(specSize);
if(!pSpec && specSize)
{
if(pBuffer) ippFree(pBuffer);
*ok = false;
return;
}
if(ippiHistogramUniformInit(ipp8u, (Ipp32f*)&low, (Ipp32f*)&high, (Ipp32s*)&levelNum, 1, pSpec) < 0)
{
if(pSpec) ippFree(pSpec);
if(pBuffer) ippFree(pBuffer);
*ok = false;
return;
}
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippiHistogram_8u_C1R, src->ptr(range.start), (int)src->step, ippiSize(src->cols, range.end - range.start),
phist.ptr<Ipp32u>(), pSpec, pBuffer);
if(pSpec) ippFree(pSpec);
if(pBuffer) ippFree(pBuffer);
#else
CV_SUPPRESS_DEPRECATED_START
IppStatus status = ippiHistogramEven_8u_C1R(src->ptr(range.start), (int)src->step, ippiSize(src->cols, range.end - range.start),
phist.ptr<Ipp32s>(), (Ipp32s*)(Ipp32f*)*levels, levelNum, (Ipp32s)low, (Ipp32s)high);
CV_SUPPRESS_DEPRECATED_END
#endif
if(status < 0)
{
*ok = false;
return;
}
for (int i = 0; i < histSize; ++i)
CV_XADD((int *)(hist->data + i * hist->step), *(int *)(phist.data + i * phist.step));
else
ippiCopy_32s_C1R((Ipp32s*)pTls->thist.get(), sizeof(Ipp32u), (Ipp32s*)m_hist.ptr(), (int)m_hist.step, ippiSize(1, m_histSize));
}
private:
const Mat * src;
Mat * hist;
AutoBuffer<Ipp32f> * levels;
Ipp32s histSize;
Ipp32f low, high;
bool * ok;
const Mat &m_src;
Mat &m_hist;
Ipp32s m_histSize;
const float *m_ranges;
bool m_uniform;
const IPPCalcHistInvoker & operator = (const IPPCalcHistInvoker & );
IppiHistogram_C1 ippiHistogram_C1;
IppiSize m_fullRoi;
IppDataType m_type;
Ipp32s m_levelsNum;
int m_bufferSize;
int m_specSize;
mutable Mutex m_syncMutex;
TLSData<ipp_calcHistParallelTLS> m_tls;
volatile bool &m_ok;
const ipp_calcHistParallel & operator = (const ipp_calcHistParallel & );
};
#endif
@ -1319,49 +1383,49 @@ namespace cv
}
#endif
#if defined(HAVE_IPP)
#ifdef HAVE_IPP
#define IPP_HISTOGRAM_PARALLEL 1
namespace cv
{
static bool ipp_calchist(const Mat* images, int nimages, const int* channels,
InputArray _mask, OutputArray _hist, int dims, const int* histSize,
const float** ranges, bool uniform, bool accumulate )
static bool ipp_calchist(const Mat &image, Mat &hist, int histSize, const float** ranges, bool uniform, bool accumulate)
{
CV_INSTRUMENT_REGION_IPP()
Mat mask = _mask.getMat();
CV_Assert(dims > 0 && histSize);
_hist.create(dims, histSize, CV_32F);
Mat hist = _hist.getMat(), ihist = hist;
ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
{
if (nimages == 1 && images[0].type() == CV_8UC1 && dims == 1 && channels &&
channels[0] == 0 && mask.empty() && images[0].dims <= 2 &&
!accumulate && uniform)
{
ihist.setTo(Scalar::all(0));
AutoBuffer<Ipp32f> levels(histSize[0]);
bool ok = true;
const Mat & src = images[0];
int nstripes = std::min<int>(8, static_cast<int>(src.total() / (1 << 16)));
#ifdef HAVE_CONCURRENCY
nstripes = 1;
// No SSE42 optimization for uniform 32f
#if IPP_DISABLE_PERF_HISTU32F_SSE42
if(uniform && image.depth() == CV_32F && !(ipp::getIppFeatures()&ippCPUID_AVX))
return false;
#endif
IPPCalcHistInvoker invoker(src, ihist, levels, histSize[0], ranges[0][0], ranges[0][1], &ok);
Range range(0, src.rows);
parallel_for_(range, invoker, nstripes);
if (ok)
{
ihist.convertTo(hist, CV_32F);
return true;
}
Mat ihist = hist;
if(accumulate)
ihist.create(1, &histSize, CV_32S);
bool ok = true;
int threads = ippiSuggestThreadsNum(image, (1+((double)ihist.total()/image.total()))*2);
Range range(0, image.rows);
ipp_calcHistParallel invoker(image, ihist, histSize, ranges[0], uniform, ok);
if(!ok)
return false;
if(IPP_HISTOGRAM_PARALLEL && threads > 1)
parallel_for_(range, invoker, threads*2);
else
invoker(range);
if(ok)
{
if(accumulate)
{
IppiSize histRoi = ippiSize(1, histSize);
IppAutoBuffer<Ipp32f> fhist(histSize*sizeof(Ipp32f));
CV_INSTRUMENT_FUN_IPP(ippiConvert_32s32f_C1R, (Ipp32s*)ihist.ptr(), (int)ihist.step, (Ipp32f*)fhist, sizeof(Ipp32f), histRoi);
CV_INSTRUMENT_FUN_IPP(ippiAdd_32f_C1IR, (Ipp32f*)fhist, sizeof(Ipp32f), (Ipp32f*)hist.ptr(), (int)hist.step, histRoi);
}
else
CV_INSTRUMENT_FUN_IPP(ippiConvert_32s32f_C1R, (Ipp32s*)ihist.ptr(), (int)ihist.step, (Ipp32f*)hist.ptr(), (int)hist.step, ippiSize(1, histSize));
}
return false;
return ok;
}
}
#endif
@ -1379,23 +1443,24 @@ void cv::calcHist( const Mat* images, int nimages, const int* channels,
ranges && ranges[0],
openvx_calchist(images[0], _hist, histSize[0], ranges[0]))
CV_IPP_RUN(nimages == 1 && images[0].type() == CV_8UC1 && dims == 1 && channels &&
channels[0] == 0 && _mask.getMat().empty() && images[0].dims <= 2 &&
!accumulate && uniform,
ipp_calchist(images, nimages, channels,
_mask, _hist, dims, histSize,
ranges, uniform, accumulate));
Mat mask = _mask.getMat();
CV_Assert(dims > 0 && histSize);
const uchar* const histdata = _hist.getMat().ptr();
_hist.create(dims, histSize, CV_32F);
Mat hist = _hist.getMat(), ihist = hist;
Mat hist = _hist.getMat();
if(histdata != hist.data)
accumulate = false;
CV_IPP_RUN(nimages == 1 && dims == 1 && channels && channels[0] == 0 && _mask.empty() && images[0].dims <= 2,
ipp_calchist(images[0], hist, histSize[0], ranges, uniform, accumulate));
Mat ihist = hist;
ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
if( !accumulate || histdata != hist.data )
if(!accumulate)
hist = Scalar(0.);
else
hist.convertTo(ihist, CV_32S);

View File

@ -57,73 +57,66 @@ using namespace cv;
namespace cv
{
#if IPP_VERSION_X100 >= 710
typedef IppStatus (CV_STDCALL* ippiResizeFunc)(const void*, int, const void*, int, IppiPoint, IppiSize, IppiBorderType, void*, void*, Ipp8u*);
typedef IppStatus (CV_STDCALL* ippiResizeGetBufferSize)(void*, IppiSize, Ipp32u, int*);
typedef IppStatus (CV_STDCALL* ippiResizeGetSrcOffset)(void*, IppiPoint, IppiPoint*);
#endif
#if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700) && IPP_DISABLE_BLOCK
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
typedef IppStatus (CV_STDCALL* ippiWarpPerspectiveFunc)(const void*, IppiSize, int, IppiRect, void *, int, IppiRect, double [3][3], int);
typedef IppStatus (CV_STDCALL* ippiWarpAffineBackFunc)(const void*, IppiSize, int, IppiRect, void *, int, IppiRect, double [2][3], int);
#if defined (HAVE_IPP) && (!IPP_DISABLE_WARPAFFINE || !IPP_DISABLE_WARPPERSPECTIVE || !IPP_DISABLE_REMAP)
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
template <int channels, typename Type>
bool IPPSetSimple(cv::Scalar value, void *dataPointer, int step, IppiSize &size, ippiSetFunc func)
template <int channels, typename Type>
bool IPPSetSimple(cv::Scalar value, void *dataPointer, int step, IppiSize &size, ippiSetFunc func)
{
CV_INSTRUMENT_REGION_IPP()
Type values[channels];
for( int i = 0; i < channels; i++ )
values[i] = saturate_cast<Type>(value[i]);
return func(values, dataPointer, step, size) >= 0;
}
static bool IPPSet(const cv::Scalar &value, void *dataPointer, int step, IppiSize &size, int channels, int depth)
{
CV_INSTRUMENT_REGION_IPP()
if( channels == 1 )
{
CV_INSTRUMENT_REGION_IPP()
Type values[channels];
for( int i = 0; i < channels; i++ )
values[i] = saturate_cast<Type>(value[i]);
return func(values, dataPointer, step, size) >= 0;
switch( depth )
{
case CV_8U:
return CV_INSTRUMENT_FUN_IPP(ippiSet_8u_C1R, saturate_cast<Ipp8u>(value[0]), (Ipp8u *)dataPointer, step, size) >= 0;
case CV_16U:
return CV_INSTRUMENT_FUN_IPP(ippiSet_16u_C1R, saturate_cast<Ipp16u>(value[0]), (Ipp16u *)dataPointer, step, size) >= 0;
case CV_32F:
return CV_INSTRUMENT_FUN_IPP(ippiSet_32f_C1R, saturate_cast<Ipp32f>(value[0]), (Ipp32f *)dataPointer, step, size) >= 0;
}
}
static bool IPPSet(const cv::Scalar &value, void *dataPointer, int step, IppiSize &size, int channels, int depth)
else
{
CV_INSTRUMENT_REGION_IPP()
if( channels == 1 )
if( channels == 3 )
{
switch( depth )
{
case CV_8U:
return CV_INSTRUMENT_FUN_IPP(ippiSet_8u_C1R,(saturate_cast<Ipp8u>(value[0]), (Ipp8u *)dataPointer, step, size)) >= 0;
return IPPSetSimple<3, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C3R);
case CV_16U:
return CV_INSTRUMENT_FUN_IPP(ippiSet_16u_C1R,(saturate_cast<Ipp16u>(value[0]), (Ipp16u *)dataPointer, step, size)) >= 0;
return IPPSetSimple<3, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C3R);
case CV_32F:
return CV_INSTRUMENT_FUN_IPP(ippiSet_32f_C1R,(saturate_cast<Ipp32f>(value[0]), (Ipp32f *)dataPointer, step, size)) >= 0;
return IPPSetSimple<3, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C3R);
}
}
else
else if( channels == 4 )
{
if( channels == 3 )
switch( depth )
{
switch( depth )
{
case CV_8U:
return IPPSetSimple<3, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C3R);
case CV_16U:
return IPPSetSimple<3, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C3R);
case CV_32F:
return IPPSetSimple<3, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C3R);
}
}
else if( channels == 4 )
{
switch( depth )
{
case CV_8U:
return IPPSetSimple<4, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C4R);
case CV_16U:
return IPPSetSimple<4, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C4R);
case CV_32F:
return IPPSetSimple<4, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C4R);
}
case CV_8U:
return IPPSetSimple<4, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C4R);
case CV_16U:
return IPPSetSimple<4, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C4R);
case CV_32F:
return IPPSetSimple<4, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C4R);
}
}
return false;
}
return false;
}
#endif
/************** interpolation formulas and tables ***************/
@ -2708,135 +2701,7 @@ static int computeResizeAreaTab( int ssize, int dsize, int cn, double scale, Dec
return k;
}
#define CHECK_IPP_STATUS(STATUS) if (STATUS < 0) { *ok = false; return; }
#define SET_IPP_RESIZE_LINEAR_FUNC_PTR(TYPE, CN) \
ippiResize = (ippiResizeFunc)ippiResizeLinear_##TYPE##_##CN##R; \
CHECK_IPP_STATUS(ippiResizeGetSize_##TYPE(srcSize, dstSize, (IppiInterpolationType)mode, 0, &specSize, &initSize));\
specBuf.allocate(specSize);\
pSpec = (uchar*)specBuf;\
CHECK_IPP_STATUS(ippiResizeLinearInit_##TYPE(srcSize, dstSize, (IppiResizeSpec_32f*)pSpec));
#define SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(TYPE, CN) \
if (mode == (int)ippCubic) { *ok = false; return; } \
ippiResize = (ippiResizeFunc)ippiResizeLinear_##TYPE##_##CN##R; \
CHECK_IPP_STATUS(ippiResizeGetSize_##TYPE(srcSize, dstSize, (IppiInterpolationType)mode, 0, &specSize, &initSize));\
specBuf.allocate(specSize);\
pSpec = (uchar*)specBuf;\
CHECK_IPP_STATUS(ippiResizeLinearInit_##TYPE(srcSize, dstSize, (IppiResizeSpec_64f*)pSpec));\
getBufferSizeFunc = (ippiResizeGetBufferSize)ippiResizeGetBufferSize_##TYPE;\
getSrcOffsetFunc = (ippiResizeGetSrcOffset) ippiResizeGetSrcOffset_##TYPE;
#define SET_IPP_RESIZE_CUBIC_FUNC_PTR(TYPE, CN) \
ippiResize = (ippiResizeFunc)ippiResizeCubic_##TYPE##_##CN##R; \
CHECK_IPP_STATUS(ippiResizeGetSize_##TYPE(srcSize, dstSize, (IppiInterpolationType)mode, 0, &specSize, &initSize));\
specBuf.allocate(specSize);\
pSpec = (uchar*)specBuf;\
AutoBuffer<uchar> buf(initSize);\
uchar* pInit = (uchar*)buf;\
CHECK_IPP_STATUS(ippiResizeCubicInit_##TYPE(srcSize, dstSize, 0.f, 0.75f, (IppiResizeSpec_32f*)pSpec, pInit));
#define SET_IPP_RESIZE_PTR(TYPE, CN) \
if (mode == (int)ippLinear) { SET_IPP_RESIZE_LINEAR_FUNC_PTR(TYPE, CN);} \
else if (mode == (int)ippCubic) { SET_IPP_RESIZE_CUBIC_FUNC_PTR(TYPE, CN);} \
else { *ok = false; return; } \
getBufferSizeFunc = (ippiResizeGetBufferSize)ippiResizeGetBufferSize_##TYPE; \
getSrcOffsetFunc = (ippiResizeGetSrcOffset)ippiResizeGetSrcOffset_##TYPE;
#if IPP_VERSION_X100 >= 710
class IPPresizeInvoker :
public ParallelLoopBody
{
public:
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), pSpec(NULL), mode(_mode),
ippiResize(NULL), getBufferSizeFunc(NULL), getSrcOffsetFunc(NULL), ok(_ok)
{
*ok = true;
IppiSize srcSize, dstSize;
int type = src.type(), specSize = 0, initSize = 0;
srcSize.width = src.cols;
srcSize.height = src.rows;
dstSize.width = dst.cols;
dstSize.height = dst.rows;
switch (type)
{
#if IPP_DISABLE_BLOCK // disabled since it breaks tests for CascadeClassifier
case CV_8UC1: SET_IPP_RESIZE_PTR(8u,C1); break;
case CV_8UC3: SET_IPP_RESIZE_PTR(8u,C3); break;
case CV_8UC4: SET_IPP_RESIZE_PTR(8u,C4); break;
#endif
case CV_16UC1: SET_IPP_RESIZE_PTR(16u,C1); break;
case CV_16UC3: SET_IPP_RESIZE_PTR(16u,C3); break;
case CV_16UC4: SET_IPP_RESIZE_PTR(16u,C4); break;
case CV_16SC1: SET_IPP_RESIZE_PTR(16s,C1); break;
case CV_16SC3: SET_IPP_RESIZE_PTR(16s,C3); break;
case CV_16SC4: SET_IPP_RESIZE_PTR(16s,C4); break;
case CV_32FC1: SET_IPP_RESIZE_PTR(32f,C1); break;
case CV_32FC3: SET_IPP_RESIZE_PTR(32f,C3); 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_64FC3: SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(64f,C3); break;
case CV_64FC4: SET_IPP_RESIZE_LINEAR_FUNC_64_PTR(64f,C4); break;
default: { *ok = false; return; } break;
}
}
~IPPresizeInvoker()
{
}
virtual void operator() (const Range& range) const
{
if (*ok == false)
return;
int cn = src.channels();
int dsty = min(cvRound(range.start * inv_scale_y), dst.rows);
int dstwidth = min(cvRound(src.cols * inv_scale_x), dst.cols);
int dstheight = min(cvRound(range.end * inv_scale_y), dst.rows);
IppiPoint dstOffset = { 0, dsty }, srcOffset = {0, 0};
IppiSize dstSize = { dstwidth, dstheight - dsty };
int bufsize = 0, itemSize = (int)src.elemSize1();
CHECK_IPP_STATUS(getBufferSizeFunc(pSpec, dstSize, cn, &bufsize));
CHECK_IPP_STATUS(getSrcOffsetFunc(pSpec, dstOffset, &srcOffset));
const Ipp8u* pSrc = src.ptr<Ipp8u>(srcOffset.y) + srcOffset.x * cn * itemSize;
Ipp8u* pDst = dst.ptr<Ipp8u>(dstOffset.y) + dstOffset.x * cn * itemSize;
AutoBuffer<uchar> buf(bufsize + 64);
uchar* bufptr = alignPtr((uchar*)buf, 32);
if( CV_INSTRUMENT_FUN_IPP(ippiResize, pSrc, (int)src.step[0], pDst, (int)dst.step[0], dstOffset, dstSize, ippBorderRepl, 0, pSpec, bufptr) < 0 )
*ok = false;
else
{
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
}
}
private:
const Mat & src;
Mat & dst;
double inv_scale_x;
double inv_scale_y;
void *pSpec;
AutoBuffer<uchar> specBuf;
int mode;
ippiResizeFunc ippiResize;
ippiResizeGetBufferSize getBufferSizeFunc;
ippiResizeGetSrcOffset getSrcOffsetFunc;
bool *ok;
const IPPresizeInvoker& operator= (const IPPresizeInvoker&);
};
#endif
#ifdef HAVE_OPENCL
static void ocl_computeResizeAreaTabs(int ssize, int dsize, double scale, int * const map_tab,
float * const alpha_tab, int * const ofs_tab)
{
@ -3090,28 +2955,190 @@ static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
#endif
#if IPP_VERSION_X100 >= 710
static bool ipp_resize_mt(Mat & src, Mat & dst,
double inv_scale_x, double inv_scale_y, int interpolation)
#ifdef HAVE_IPP
#define IPP_RESIZE_PARALLEL 1
#ifdef HAVE_IPP_IW
class ipp_resizeParallel: public ParallelLoopBody
{
public:
ipp_resizeParallel(::ipp::IwiImage &src, ::ipp::IwiImage &dst, bool &ok):
m_src(src), m_dst(dst), m_ok(ok) {}
~ipp_resizeParallel()
{
}
void Init(IppiInterpolationType inter)
{
iwiResize.InitAlloc(m_src.m_size, m_dst.m_size, m_src.m_dataType, m_src.m_channels, inter, ::ipp::IwiResizeParams(0, 0, 0.75, 4), ippBorderRepl);
m_ok = true;
}
virtual void operator() (const Range& range) const
{
CV_INSTRUMENT_REGION_IPP()
if(!m_ok)
return;
try
{
::ipp::IwiRoi roi = ::ipp::IwiRect(0, range.start, m_dst.m_size.width, range.end - range.start);
CV_INSTRUMENT_FUN_IPP(iwiResize, &m_src, &m_dst, &roi);
}
catch(::ipp::IwException)
{
m_ok = false;
return;
}
}
private:
::ipp::IwiImage &m_src;
::ipp::IwiImage &m_dst;
mutable ::ipp::IwiResize iwiResize;
volatile bool &m_ok;
const ipp_resizeParallel& operator= (const ipp_resizeParallel&);
};
class ipp_resizeAffineParallel: public ParallelLoopBody
{
public:
ipp_resizeAffineParallel(::ipp::IwiImage &src, ::ipp::IwiImage &dst, bool &ok):
m_src(src), m_dst(dst), m_ok(ok) {}
~ipp_resizeAffineParallel()
{
}
void Init(IppiInterpolationType inter, double scaleX, double scaleY)
{
double shift = (inter == ippNearest)?-1e-10:-0.5;
double coeffs[2][3] = {
{scaleX, 0, shift+0.5*scaleX},
{0, scaleY, shift+0.5*scaleY}
};
iwiWarpAffine.InitAlloc(m_src.m_size, m_dst.m_size, m_src.m_dataType, m_src.m_channels, coeffs, ippWarpForward, inter, ::ipp::IwiWarpAffineParams(0, 0.75, 0), ippBorderRepl);
m_ok = true;
}
virtual void operator() (const Range& range) const
{
CV_INSTRUMENT_REGION_IPP()
if(!m_ok)
return;
try
{
::ipp::IwiRoi roi = ::ipp::IwiRect(0, range.start, m_dst.m_size.width, range.end - range.start);
CV_INSTRUMENT_FUN_IPP(iwiWarpAffine, &m_src, &m_dst, &roi);
}
catch(::ipp::IwException)
{
m_ok = false;
return;
}
}
private:
::ipp::IwiImage &m_src;
::ipp::IwiImage &m_dst;
mutable ::ipp::IwiWarpAffine iwiWarpAffine;
volatile bool &m_ok;
const ipp_resizeAffineParallel& operator= (const ipp_resizeAffineParallel&);
};
#endif
static bool ipp_resize(const uchar * src_data, size_t src_step, int src_width, int src_height,
uchar * dst_data, size_t dst_step, int dst_width, int dst_height, double inv_scale_x, double inv_scale_y,
int depth, int channels, int interpolation)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
int mode = -1;
if (interpolation == INTER_LINEAR && src.rows >= 2 && src.cols >= 2)
mode = ippLinear;
else if (interpolation == INTER_CUBIC && src.rows >= 4 && src.cols >= 4)
mode = ippCubic;
else
IppDataType ippDataType = ippiGetDataType(depth);
IppiInterpolationType ippInter = ippiGetInterpolation(interpolation);
if(ippInter < 0)
return false;
bool ok = true;
Range range(0, src.rows);
IPPresizeInvoker invoker(src, dst, inv_scale_x, inv_scale_y, mode, &ok);
parallel_for_(range, invoker, dst.total()/(double)(1<<16));
if( ok )
return true;
#if IPP_DISABLE_RESIZE_NEAREST
if(ippInter == ippNearest)
return false;
#endif
#if IPP_DISABLE_RESIZE_AREA
if(ippInter == ippSuper)
return false;
#endif
if(ippInter != ippLinear && ippDataType == ipp64f)
return false;
// Accuracy mismatch is 1 but affects detectors greatly
#if IPP_DISABLE_RESIZE_8U
if(ippDataType == ipp8u && ippInter == ippLinear)
return false;
#endif
bool affine = false;
const double IPP_RESIZE_EPS = (depth == CV_64F)?0:1e-10;
double ex = fabs((double)dst_width / src_width - inv_scale_x) / inv_scale_x;
double ey = fabs((double)dst_height / src_height - inv_scale_y) / inv_scale_y;
// Use affine transform resize to allow sub-pixel accuracy
if(ex > IPP_RESIZE_EPS || ey > IPP_RESIZE_EPS)
affine = true;
// Affine doesn't support Lanczos and Super interpolations
if(affine && (ippInter == ippLanczos || ippInter == ippSuper))
return false;
try
{
::ipp::IwiImage iwSrc(::ipp::IwiSize(src_width, src_height), ippDataType, channels, 0, (void*)src_data, src_step);
::ipp::IwiImage iwDst(::ipp::IwiSize(dst_width, dst_height), ippDataType, channels, 0, (void*)dst_data, dst_step);
bool ok;
int threads = ippiSuggestThreadsNum(iwDst, 1+((double)(src_width*src_height)/(dst_width*dst_height)));
Range range(0, dst_height);
ipp_resizeParallel invokerGeneral(iwSrc, iwDst, ok);
ipp_resizeAffineParallel invokerAffine(iwSrc, iwDst, ok);
ParallelLoopBody *pInvoker = NULL;
if(affine)
{
pInvoker = &invokerAffine;
invokerAffine.Init(ippInter, inv_scale_x, inv_scale_y);
}
else
{
pInvoker = &invokerGeneral;
invokerGeneral.Init(ippInter);
}
if(IPP_RESIZE_PARALLEL && threads > 1)
parallel_for_(range, *pInvoker, threads*4);
else
pInvoker->operator()(range);
if(!ok)
return false;
}
catch(::ipp::IwException)
{
return false;
}
return true;
#else
CV_UNUSED(src_data); CV_UNUSED(src_step); CV_UNUSED(src_width); CV_UNUSED(src_height); CV_UNUSED(dst_data); CV_UNUSED(dst_step);
CV_UNUSED(dst_width); CV_UNUSED(dst_height); CV_UNUSED(inv_scale_x); CV_UNUSED(inv_scale_y); CV_UNUSED(depth);
CV_UNUSED(channels); CV_UNUSED(interpolation);
return false;
#endif
}
#endif
@ -3135,6 +3162,13 @@ void resize(int src_type,
CALL_HAL(resize, cv_hal_resize, src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, inv_scale_x, inv_scale_y, interpolation);
int depth = CV_MAT_DEPTH(src_type), cn = CV_MAT_CN(src_type);
Size dsize = Size(saturate_cast<int>(src_width*inv_scale_x),
saturate_cast<int>(src_height*inv_scale_y));
CV_Assert( dsize.area() > 0 );
CV_IPP_RUN_FAST(ipp_resize(src_data, src_step, src_width, src_height, dst_data, dst_step, dsize.width, dsize.height, inv_scale_x, inv_scale_y, depth, cn, interpolation))
static ResizeFunc linear_tab[] =
{
resizeGeneric_<
@ -3239,7 +3273,6 @@ void resize(int src_type,
resizeArea_<double, double>, 0
};
int depth = CV_MAT_DEPTH(src_type), cn = CV_MAT_CN(src_type);
double scale_x = 1./inv_scale_x, scale_y = 1./inv_scale_y;
int iscale_x = saturate_cast<int>(scale_x);
@ -3248,31 +3281,9 @@ void resize(int src_type,
bool is_area_fast = std::abs(scale_x - iscale_x) < DBL_EPSILON &&
std::abs(scale_y - iscale_y) < DBL_EPSILON;
Size dsize = Size(saturate_cast<int>(src_width*inv_scale_x),
saturate_cast<int>(src_height*inv_scale_y));
CV_Assert( dsize.area() > 0 );
Mat src(Size(src_width, src_height), src_type, const_cast<uchar*>(src_data), src_step);
Mat dst(dsize, src_type, dst_data, dst_step);
#ifdef HAVE_IPP
int mode = -1;
if (interpolation == INTER_LINEAR && src_height >= 2 && src_width >= 2)
mode = INTER_LINEAR;
else if (interpolation == INTER_CUBIC && src_height >= 4 && src_width >= 4)
mode = INTER_CUBIC;
const double IPP_RESIZE_EPS = 1e-10;
double ex = fabs((double)dsize.width / src_width - inv_scale_x) / inv_scale_x;
double ey = fabs((double)dsize.height / src_height - inv_scale_y) / inv_scale_y;
#endif
CV_IPP_RUN(IPP_VERSION_X100 >= 710 && ((ex < IPP_RESIZE_EPS && ey < IPP_RESIZE_EPS && depth != CV_64F) || (ex == 0 && ey == 0 && depth == CV_64F)) &&
(interpolation == INTER_LINEAR || interpolation == INTER_CUBIC) &&
!(interpolation == INTER_LINEAR && is_area_fast && iscale_x == 2 && iscale_y == 2 && depth == CV_8U) &&
mode >= 0 && (cn == 1 || cn == 3 || cn == 4) && (depth == CV_16U || depth == CV_16S || depth == CV_32F ||
(depth == CV_64F && mode == INTER_LINEAR)),
ipp_resize_mt(src, dst, inv_scale_x, inv_scale_y, interpolation))
if( interpolation == INTER_NEAREST )
{
resizeNN( src, dst, inv_scale_x, inv_scale_y );
@ -4829,7 +4840,7 @@ static bool openvx_remap(Mat src, Mat dst, Mat map1, Mat map2, int interpolation
}
#endif
#if defined HAVE_IPP && IPP_DISABLE_BLOCK
#if defined HAVE_IPP && !IPP_DISABLE_REMAP
typedef IppStatus (CV_STDCALL * ippiRemap)(const void * pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
const Ipp32f* pxMap, int xMapStep, const Ipp32f* pyMap, int yMapStep,
@ -4861,9 +4872,9 @@ public:
return;
}
if (CV_INSTRUMENT_FUN_PTR_CALL_IPP(ippFunc,(src.ptr(), ippiSize(src.size()), (int)src.step, srcRoiRect,
if (CV_INSTRUMENT_FUN_IPP(ippFunc, src.ptr(), ippiSize(src.size()), (int)src.step, srcRoiRect,
map1.ptr<Ipp32f>(), (int)map1.step, map2.ptr<Ipp32f>(), (int)map2.step,
dstRoi.ptr(), (int)dstRoi.step, dstRoiSize, ippInterpolation)) < 0)
dstRoi.ptr(), (int)dstRoi.step, dstRoiSize, ippInterpolation) < 0)
*ok = false;
else
{
@ -4952,7 +4963,7 @@ void cv::remap( InputArray _src, OutputArray _dst,
int type = src.type(), depth = CV_MAT_DEPTH(type);
#if defined HAVE_IPP && IPP_DISABLE_BLOCK
#if defined HAVE_IPP && !IPP_DISABLE_REMAP
CV_IPP_CHECK()
{
if ((interpolation == INTER_LINEAR || interpolation == INTER_CUBIC || interpolation == INTER_NEAREST) &&
@ -5680,7 +5691,9 @@ private:
};
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_WARPAFFINE
typedef IppStatus (CV_STDCALL* ippiWarpAffineBackFunc)(const void*, IppiSize, int, IppiRect, void *, int, IppiRect, double [2][3], int);
class IPPWarpAffineInvoker :
public ParallelLoopBody
{
@ -5711,7 +5724,7 @@ public:
}
// Aug 2013: problem in IPP 7.1, 8.0 : sometimes function return ippStsCoeffErr
IppStatus status = CV_INSTRUMENT_FUN_PTR_CALL_IPP(func,( src.ptr(), srcsize, (int)src.step[0], srcroi, dst.ptr(),
IppStatus status = CV_INSTRUMENT_FUN_IPP(func,( src.ptr(), srcsize, (int)src.step[0], srcroi, dst.ptr(),
(int)dst.step[0], dstroi, coeffs, mode ));
if( status < 0)
*ok = false;
@ -5988,7 +6001,7 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
M[2] = b1; M[5] = b2;
}
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_WARPAFFINE
CV_IPP_CHECK()
{
int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
@ -6403,7 +6416,9 @@ private:
Scalar borderValue;
};
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_WARPPERSPECTIVE
typedef IppStatus (CV_STDCALL* ippiWarpPerspectiveFunc)(const void*, IppiSize, int, IppiRect, void *, int, IppiRect, double [3][3], int);
class IPPWarpPerspectiveInvoker :
public ParallelLoopBody
{
@ -6434,7 +6449,7 @@ public:
}
}
IppStatus status = CV_INSTRUMENT_FUN_PTR_CALL_IPP(func,(src.ptr(), srcsize, (int)src.step[0], srcroi, dst.ptr(), (int)dst.step[0], dstroi, coeffs, mode));
IppStatus status = CV_INSTRUMENT_FUN_IPP(func,(src.ptr(), srcsize, (int)src.step[0], srcroi, dst.ptr(), (int)dst.step[0], dstroi, coeffs, mode));
if (status != ippStsNoErr)
*ok = false;
else
@ -6507,7 +6522,7 @@ void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
CV_Assert( (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 3 && M0.cols == 3 );
M0.convertTo(matM, matM.type());
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && IPP_DISABLE_BLOCK
#if defined (HAVE_IPP) && IPP_VERSION_X100 >= 810 && !IPP_DISABLE_WARPPERSPECTIVE
CV_IPP_CHECK()
{
int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);

View File

@ -1113,68 +1113,20 @@ static bool halMorph(int op, int src_type, int dst_type,
}
// ===== 2. IPP implementation
#ifdef HAVE_IPP
#if IPP_VERSION_X100 >= 810
template <int cvtype> struct IppMorphTrait {};
#if IPP_VERSION_X100 >= 900
#define DEFINE_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
template <>\
struct IppMorphTrait<cvtype>\
{\
typedef Ipp##ipptype ipp_data_type;\
enum { cn = channels };\
IppDataType getDataType() {return ipp##ipptype;}\
\
IppStatus getMorphSize(IppiSize roiSize, IppiSize maskSize, int* pSpecSize, int* pBufferSize) {return ippiMorphologyBorderGetSize_##flavor(roiSize, maskSize, pSpecSize, pBufferSize);}\
IppStatus morphInit(IppiSize roiSize, const Ipp8u* pMask, IppiSize maskSize, IppiMorphState* pMorphSpec, Ipp8u* pBuffer) {return ippiMorphologyBorderInit_##flavor(roiSize, pMask, maskSize, pMorphSpec, pBuffer);}\
IppStatus filterGetMinSize(IppiSize dstRoiSize, IppiSize maskSize, IppDataType dataType, int numChannels, int* pBufferSize) {return ippiFilterMinBorderGetBufferSize(dstRoiSize, maskSize, dataType, numChannels, pBufferSize);}\
IppStatus filterGetMaxSize(IppiSize dstRoiSize, IppiSize maskSize, IppDataType dataType, int numChannels, int* pBufferSize) {return ippiFilterMaxBorderGetBufferSize(dstRoiSize, maskSize, dataType, numChannels, pBufferSize);}\
IppStatus filterMinBorder(const ipp_data_type* pSrc, int srcStep, ipp_data_type* pDst, int dstStep, IppiSize dstRoiSize, IppiSize maskSize, IppiPoint, Ipp8u* pBuffer) { ipp_data_type zerodef; return CV_INSTRUMENT_FUN_IPP(ippiFilterMinBorder_##flavor, pSrc, srcStep, pDst, dstStep, dstRoiSize, maskSize, ippBorderRepl, zero, pBuffer); }\
IppStatus filterMaxBorder(const ipp_data_type* pSrc, int srcStep, ipp_data_type* pDst, int dstStep, IppiSize dstRoiSize, IppiSize maskSize, IppiPoint, Ipp8u* pBuffer) { ipp_data_type zerodef; return CV_INSTRUMENT_FUN_IPP(ippiFilterMaxBorder_##flavor, pSrc, srcStep, pDst, dstStep, dstRoiSize, maskSize, ippBorderRepl, zero, pBuffer); }\
IppStatus morphDilate(const ipp_data_type* pSrc, int srcStep, ipp_data_type* pDst, int dstStep, IppiSize roiSize, const IppiMorphState* pMorphSpec, Ipp8u* pBuffer) { ipp_data_type zerodef; return CV_INSTRUMENT_FUN_IPP(ippiDilateBorder_##flavor, pSrc, srcStep, pDst, dstStep, roiSize, ippBorderRepl, zero, pMorphSpec, pBuffer); }\
IppStatus morphErode(const ipp_data_type* pSrc, int srcStep, ipp_data_type* pDst, int dstStep, IppiSize roiSize, const IppiMorphState* pMorphSpec, Ipp8u* pBuffer) { ipp_data_type zerodef; return CV_INSTRUMENT_FUN_IPP(ippiErodeBorder_##flavor, pSrc, srcStep, pDst, dstStep, roiSize, ippBorderRepl, zero, pMorphSpec, pBuffer); }\
};
#else
#define DEFINE_TRAIT(cvtype, ipptype, flavor, channels, zerodef)\
template <>\
struct IppMorphTrait<cvtype>\
{\
typedef Ipp##ipptype ipp_data_type;\
enum { cn = channels };\
IppDataType getDataType() {return ipp##ipptype;}\
\
IppStatus getMorphSize(IppiSize roiSize, IppiSize maskSize, int* pSpecSize, int* pBufferSize) {return ippiMorphologyBorderGetSize_##flavor(roiSize.width, maskSize, pSpecSize, pBufferSize);}\
IppStatus morphInit(IppiSize roiSize, const Ipp8u* pMask, IppiSize maskSize, IppiMorphState* pMorphSpec, Ipp8u* pBuffer) {return ippiMorphologyBorderInit_##flavor(roiSize.width, pMask, maskSize, pMorphSpec, pBuffer);}\
IppStatus filterGetMinSize(IppiSize dstRoiSize, IppiSize maskSize, IppDataType, int, int* pBufferSize) {return ippiFilterMinGetBufferSize_##flavor(dstRoiSize.width, maskSize, pBufferSize);}\
IppStatus filterGetMaxSize(IppiSize dstRoiSize, IppiSize maskSize, IppDataType, int, int* pBufferSize) {return ippiFilterMinGetBufferSize_##flavor(dstRoiSize.width, maskSize, pBufferSize);}\
IppStatus filterMinBorder(const ipp_data_type* pSrc, int srcStep, ipp_data_type* pDst, int dstStep, IppiSize dstRoiSize, IppiSize maskSize, IppiPoint anchor, Ipp8u* pBuffer) { return ippiFilterMinBorderReplicate_##flavor(pSrc, srcStep, pDst, dstStep, dstRoiSize, maskSize, anchor, pBuffer); }\
IppStatus filterMaxBorder(const ipp_data_type* pSrc, int srcStep, ipp_data_type* pDst, int dstStep, IppiSize dstRoiSize, IppiSize maskSize, IppiPoint anchor, Ipp8u* pBuffer) { return ippiFilterMaxBorderReplicate_##flavor(pSrc, srcStep, pDst, dstStep, dstRoiSize, maskSize, anchor, pBuffer); }\
IppStatus morphDilate(const ipp_data_type* pSrc, int srcStep, ipp_data_type* pDst, int dstStep, IppiSize roiSize, const IppiMorphState* pMorphSpec, Ipp8u* pBuffer) {return ippiDilateBorder_##flavor(pSrc, srcStep, pDst, dstStep, roiSize, ippBorderRepl, 0, pMorphSpec, pBuffer);}\
IppStatus morphErode(const ipp_data_type* pSrc, int srcStep, ipp_data_type* pDst, int dstStep, IppiSize roiSize, const IppiMorphState* pMorphSpec, Ipp8u* pBuffer) {return ippiErodeBorder_##flavor(pSrc, srcStep, pDst, dstStep, roiSize, ippBorderRepl, 0, pMorphSpec, pBuffer);}\
};
#ifdef HAVE_IPP_IW
static inline IwiMorphologyType ippiGetMorphologyType(int morphOp)
{
return morphOp == MORPH_ERODE ? iwiMorphErode :
morphOp == MORPH_DILATE ? iwiMorphDilate :
morphOp == MORPH_OPEN ? iwiMorphOpen :
morphOp == MORPH_CLOSE ? iwiMorphClose :
morphOp == MORPH_GRADIENT ? iwiMorphGradient :
morphOp == MORPH_TOPHAT ? iwiMorphTophat :
morphOp == MORPH_BLACKHAT ? iwiMorphBlackhat : (IwiMorphologyType)-1;
}
#endif
DEFINE_TRAIT(CV_8UC1, 8u, 8u_C1R, 1, zero = 0)
DEFINE_TRAIT(CV_8UC3, 8u, 8u_C3R, 3, zero[3] = {0})
DEFINE_TRAIT(CV_8UC4, 8u, 8u_C4R, 4, zero[4] = {0})
DEFINE_TRAIT(CV_32FC1, 32f, 32f_C1R, 1, zero = 0)
DEFINE_TRAIT(CV_32FC3, 32f, 32f_C3R, 3, zero[3] = {0})
DEFINE_TRAIT(CV_32FC4, 32f, 32f_C4R, 4, zero[4] = {0})
#undef DEFINE_TRAIT
//--------------------------------------
template <int cvtype>
static bool ippMorph(int op, int src_type, int dst_type,
const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
@ -1185,146 +1137,131 @@ static bool ippMorph(int op, int src_type, int dst_type,
int kernel_width, int kernel_height, int anchor_x, int anchor_y,
int borderType, const double borderValue[4], int iterations, bool isSubmatrix)
{
IppMorphTrait<cvtype> trait;
typedef typename IppMorphTrait<cvtype>::ipp_data_type ipp_data_type;
IppAutoBuffer<IppiMorphState> specBuf;
IppAutoBuffer<Ipp8u> workBuf;
IppiSize kernelSize;
bool rectKernel;
IppiPoint anchor;
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
CV_UNUSED(roi_width); CV_UNUSED(roi_height); CV_UNUSED(roi_x); CV_UNUSED(roi_y);
CV_UNUSED(roi_width2); CV_UNUSED(roi_height2); CV_UNUSED(roi_x2); CV_UNUSED(roi_y2);
CV_UNUSED(dst_type);
// Problem with SSE42 optimizations
#if IPP_DISABLE_PERF_MORPH_SSE42
if(!(ipp::getIppFeatures()&ippCPUID_AVX))
return false;
#endif
anchor = ippiPoint(anchor_x, anchor_y);
::ipp::IwAutoBuffer<Ipp8u> kernelTempBuffer;
::ipp::IwiBorderSize iwBorderSize;
::ipp::IwiBorderType iwBorderType;
::ipp::IwiImage iwMask;
::ipp::IwiImage iwInter;
::ipp::IwiSize initSize(width, height);
::ipp::IwiSize kernelSize(kernel_width, kernel_height);
::ipp::IwiPoint anchor(anchor_x, anchor_y);
IppDataType type = ippiGetDataType(CV_MAT_DEPTH(src_type));
int channels = CV_MAT_CN(src_type);
IwiMorphologyType morphType = ippiGetMorphologyType(op);
Mat kernel(Size(kernel_width, kernel_height), kernel_type, kernel_data, kernel_step);
int depth = CV_MAT_DEPTH(src_type), cn = CV_MAT_CN(src_type);
CV_UNUSED(isSubmatrix);
if( !( depth == CV_8U || depth == CV_32F )
|| !(cn == 1 || cn == 3 || cn == 4)
|| !( borderType == cv::BORDER_REPLICATE
|| (borderType == cv::BORDER_CONSTANT && Vec<double, 4>(borderValue) == morphologyDefaultBorderValue() && kernel.size() == Size(3,3)))
|| !( op == MORPH_DILATE || op == MORPH_ERODE)
|| isSubmatrix
|| src_data == dst_data)
if(morphType < 0)
return false;
// In case BORDER_CONSTANT, IPPMorphReplicate works correct with kernels of size 3*3 only
if( borderType == cv::BORDER_CONSTANT && kernel.data )
{
int x, y;
for( y = 0; y < kernel.rows; y++ )
{
if( kernel.at<uchar>(y, anchor.x) != 0 )
continue;
for( x = 0; x < kernel.cols; x++ )
{
if( kernel.at<uchar>(y,x) != 0 )
return false;
}
}
for( x = 0; x < kernel.cols; x++ )
{
if( kernel.at<uchar>(anchor.y, x) != 0 )
continue;
for( y = 0; y < kernel.rows; y++ )
{
if( kernel.at<uchar>(y,x) != 0 )
return false;
}
}
}
Size ksize = !kernel.empty() ? kernel.size() : Size(3,3);
rectKernel = false;
if( kernel.empty() )
{
ksize = Size(1+iterations*2,1+iterations*2);
anchor = ippiPoint(iterations, iterations);
rectKernel = true;
iterations = 1;
}
else if( iterations >= 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
{
ksize = Size(ksize.width + (iterations-1)*(ksize.width-1),
ksize.height + (iterations-1)*(ksize.height-1)),
anchor = ippiPoint(anchor.x*iterations, anchor.y*iterations);
kernel = Mat();
rectKernel = true;
iterations = 1;
}
// TODO: implement the case of iterations > 1.
if( iterations > 1 )
if(iterations > 1 && morphType != iwiMorphErode && morphType != iwiMorphDilate)
return false;
IppiSize roiSize = {width, height};
kernelSize = ippiSize(ksize);
if(src_type != dst_type)
return false;
IppStatus res;
if (!rectKernel)
try
{
if (((kernel.cols - 1) / 2 != anchor.x) || ((kernel.rows - 1) / 2 != anchor.y))
::ipp::IwiImage iwSrc(initSize, type, channels, ::ipp::IwiBorderSize(roi_x, roi_y, roi_width-roi_x-width, roi_height-roi_y-height), (void*)src_data, src_step);
::ipp::IwiImage iwDst(initSize, type, channels, ::ipp::IwiBorderSize(roi_x2, roi_y2, roi_width2-roi_x2-width, roi_height2-roi_y2-height), (void*)dst_data, dst_step);
::ipp::iwiFilterMorphology_GetBorderSize(morphType, kernelSize, iwBorderSize);
if(morphType != iwiMorphErode && morphType != iwiMorphDilate)
{
iwBorderSize.borderLeft /= 2;
iwBorderSize.borderTop /= 2;
iwBorderSize.borderRight /= 2;
iwBorderSize.borderBottom /= 2;
}
iwBorderType = ippiGetBorder(iwSrc, borderType, iwBorderSize);
if(!iwBorderType.m_borderType || ((iwBorderType.m_borderFlags&ippBorderInMem) && (iwBorderType.m_borderFlags&ippBorderInMem) != ippBorderInMem))
return false;
int specSize = 0, bufferSize = 0;
res = trait.getMorphSize(roiSize, kernelSize, &specSize, &bufferSize);
if (res >= 0)
if(iwBorderType.m_borderType == ippBorderConst)
{
specBuf.Alloc(specSize);
workBuf.Alloc(bufferSize);
res = trait.morphInit(roiSize, kernel.ptr(), kernelSize, specBuf, workBuf);
if (res < 0)
return false;
}
}
else
{
if (((kernelSize.width - 1) / 2 != anchor.x) || ((kernelSize.height - 1) / 2 != anchor.y))
return false;
if (op == MORPH_ERODE)
{
int bufSize = 0;
res = trait.filterGetMinSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize);
if (res >= 0)
workBuf.Alloc(bufSize);
if(Vec<double, 4>(borderValue) == morphologyDefaultBorderValue())
iwBorderType.m_borderType = ippBorderDefault;
else
return false;
iwBorderType.SetValue(borderValue[0], borderValue[1], borderValue[2], borderValue[3]);
}
if(morphType != iwiMorphErode && morphType != iwiMorphDilate)
{
if((iwBorderType.m_borderFlags&ippBorderInMem) == ippBorderInMem)
iwBorderType.m_borderFlags = ippBorderFirstStageInMem;
}
// Test input parameters on dummy structures
{
::ipp::IwiImage testSrc(initSize, type, channels);
::ipp::IwiImage testDst(initSize, type, channels);
::ipp::IwiImage testMask(ippiSize(kernel_width, kernel_height), ipp8u, CV_MAT_CN(kernel_type));
::ipp::iwiFilterMorphology(&testSrc, &testDst, morphType, &testMask, &anchor, iwBorderType);
}
iwMask.Init(ippiSize(kernel_width, kernel_height), ippiGetDataType(CV_MAT_DEPTH(kernel_type)), CV_MAT_CN(kernel_type), 0, kernel_data, kernel_step);
if((int)kernel_step != kernel_width || CV_MAT_DEPTH(kernel_type) != CV_8U)
{
kernelTempBuffer.Alloc(kernel_width*kernel_height);
::ipp::IwiImage iwMaskTmp(ippiSize(kernel_width, kernel_height), ipp8u, 1, 0, kernelTempBuffer, kernel_width);
::ipp::iwiScale(&iwMask, &iwMaskTmp, 1, 0);
iwMask = iwMaskTmp;
}
if(iterations > 1)
{
iwInter.Alloc(initSize, type, channels);
::ipp::IwiImage *pSwap[2] = {&iwInter, &iwDst};
::ipp::IwiBorderType iterBorder = iwBorderType;
iterBorder.m_borderFlags = 0;
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, &iwSrc, &iwInter, morphType, &iwMask, NULL, iwBorderType);
for(int i = 0; i < iterations-1; i++)
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, pSwap[i&0x1], pSwap[(i+1)&0x1], morphType, &iwMask, NULL, iterBorder);
if(iterations&0x1)
CV_INSTRUMENT_FUN_IPP(::ipp::iwiCopyMask, &iwInter, &iwDst);
}
else
{
int bufSize = 0;
res = trait.filterGetMaxSize(roiSize, kernelSize, trait.getDataType(), trait.cn, &bufSize);
if (res >= 0)
workBuf.Alloc(bufSize);
if(src_data == dst_data)
{
iwInter.Alloc(initSize, type, channels);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, &iwSrc, &iwInter, morphType, &iwMask, NULL, iwBorderType);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiCopyMask, &iwInter, &iwDst);
}
else
return false;
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterMorphology, &iwSrc, &iwDst, morphType, &iwMask, NULL, iwBorderType);
}
}
catch(::ipp::IwException ex)
{
return false;
}
if (!rectKernel)
{
if (op == MORPH_ERODE)
res = (trait.morphErode((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, specBuf, workBuf));
else
res = (trait.morphDilate((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, specBuf, workBuf));
}
else
{
if (op == MORPH_ERODE)
res = (trait.filterMinBorder((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, kernelSize, anchor, workBuf));
else
res = (trait.filterMaxBorder((ipp_data_type*)src_data, (int)src_step, (ipp_data_type*)dst_data, (int)dst_step, roiSize, kernelSize, anchor, workBuf));
}
return res >= 0;
}
return true;
#else
CV_UNUSED(op); CV_UNUSED(src_type); CV_UNUSED(dst_type); CV_UNUSED(src_data); CV_UNUSED(src_step); CV_UNUSED(dst_data);
CV_UNUSED(dst_step); CV_UNUSED(width); CV_UNUSED(height); CV_UNUSED(roi_width); CV_UNUSED(roi_height);
CV_UNUSED(roi_x); CV_UNUSED(roi_y); CV_UNUSED(roi_width2); CV_UNUSED(roi_height2); CV_UNUSED(roi_x2); CV_UNUSED(roi_y2);
CV_UNUSED(kernel_type); CV_UNUSED(kernel_data); CV_UNUSED(kernel_step); CV_UNUSED(kernel_width); CV_UNUSED(kernel_height);
CV_UNUSED(anchor_x); CV_UNUSED(anchor_y); CV_UNUSED(borderType); CV_UNUSED(borderValue); CV_UNUSED(iterations);
CV_UNUSED(isSubmatrix);
return false;
#endif
};
#endif // IPP_VERSION_X100 >= 810
#endif // HAVE_IPP
// ===== 3. Fallback implementation
@ -1393,37 +1330,12 @@ void morph(int op, int src_type, int dst_type,
return;
}
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 810
#define ONE_CASE(type) \
case type: \
res = ippMorph<type>(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height, \
roi_width, roi_height, roi_x, roi_y, \
roi_width2, roi_height2, roi_x2, roi_y2, \
kernel_type, kernel_data, kernel_step, \
kernel_width, kernel_height, anchor_x, anchor_y, \
borderType, borderValue, iterations, isSubmatrix); \
break;
CV_IPP_CHECK()
{
bool res = false;
switch (src_type)
{
ONE_CASE(CV_8UC1)
ONE_CASE(CV_8UC3)
ONE_CASE(CV_8UC4)
ONE_CASE(CV_32FC1)
ONE_CASE(CV_32FC3)
ONE_CASE(CV_32FC4)
}
if (res)
return;
}
#undef ONE_CASE
#endif
CV_IPP_RUN_FAST(ippMorph(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height,
roi_width, roi_height, roi_x, roi_y,
roi_width2, roi_height2, roi_x2, roi_y2,
kernel_type, kernel_data, kernel_step,
kernel_width, kernel_height, anchor_x, anchor_y,
borderType, borderValue, iterations, isSubmatrix));
ocvMorph(op, src_type, dst_type, src_data, src_step, dst_data, dst_step, width, height,
roi_width, roi_height, roi_x, roi_y,
@ -1854,6 +1766,8 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
Point anchor, int iterations,
int borderType, const Scalar& borderValue )
{
CV_INSTRUMENT_REGION()
Mat kernel = _kernel.getMat();
Size ksize = !kernel.empty() ? kernel.size() : Size(3,3);
anchor = normalizeAnchor(anchor, ksize);
@ -1996,7 +1910,77 @@ static bool ocl_morphologyEx(InputArray _src, OutputArray _dst, int op,
}
}
#endif
#ifdef HAVE_IPP
#if !IPP_DISABLE_MORPH_ADV
namespace cv {
static bool ipp_morphologyEx(int op, InputArray _src, OutputArray _dst,
InputArray _kernel,
Point anchor, int iterations,
int borderType, const Scalar& borderValue)
{
#if defined HAVE_IPP_IW
Mat kernel = _kernel.getMat();
Size ksize = !kernel.empty() ? kernel.size() : Size(3,3);
anchor = normalizeAnchor(anchor, ksize);
if (iterations == 0 || kernel.rows*kernel.cols == 1)
{
_src.copyTo(_dst);
return true;
}
if (kernel.empty())
{
kernel = getStructuringElement(MORPH_RECT, Size(1+iterations*2,1+iterations*2));
anchor = Point(iterations, iterations);
iterations = 1;
}
else if( iterations > 1 && countNonZero(kernel) == kernel.rows*kernel.cols )
{
anchor = Point(anchor.x*iterations, anchor.y*iterations);
kernel = getStructuringElement(MORPH_RECT,
Size(ksize.width + (iterations-1)*(ksize.width-1),
ksize.height + (iterations-1)*(ksize.height-1)),
anchor);
iterations = 1;
}
Mat src = _src.getMat();
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
Point s_ofs;
Size s_wsz(src.cols, src.rows);
Point d_ofs;
Size d_wsz(dst.cols, dst.rows);
bool isolated = (borderType&BORDER_ISOLATED)?true:false;
borderType = (borderType&~BORDER_ISOLATED);
if(!isolated)
{
src.locateROI(s_wsz, s_ofs);
dst.locateROI(d_wsz, d_ofs);
}
return ippMorph(op, src.type(), dst.type(),
src.data, src.step,
dst.data, dst.step,
src.cols, src.rows,
s_wsz.width, s_wsz.height, s_ofs.x, s_ofs.y,
d_wsz.width, d_wsz.height, d_ofs.x, d_ofs.y,
kernel.type(), kernel.data, kernel.step, kernel.cols, kernel.rows, anchor.x, anchor.y,
borderType, borderValue.val, iterations,
(src.isSubmatrix() && !isolated));
#else
CV_UNUSED(op); CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(_kernel); CV_UNUSED(anchor);
CV_UNUSED(iterations); CV_UNUSED(borderType); CV_UNUSED(borderValue);
return false;
#endif
}
}
#endif
#endif
void cv::morphologyEx( InputArray _src, OutputArray _dst, int op,
@ -2024,7 +2008,11 @@ void cv::morphologyEx( InputArray _src, OutputArray _dst, int op,
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();
Mat k1, k2, e1, e2; //only for hit and miss op
#if !IPP_DISABLE_MORPH_ADV
CV_IPP_RUN_FAST(ipp_morphologyEx(op, src, dst, kernel, anchor, iterations, borderType, borderValue));
#endif
Mat k1, k2, e1, e2; //only for hit and miss op
switch( op )
{

View File

@ -93,6 +93,19 @@ extern const float icv8x32fSqrTab[];
#undef CV_CALC_MAX
#define CV_CALC_MAX(a, b) if((a) < (b)) (a) = (b)
#ifdef HAVE_IPP
static inline IppiInterpolationType ippiGetInterpolation(int inter)
{
inter &= cv::INTER_MAX;
return inter == cv::INTER_NEAREST ? ippNearest :
inter == cv::INTER_LINEAR ? ippLinear :
inter == cv::INTER_CUBIC ? ippCubic :
inter == cv::INTER_LANCZOS4 ? ippLanczos :
inter == cv::INTER_AREA ? ippSuper :
(IppiInterpolationType)-1;
}
#endif
#include "_geom.h"
#include "filterengine.hpp"

View File

@ -2295,101 +2295,54 @@ static bool openvx_gaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
#endif
#ifdef HAVE_IPP
static bool ipp_GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
double sigma1, double sigma2,
int borderType )
static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
double sigma1, double sigma2, int borderType )
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 810
if ((borderType & BORDER_ISOLATED) == 0 && _src.isSubmatrix())
#if IPP_VERSION_X100 <= 201702 && ((defined _MSC_VER && defined _M_IX86) || (defined __GNUC__ && defined __i386__))
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(ksize); CV_UNUSED(sigma1); CV_UNUSED(sigma2); CV_UNUSED(borderType);
return false; // bug on ia32
#else
if(sigma1 != sigma2)
return false;
int type = _src.type();
Size size = _src.size();
if(sigma1 < FLT_EPSILON)
return false;
if( borderType != BORDER_CONSTANT && (borderType & BORDER_ISOLATED) != 0 )
if(ksize.width != ksize.height)
return false;
// Acquire data and begin processing
try
{
if( size.height == 1 )
ksize.height = 1;
if( size.width == 1 )
ksize.width = 1;
Mat src = _src.getMat();
Mat dst = _dst.getMat();
::ipp::IwiImage iwSrc = ippiGetImage(src);
::ipp::IwiImage iwDst = ippiGetImage(dst);
::ipp::IwiBorderSize borderSize(::ipp::IwiSize(ippiSize(ksize)));
::ipp::IwiBorderType ippBorder(ippiGetBorder(iwSrc, borderType, borderSize));
if(!ippBorder.m_borderType)
return false;
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, &iwSrc, &iwDst, ksize.width, (float)sigma1, ippBorder);
}
catch (::ipp::IwException ex)
{
return false;
}
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
if ((depth == CV_8U || depth == CV_16U || depth == CV_16S || depth == CV_32F) && (cn == 1 || cn == 3) &&
sigma1 == sigma2 && ksize.width == ksize.height && sigma1 != 0.0 )
{
IppiBorderType ippBorder = ippiGetBorderType(borderType);
if (ippBorderConst == ippBorder || ippBorderRepl == ippBorder)
{
Mat src = _src.getMat(), dst = _dst.getMat();
IppiSize roiSize = { src.cols, src.rows };
IppDataType dataType = ippiGetDataType(depth);
Ipp32s specSize = 0, bufferSize = 0;
if (ippiFilterGaussianGetBufferSize(roiSize, (Ipp32u)ksize.width, dataType, cn, &specSize, &bufferSize) >= 0)
{
IppAutoBuffer<IppFilterGaussianSpec> spec(specSize);
IppAutoBuffer<Ipp8u> buffer(bufferSize);
if (ippiFilterGaussianInit(roiSize, (Ipp32u)ksize.width, (Ipp32f)sigma1, ippBorder, dataType, cn, spec, buffer) >= 0)
{
#define IPP_FILTER_GAUSS_C1(ippfavor) \
{ \
Ipp##ippfavor borderValues = 0; \
status = CV_INSTRUMENT_FUN_IPP(ippiFilterGaussianBorder_##ippfavor##_C1R, src.ptr<Ipp##ippfavor>(), (int)src.step, \
dst.ptr<Ipp##ippfavor>(), (int)dst.step, roiSize, borderValues, spec, buffer); \
}
#define IPP_FILTER_GAUSS_CN(ippfavor, ippcn) \
{ \
Ipp##ippfavor borderValues[] = { 0, 0, 0 }; \
status = CV_INSTRUMENT_FUN_IPP(ippiFilterGaussianBorder_##ippfavor##_C##ippcn##R, src.ptr<Ipp##ippfavor>(), (int)src.step, \
dst.ptr<Ipp##ippfavor>(), (int)dst.step, roiSize, borderValues, spec, buffer); \
}
IppStatus status = ippStsErr;
#if IPP_VERSION_X100 > 900 // Buffer overflow may happen in IPP 9.0.0 and less
if (type == CV_8UC1)
IPP_FILTER_GAUSS_C1(8u)
else
return true;
#endif
if (type == CV_8UC3)
IPP_FILTER_GAUSS_CN(8u, 3)
else if (type == CV_16UC1)
IPP_FILTER_GAUSS_C1(16u)
else if (type == CV_16UC3)
IPP_FILTER_GAUSS_CN(16u, 3)
else if (type == CV_16SC1)
IPP_FILTER_GAUSS_C1(16s)
else if (type == CV_16SC3)
IPP_FILTER_GAUSS_CN(16s, 3)
else if (type == CV_32FC3)
IPP_FILTER_GAUSS_CN(32f, 3)
else if (type == CV_32FC1)
IPP_FILTER_GAUSS_C1(32f)
if(status >= 0)
return true;
#undef IPP_FILTER_GAUSS_C1
#undef IPP_FILTER_GAUSS_CN
}
}
}
}
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(ksize); CV_UNUSED(sigma1); CV_UNUSED(sigma2); CV_UNUSED(borderType);
#endif
return false;
#endif
}
#endif
}
void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
double sigma1, double sigma2,
int borderType )
@ -2423,17 +2376,18 @@ void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
if(sigma1 == 0 && sigma2 == 0 && tegra::useTegra() && tegra::gaussian(src, dst, ksize, borderType))
return;
#endif
bool useOpenCL = (_dst.isUMat() && _src.dims() <= 2 &&
((ksize.width == 3 && ksize.height == 3) ||
(ksize.width == 5 && ksize.height == 5)) &&
_src.rows() > ksize.height && _src.cols() > ksize.width);
(void)useOpenCL;
CV_IPP_RUN(!(ocl::useOpenCL() && _dst.isUMat()), ipp_GaussianBlur( _src, _dst, ksize, sigma1, sigma2, borderType));
CV_IPP_RUN(!useOpenCL, ipp_GaussianBlur( _src, _dst, ksize, sigma1, sigma2, borderType));
Mat kx, ky;
createGaussianKernels(kx, ky, type, ksize, sigma1, sigma2);
CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2 &&
((ksize.width == 3 && ksize.height == 3) ||
(ksize.width == 5 && ksize.height == 5)) &&
(size_t)_src.rows() > ky.total() && (size_t)_src.cols() > kx.total(),
ocl_GaussianBlur_8UC1(_src, _dst, ksize, CV_MAT_DEPTH(type), kx, ky, borderType));
CV_OCL_RUN(useOpenCL, ocl_GaussianBlur_8UC1(_src, _dst, ksize, CV_MAT_DEPTH(type), kx, ky, borderType));
sepFilter2D(_src, _dst, CV_MAT_DEPTH(type), kx, ky, Point(-1,-1), 0, borderType );
}
@ -3430,60 +3384,69 @@ namespace cv
#ifdef HAVE_IPP
namespace cv
{
static bool ipp_medianFilter( InputArray _src0, OutputArray _dst, int ksize )
static bool ipp_medianFilter(Mat &src0, Mat &dst, int ksize)
{
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 810
Mat src0 = _src0.getMat();
_dst.create( src0.size(), src0.type() );
Mat dst = _dst.getMat();
#define IPP_FILTER_MEDIAN_BORDER(ippType, ippDataType, flavor) \
do \
{ \
if (ippiFilterMedianBorderGetBufferSize(dstRoiSize, maskSize, \
ippDataType, CV_MAT_CN(type), &bufSize) >= 0) \
{ \
Ipp8u * buffer = ippsMalloc_8u(bufSize); \
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_##flavor, src.ptr<ippType>(), (int)src.step, \
dst.ptr<ippType>(), (int)dst.step, dstRoiSize, maskSize, \
ippBorderRepl, (ippType)0, buffer); \
ippsFree(buffer); \
if (status >= 0) \
{ \
CV_IMPL_ADD(CV_IMPL_IPP); \
return true; \
} \
} \
} \
while ((void)0, 0)
if( ksize <= 5 )
{
Ipp32s bufSize;
IppiSize dstRoiSize = ippiSize(dst.cols, dst.rows), maskSize = ippiSize(ksize, ksize);
int bufSize;
IppiSize dstRoiSize = ippiSize(dst.cols, dst.rows), maskSize = ippiSize(ksize, ksize);
IppDataType ippType = ippiGetDataType(src0.type());
int channels = src0.channels();
IppAutoBuffer<Ipp8u> buffer;
if(src0.isSubmatrix())
return false;
Mat src;
if( dst.data != src0.data )
if(dst.data != src0.data)
src = src0;
else
src0.copyTo(src);
int type = src0.type();
if (type == CV_8UC1)
IPP_FILTER_MEDIAN_BORDER(Ipp8u, ipp8u, 8u_C1R);
else if (type == CV_16UC1)
IPP_FILTER_MEDIAN_BORDER(Ipp16u, ipp16u, 16u_C1R);
else if (type == CV_16SC1)
IPP_FILTER_MEDIAN_BORDER(Ipp16s, ipp16s, 16s_C1R);
else if (type == CV_32FC1)
IPP_FILTER_MEDIAN_BORDER(Ipp32f, ipp32f, 32f_C1R);
if(ippiFilterMedianBorderGetBufferSize(dstRoiSize, maskSize, ippType, channels, &bufSize) < 0)
return false;
buffer.allocate(bufSize);
switch(ippType)
{
case ipp8u:
if(channels == 1)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_8u_C1R, src.ptr<Ipp8u>(), (int)src.step, dst.ptr<Ipp8u>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else if(channels == 3)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_8u_C3R, src.ptr<Ipp8u>(), (int)src.step, dst.ptr<Ipp8u>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else if(channels == 4)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_8u_C4R, src.ptr<Ipp8u>(), (int)src.step, dst.ptr<Ipp8u>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else
return false;
case ipp16u:
if(channels == 1)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_16u_C1R, src.ptr<Ipp16u>(), (int)src.step, dst.ptr<Ipp16u>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else if(channels == 3)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_16u_C3R, src.ptr<Ipp16u>(), (int)src.step, dst.ptr<Ipp16u>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else if(channels == 4)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_16u_C4R, src.ptr<Ipp16u>(), (int)src.step, dst.ptr<Ipp16u>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else
return false;
case ipp16s:
if(channels == 1)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_16s_C1R, src.ptr<Ipp16s>(), (int)src.step, dst.ptr<Ipp16s>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else if(channels == 3)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_16s_C3R, src.ptr<Ipp16s>(), (int)src.step, dst.ptr<Ipp16s>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else if(channels == 4)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_16s_C4R, src.ptr<Ipp16s>(), (int)src.step, dst.ptr<Ipp16s>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else
return false;
case ipp32f:
if(channels == 1)
return CV_INSTRUMENT_FUN_IPP(ippiFilterMedianBorder_32f_C1R, src.ptr<Ipp32f>(), (int)src.step, dst.ptr<Ipp32f>(), (int)dst.step, dstRoiSize, maskSize, ippBorderRepl, 0, buffer) >= 0;
else
return false;
default:
return false;
}
}
#undef IPP_FILTER_MEDIAN_BORDER
#else
CV_UNUSED(_src0); CV_UNUSED(_dst); CV_UNUSED(ksize);
#endif
return false;
}
}
#endif
@ -3510,7 +3473,7 @@ void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize )
CV_OVX_RUN(true,
openvx_medianFilter(_src0, _dst, ksize))
CV_IPP_RUN(IPP_VERSION_X100 >= 810 && ksize <= 5, ipp_medianFilter(_src0,_dst, ksize));
CV_IPP_RUN_FAST(ipp_medianFilter(src0, dst, ksize));
#ifdef HAVE_TEGRA_OPTIMIZATION
if (tegra::useTegra() && tegra::medianBlur(src0, dst, ksize))

View File

@ -560,82 +560,6 @@ static bool ocl_matchTemplate( InputArray _img, InputArray _templ, OutputArray _
#endif
#if defined HAVE_IPP
typedef IppStatus (CV_STDCALL * ippimatchTemplate)(const void*, int, IppiSize, const void*, int, IppiSize, Ipp32f* , int , IppEnum , Ipp8u*);
static bool ipp_crossCorr(const Mat& src, const Mat& tpl, Mat& dst)
{
CV_INSTRUMENT_REGION_IPP()
IppStatus status;
IppiSize srcRoiSize = {src.cols,src.rows};
IppiSize tplRoiSize = {tpl.cols,tpl.rows};
Ipp8u *pBuffer;
int bufSize=0;
int depth = src.depth();
ippimatchTemplate ippiCrossCorrNorm =
depth==CV_8U ? (ippimatchTemplate)ippiCrossCorrNorm_8u32f_C1R:
depth==CV_32F? (ippimatchTemplate)ippiCrossCorrNorm_32f_C1R: 0;
if (ippiCrossCorrNorm==0)
return false;
IppEnum funCfg = (IppEnum)(ippAlgAuto | ippiNormNone | ippiROIValid);
status = ippiCrossCorrNormGetBufferSize(srcRoiSize, tplRoiSize, funCfg, &bufSize);
if ( status < 0 )
return false;
pBuffer = ippsMalloc_8u( bufSize );
status = CV_INSTRUMENT_FUN_IPP(ippiCrossCorrNorm, src.ptr(), (int)src.step, srcRoiSize, tpl.ptr(), (int)tpl.step, tplRoiSize, dst.ptr<Ipp32f>(), (int)dst.step, funCfg, pBuffer);
ippsFree( pBuffer );
return status >= 0;
}
static bool ipp_sqrDistance(const Mat& src, const Mat& tpl, Mat& dst)
{
CV_INSTRUMENT_REGION_IPP()
IppStatus status;
IppiSize srcRoiSize = {src.cols,src.rows};
IppiSize tplRoiSize = {tpl.cols,tpl.rows};
Ipp8u *pBuffer;
int bufSize=0;
int depth = src.depth();
ippimatchTemplate ippiSqrDistanceNorm =
depth==CV_8U ? (ippimatchTemplate)ippiSqrDistanceNorm_8u32f_C1R:
depth==CV_32F? (ippimatchTemplate)ippiSqrDistanceNorm_32f_C1R: 0;
if (ippiSqrDistanceNorm==0)
return false;
IppEnum funCfg = (IppEnum)(ippAlgAuto | ippiNormNone | ippiROIValid);
status = ippiSqrDistanceNormGetBufferSize(srcRoiSize, tplRoiSize, funCfg, &bufSize);
if ( status < 0 )
return false;
pBuffer = ippsMalloc_8u( bufSize );
status = CV_INSTRUMENT_FUN_IPP(ippiSqrDistanceNorm, src.ptr(), (int)src.step, srcRoiSize, tpl.ptr(), (int)tpl.step, tplRoiSize, dst.ptr<Ipp32f>(), (int)dst.step, funCfg, pBuffer);
ippsFree( pBuffer );
return status >= 0;
}
#endif
#include "opencv2/core/hal/hal.hpp"
void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
@ -915,11 +839,7 @@ static void matchTemplateMask( InputArray _img, InputArray _templ, OutputArray _
else
CV_Error(Error::StsNotImplemented, "");
}
}
namespace cv
{
static void common_matchTemplate( Mat& img, Mat& templ, Mat& result, int method, int cn )
{
if( method == CV_TM_CCORR )
@ -1043,26 +963,117 @@ static void common_matchTemplate( Mat& img, Mat& templ, Mat& result, int method,
#if defined HAVE_IPP
namespace cv
{
static bool ipp_matchTemplate( Mat& img, Mat& templ, Mat& result, int method, int cn )
typedef IppStatus (CV_STDCALL * ippimatchTemplate)(const void*, int, IppiSize, const void*, int, IppiSize, Ipp32f* , int , IppEnum , Ipp8u*);
static bool ipp_crossCorr(const Mat& src, const Mat& tpl, Mat& dst, bool normed)
{
CV_INSTRUMENT_REGION_IPP()
bool useIppMT = (templ.rows < img.rows/2 && templ.cols < img.cols/2);
IppStatus status;
if(cn == 1 && useIppMT)
IppiSize srcRoiSize = {src.cols,src.rows};
IppiSize tplRoiSize = {tpl.cols,tpl.rows};
IppAutoBuffer<Ipp8u> buffer;
int bufSize=0;
int depth = src.depth();
ippimatchTemplate ippiCrossCorrNorm =
depth==CV_8U ? (ippimatchTemplate)ippiCrossCorrNorm_8u32f_C1R:
depth==CV_32F? (ippimatchTemplate)ippiCrossCorrNorm_32f_C1R: 0;
if (ippiCrossCorrNorm==0)
return false;
IppEnum funCfg = (IppEnum)(ippAlgAuto | ippiROIValid);
if(normed)
funCfg |= ippiNorm;
else
funCfg |= ippiNormNone;
status = ippiCrossCorrNormGetBufferSize(srcRoiSize, tplRoiSize, funCfg, &bufSize);
if ( status < 0 )
return false;
buffer.allocate( bufSize );
status = CV_INSTRUMENT_FUN_IPP(ippiCrossCorrNorm, src.ptr(), (int)src.step, srcRoiSize, tpl.ptr(), (int)tpl.step, tplRoiSize, dst.ptr<Ipp32f>(), (int)dst.step, funCfg, buffer);
return status >= 0;
}
static bool ipp_sqrDistance(const Mat& src, const Mat& tpl, Mat& dst)
{
CV_INSTRUMENT_REGION_IPP()
IppStatus status;
IppiSize srcRoiSize = {src.cols,src.rows};
IppiSize tplRoiSize = {tpl.cols,tpl.rows};
IppAutoBuffer<Ipp8u> buffer;
int bufSize=0;
int depth = src.depth();
ippimatchTemplate ippiSqrDistanceNorm =
depth==CV_8U ? (ippimatchTemplate)ippiSqrDistanceNorm_8u32f_C1R:
depth==CV_32F? (ippimatchTemplate)ippiSqrDistanceNorm_32f_C1R: 0;
if (ippiSqrDistanceNorm==0)
return false;
IppEnum funCfg = (IppEnum)(ippAlgAuto | ippiROIValid | ippiNormNone);
status = ippiSqrDistanceNormGetBufferSize(srcRoiSize, tplRoiSize, funCfg, &bufSize);
if ( status < 0 )
return false;
buffer.allocate( bufSize );
status = CV_INSTRUMENT_FUN_IPP(ippiSqrDistanceNorm, src.ptr(), (int)src.step, srcRoiSize, tpl.ptr(), (int)tpl.step, tplRoiSize, dst.ptr<Ipp32f>(), (int)dst.step, funCfg, buffer);
return status >= 0;
}
static bool ipp_matchTemplate( Mat& img, Mat& templ, Mat& result, int method)
{
CV_INSTRUMENT_REGION_IPP()
if(img.channels() != 1)
return false;
// These functions are not efficient if template size is comparable with image size
if(templ.size().area()*4 > img.size().area())
return false;
if(method == CV_TM_SQDIFF)
{
if(method == CV_TM_SQDIFF)
if(ipp_sqrDistance(img, templ, result))
return true;
}
else if(method == CV_TM_SQDIFF_NORMED)
{
if(ipp_crossCorr(img, templ, result, false))
{
if (ipp_sqrDistance(img, templ, result))
return true;
common_matchTemplate(img, templ, result, CV_TM_SQDIFF_NORMED, 1);
return true;
}
else
}
else if(method == CV_TM_CCORR)
{
if(ipp_crossCorr(img, templ, result, false))
return true;
}
else if(method == CV_TM_CCORR_NORMED)
{
if(ipp_crossCorr(img, templ, result, true))
return true;
}
else if(method == CV_TM_CCOEFF || method == CV_TM_CCOEFF_NORMED)
{
if(ipp_crossCorr(img, templ, result, false))
{
if(ipp_crossCorr(img, templ, result))
{
common_matchTemplate(img, templ, result, method, cn);
return true;
}
common_matchTemplate(img, templ, result, method, 1);
return true;
}
}
@ -1109,7 +1120,7 @@ void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result,
return;
#endif
CV_IPP_RUN(true, ipp_matchTemplate(img, templ, result, method, cn))
CV_IPP_RUN_FAST(ipp_matchTemplate(img, templ, result, method))
crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0);

View File

@ -715,7 +715,7 @@ void CV_SmoothBaseTest::get_test_array_types_and_sizes( int test_case_idx,
double CV_SmoothBaseTest::get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ )
{
int depth = test_mat[INPUT][0].depth();
return depth <= CV_8S ? 1 : 1e-5;
return depth < CV_32F ? 1 : 1e-5;
}