mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Merge pull request #26880 from asmorkalov:as/ipp_hal
Initial version of IPP-based HAL for x86 and x86_64 platforms #26880 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
parent
8566930922
commit
01ef38dcad
34
3rdparty/ipphal/CMakeLists.txt
vendored
Normal file
34
3rdparty/ipphal/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
project(ipphal)
|
||||
|
||||
set(IPP_HAL_VERSION 0.0.1 CACHE INTERNAL "")
|
||||
set(IPP_HAL_LIBRARIES "ipphal" CACHE INTERNAL "")
|
||||
set(IPP_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" CACHE INTERNAL "")
|
||||
set(IPP_HAL_HEADERS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/ipp_hal_core.hpp"
|
||||
CACHE INTERNAL "")
|
||||
|
||||
add_library(ipphal STATIC "${CMAKE_CURRENT_SOURCE_DIR}/src/mean_ipp.cpp")
|
||||
|
||||
if(HAVE_IPP_ICV)
|
||||
target_compile_definitions(ipphal PRIVATE HAVE_IPP_ICV)
|
||||
endif()
|
||||
|
||||
target_include_directories(ipphal PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
target_include_directories(ipphal PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
${CMAKE_SOURCE_DIR}/modules/core/include
|
||||
${IPP_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(ipphal PUBLIC ${IPP_IW_LIBRARY} ${IPP_LIBRARIES})
|
||||
|
||||
set_target_properties(ipphal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
ocv_install_target(ipphal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(ipphal PROPERTIES FOLDER "3rdparty")
|
||||
endif()
|
15
3rdparty/ipphal/include/ipp_hal_core.hpp
vendored
Normal file
15
3rdparty/ipphal/include/ipp_hal_core.hpp
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef __IPP_HAL_CORE_HPP__
|
||||
#define __IPP_HAL_CORE_HPP__
|
||||
|
||||
#include <opencv2/core/base.hpp>
|
||||
#include "ipp_utils.hpp"
|
||||
|
||||
#if (IPP_VERSION_X100 >= 700)
|
||||
int ipp_hal_meanStdDev(const uchar* src_data, size_t src_step, int width, int height, int src_type,
|
||||
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
|
||||
|
||||
#undef cv_hal_meanStdDev
|
||||
#define cv_hal_meanStdDev ipp_hal_meanStdDev
|
||||
#endif
|
||||
|
||||
#endif
|
24
3rdparty/ipphal/include/ipp_utils.hpp
vendored
Normal file
24
3rdparty/ipphal/include/ipp_utils.hpp
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef __IPP_HAL_UTILS_HPP__
|
||||
#define __IPP_HAL_UTILS_HPP__
|
||||
|
||||
#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)
|
||||
|
||||
#ifdef HAVE_IPP_ICV
|
||||
# define ICV_BASE
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
# include "ippicv.h"
|
||||
#else
|
||||
# include "ipp.h"
|
||||
#endif
|
||||
#else
|
||||
# include "ipp.h"
|
||||
#endif
|
||||
|
||||
#define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__))
|
||||
|
||||
#endif
|
206
3rdparty/ipphal/src/mean_ipp.cpp
vendored
Normal file
206
3rdparty/ipphal/src/mean_ipp.cpp
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
#include "ipp_hal_core.hpp"
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/core/base.hpp>
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
|
||||
static int ipp_mean(const uchar* src_data, size_t src_step, int width, int height,
|
||||
int src_type, double* mean_val, uchar* mask, size_t mask_step)
|
||||
{
|
||||
int cn = CV_MAT_CN(src_type);
|
||||
if (cn > 4)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if((src_step == 1 || src_step == static_cast<size_t>(width)) && (mask_step == 1 || mask_step == static_cast<size_t>(width)))
|
||||
{
|
||||
IppiSize sz = { width, height };
|
||||
if( mask )
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *);
|
||||
ippiMaskMeanFuncC1 ippiMean_C1MR =
|
||||
src_type == CV_8UC1 ? (ippiMaskMeanFuncC1)ippiMean_8u_C1MR :
|
||||
src_type == CV_16UC1 ? (ippiMaskMeanFuncC1)ippiMean_16u_C1MR :
|
||||
src_type == CV_32FC1 ? (ippiMaskMeanFuncC1)ippiMean_32f_C1MR :
|
||||
0;
|
||||
if( ippiMean_C1MR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_C1MR, src_data, (int)src_step, mask, (int)mask_step, sz, mean_val) >= 0 )
|
||||
{
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *);
|
||||
ippiMaskMeanFuncC3 ippiMean_C3MR =
|
||||
src_type == CV_8UC3 ? (ippiMaskMeanFuncC3)ippiMean_8u_C3CMR :
|
||||
src_type == CV_16UC3 ? (ippiMaskMeanFuncC3)ippiMean_16u_C3CMR :
|
||||
src_type == CV_32FC3 ? (ippiMaskMeanFuncC3)ippiMean_32f_C3CMR :
|
||||
0;
|
||||
if( ippiMean_C3MR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 1, &mean_val[0]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 2, &mean_val[1]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src_data, (int)src_step, mask, (int)mask_step, sz, 3, &mean_val[2]) >= 0 )
|
||||
{
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm);
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanFuncNoHint)(const void*, int, IppiSize, double *);
|
||||
ippiMeanFuncHint ippiMeanHint =
|
||||
src_type == CV_32FC1 ? (ippiMeanFuncHint)ippiMean_32f_C1R :
|
||||
src_type == CV_32FC3 ? (ippiMeanFuncHint)ippiMean_32f_C3R :
|
||||
src_type == CV_32FC4 ? (ippiMeanFuncHint)ippiMean_32f_C4R :
|
||||
0;
|
||||
ippiMeanFuncNoHint ippiMean =
|
||||
src_type == CV_8UC1 ? (ippiMeanFuncNoHint)ippiMean_8u_C1R :
|
||||
src_type == CV_8UC3 ? (ippiMeanFuncNoHint)ippiMean_8u_C3R :
|
||||
src_type == CV_8UC4 ? (ippiMeanFuncNoHint)ippiMean_8u_C4R :
|
||||
src_type == CV_16UC1 ? (ippiMeanFuncNoHint)ippiMean_16u_C1R :
|
||||
src_type == CV_16UC3 ? (ippiMeanFuncNoHint)ippiMean_16u_C3R :
|
||||
src_type == CV_16UC4 ? (ippiMeanFuncNoHint)ippiMean_16u_C4R :
|
||||
src_type == CV_16SC1 ? (ippiMeanFuncNoHint)ippiMean_16s_C1R :
|
||||
src_type == CV_16SC3 ? (ippiMeanFuncNoHint)ippiMean_16s_C3R :
|
||||
src_type == CV_16SC4 ? (ippiMeanFuncNoHint)ippiMean_16s_C4R :
|
||||
0;
|
||||
|
||||
// Make sure only zero or one version of the function pointer is valid
|
||||
CV_Assert(!ippiMeanHint || !ippiMean);
|
||||
if( ippiMeanHint || ippiMean )
|
||||
{
|
||||
IppStatus status = ippiMeanHint ? CV_INSTRUMENT_FUN_IPP(ippiMeanHint, src_data, (int)src_step, sz, mean_val, ippAlgHintAccurate) :
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean, src_data, (int)src_step, sz, mean_val);
|
||||
if( status >= 0 )
|
||||
{
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int ipp_meanStdDev(const uchar* src_data, size_t src_step, int width, int height,
|
||||
int src_type, double* mean_val, double* stddev_val, uchar* mask, size_t mask_step)
|
||||
{
|
||||
int cn = CV_MAT_CN(src_type);
|
||||
|
||||
if((src_step == 1 || src_step == static_cast<size_t>(width)) && (mask_step == 1 || mask_step == static_cast<size_t>(width)))
|
||||
{
|
||||
Ipp64f mean_temp[3];
|
||||
Ipp64f stddev_temp[3];
|
||||
Ipp64f *pmean = &mean_temp[0];
|
||||
Ipp64f *pstddev = &stddev_temp[0];
|
||||
int dcn_mean = -1;
|
||||
if( mean_val )
|
||||
{
|
||||
dcn_mean = cn;
|
||||
pmean = mean_val;
|
||||
}
|
||||
int dcn_stddev = -1;
|
||||
if( stddev_val )
|
||||
{
|
||||
dcn_stddev = cn;
|
||||
pstddev = stddev_val;
|
||||
}
|
||||
|
||||
for( int c = cn; c < dcn_mean; c++ )
|
||||
pmean[c] = 0;
|
||||
for( int c = cn; c < dcn_stddev; c++ )
|
||||
pstddev[c] = 0;
|
||||
|
||||
IppiSize sz = { width, height };
|
||||
if( !mask )
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *, Ipp64f *);
|
||||
ippiMaskMeanStdDevFuncC1 ippiMean_StdDev_C1MR =
|
||||
src_type == CV_8UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_8u_C1MR :
|
||||
src_type == CV_16UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_16u_C1MR :
|
||||
src_type == CV_32FC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_32f_C1MR :
|
||||
nullptr;
|
||||
if( ippiMean_StdDev_C1MR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1MR, src_data, (int)src_step, mask, (int)mask_step, sz, pmean, pstddev) >= 0 )
|
||||
{
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
|
||||
ippiMaskMeanStdDevFuncC3 ippiMean_StdDev_C3CMR =
|
||||
src_type == CV_8UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CMR :
|
||||
src_type == CV_16UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CMR :
|
||||
src_type == CV_32FC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CMR :
|
||||
nullptr;
|
||||
if( ippiMean_StdDev_C3CMR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src_data, (int)src_step, mask, (int)mask_step, sz, 3, &pmean[2], &pstddev[2]) >= 0 )
|
||||
{
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC1)(const void *, int, IppiSize, Ipp64f *, Ipp64f *);
|
||||
ippiMeanStdDevFuncC1 ippiMean_StdDev_C1R =
|
||||
src_type == CV_8UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_8u_C1R :
|
||||
src_type == CV_16UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_16u_C1R :
|
||||
#if (IPP_VERSION_X100 >= 810)
|
||||
src_type == CV_32FC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_32f_C1R ://Aug 2013: bug in IPP 7.1, 8.0
|
||||
#endif
|
||||
nullptr;
|
||||
if( ippiMean_StdDev_C1R )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1R, src_data, (int)src_step, sz, pmean, pstddev) >= 0 )
|
||||
{
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC3)(const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
|
||||
ippiMeanStdDevFuncC3 ippiMean_StdDev_C3CR =
|
||||
src_type == CV_8UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CR :
|
||||
src_type == CV_16UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CR :
|
||||
src_type == CV_32FC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CR :
|
||||
nullptr;
|
||||
if( ippiMean_StdDev_C3CR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src_data, (int)src_step, sz, 3, &pmean[2], &pstddev[2]) >= 0 )
|
||||
{
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int ipp_hal_meanStdDev(const uchar* src_data, size_t src_step, int width, int height, int src_type,
|
||||
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step)
|
||||
{
|
||||
if (stddev_val)
|
||||
{
|
||||
return ipp_meanStdDev(src_data, src_step, width, height, src_type, mean_val, stddev_val, mask, mask_step);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ipp_mean(src_data, src_step, width, height, src_type, mean_val, mask, mask_step);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // IPP_VERSION_X100 >= 700
|
@ -952,7 +952,15 @@ if(NOT DEFINED OpenCV_HAL)
|
||||
set(OpenCV_HAL "OpenCV_HAL")
|
||||
endif()
|
||||
|
||||
if(HAVE_IPP)
|
||||
ocv_debug_message(STATUS "Enable IPP acceleration")
|
||||
if(NOT ";${OpenCV_HAL};" MATCHES ";ipp;")
|
||||
set(OpenCV_HAL "ipp;${OpenCV_HAL}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_OPENVX)
|
||||
ocv_debug_message(STATUS "Enable OpenVX acceleration")
|
||||
if(NOT ";${OpenCV_HAL};" MATCHES ";openvx;")
|
||||
set(OpenCV_HAL "openvx;${OpenCV_HAL}")
|
||||
endif()
|
||||
@ -1030,6 +1038,10 @@ foreach(hal ${OpenCV_HAL})
|
||||
else()
|
||||
message(STATUS "HAL RVV: RVV is not available, disabling halrvv...")
|
||||
endif()
|
||||
elseif(hal STREQUAL "ipp")
|
||||
add_subdirectory(3rdparty/ipphal)
|
||||
ocv_hal_register(IPP_HAL_LIBRARIES IPP_HAL_HEADERS IPP_HAL_INCLUDE_DIRS)
|
||||
list(APPEND OpenCV_USED_HAL "ipp (ver ${IPP_HAL_VERSION})")
|
||||
elseif(hal STREQUAL "openvx")
|
||||
add_subdirectory(3rdparty/openvx)
|
||||
ocv_hal_register(OPENVX_HAL_LIBRARIES OPENVX_HAL_HEADERS OPENVX_HAL_INCLUDE_DIRS)
|
||||
|
@ -28,99 +28,6 @@
|
||||
|
||||
namespace cv {
|
||||
|
||||
#if defined HAVE_IPP
|
||||
static bool ipp_mean( Mat &src, Mat &mask, Scalar &ret )
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
size_t total_size = src.total();
|
||||
int cn = src.channels();
|
||||
if (cn > 4)
|
||||
return false;
|
||||
int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0;
|
||||
if( src.dims == 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) )
|
||||
{
|
||||
IppiSize sz = { cols, rows };
|
||||
int type = src.type();
|
||||
if( !mask.empty() )
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *);
|
||||
ippiMaskMeanFuncC1 ippiMean_C1MR =
|
||||
type == CV_8UC1 ? (ippiMaskMeanFuncC1)ippiMean_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskMeanFuncC1)ippiMean_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskMeanFuncC1)ippiMean_32f_C1MR :
|
||||
0;
|
||||
if( ippiMean_C1MR )
|
||||
{
|
||||
Ipp64f res;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_C1MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &res) >= 0 )
|
||||
{
|
||||
ret = Scalar(res);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *);
|
||||
ippiMaskMeanFuncC3 ippiMean_C3MR =
|
||||
type == CV_8UC3 ? (ippiMaskMeanFuncC3)ippiMean_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskMeanFuncC3)ippiMean_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskMeanFuncC3)ippiMean_32f_C3CMR :
|
||||
0;
|
||||
if( ippiMean_C3MR )
|
||||
{
|
||||
Ipp64f res1, res2, res3;
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 1, &res1) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 2, &res2) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_C3MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 3, &res3) >= 0 )
|
||||
{
|
||||
ret = Scalar(res1, res2, res3);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm);
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanFuncNoHint)(const void*, int, IppiSize, double *);
|
||||
ippiMeanFuncHint ippiMeanHint =
|
||||
type == CV_32FC1 ? (ippiMeanFuncHint)ippiMean_32f_C1R :
|
||||
type == CV_32FC3 ? (ippiMeanFuncHint)ippiMean_32f_C3R :
|
||||
type == CV_32FC4 ? (ippiMeanFuncHint)ippiMean_32f_C4R :
|
||||
0;
|
||||
ippiMeanFuncNoHint ippiMean =
|
||||
type == CV_8UC1 ? (ippiMeanFuncNoHint)ippiMean_8u_C1R :
|
||||
type == CV_8UC3 ? (ippiMeanFuncNoHint)ippiMean_8u_C3R :
|
||||
type == CV_8UC4 ? (ippiMeanFuncNoHint)ippiMean_8u_C4R :
|
||||
type == CV_16UC1 ? (ippiMeanFuncNoHint)ippiMean_16u_C1R :
|
||||
type == CV_16UC3 ? (ippiMeanFuncNoHint)ippiMean_16u_C3R :
|
||||
type == CV_16UC4 ? (ippiMeanFuncNoHint)ippiMean_16u_C4R :
|
||||
type == CV_16SC1 ? (ippiMeanFuncNoHint)ippiMean_16s_C1R :
|
||||
type == CV_16SC3 ? (ippiMeanFuncNoHint)ippiMean_16s_C3R :
|
||||
type == CV_16SC4 ? (ippiMeanFuncNoHint)ippiMean_16s_C4R :
|
||||
0;
|
||||
// Make sure only zero or one version of the function pointer is valid
|
||||
CV_Assert(!ippiMeanHint || !ippiMean);
|
||||
if( ippiMeanHint || ippiMean )
|
||||
{
|
||||
Ipp64f res[4];
|
||||
IppStatus status = ippiMeanHint ? CV_INSTRUMENT_FUN_IPP(ippiMeanHint, src.ptr(), (int)src.step[0], sz, res, ippAlgHintAccurate) :
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean, src.ptr(), (int)src.step[0], sz, res);
|
||||
if( status >= 0 )
|
||||
{
|
||||
for( int i = 0; i < cn; i++ )
|
||||
ret[i] = res[i];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
Scalar mean(InputArray _src, InputArray _mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@ -327,143 +234,6 @@ static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_meanStdDev(Mat& src, OutputArray _mean, OutputArray _sdv, Mat& mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
int cn = src.channels();
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// IPP_DISABLE: C3C functions can read outside of allocated memory
|
||||
if (cn > 1)
|
||||
return false;
|
||||
#endif
|
||||
#if IPP_VERSION_X100 >= 201900 && IPP_VERSION_X100 < 201901
|
||||
// IPP_DISABLE: 32f C3C functions can read outside of allocated memory
|
||||
if (cn > 1 && src.depth() == CV_32F)
|
||||
return false;
|
||||
|
||||
// SSE4.2 buffer overrun
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
// IPPICV doesn't have AVX2 in 32-bit builds
|
||||
// However cv::ipp::getIppTopFeatures() may return AVX2 value on AVX2 capable H/W
|
||||
// details #12959
|
||||
#else
|
||||
if (cv::ipp::getIppTopFeatures() == ippCPUID_SSE42) // Linux x64 + OPENCV_IPP=SSE42 is affected too
|
||||
#endif
|
||||
{
|
||||
if (src.depth() == CV_32F && src.dims > 1 && src.size[src.dims - 1] == 6)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t total_size = src.total();
|
||||
int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0;
|
||||
if( src.dims == 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) )
|
||||
{
|
||||
Ipp64f mean_temp[3];
|
||||
Ipp64f stddev_temp[3];
|
||||
Ipp64f *pmean = &mean_temp[0];
|
||||
Ipp64f *pstddev = &stddev_temp[0];
|
||||
Mat mean, stddev;
|
||||
int dcn_mean = -1;
|
||||
if( _mean.needed() )
|
||||
{
|
||||
if( !_mean.fixedSize() )
|
||||
_mean.create(cn, 1, CV_64F, -1, true);
|
||||
mean = _mean.getMat();
|
||||
dcn_mean = (int)mean.total();
|
||||
pmean = mean.ptr<Ipp64f>();
|
||||
}
|
||||
int dcn_stddev = -1;
|
||||
if( _sdv.needed() )
|
||||
{
|
||||
if( !_sdv.fixedSize() )
|
||||
_sdv.create(cn, 1, CV_64F, -1, true);
|
||||
stddev = _sdv.getMat();
|
||||
dcn_stddev = (int)stddev.total();
|
||||
pstddev = stddev.ptr<Ipp64f>();
|
||||
}
|
||||
for( int c = cn; c < dcn_mean; c++ )
|
||||
pmean[c] = 0;
|
||||
for( int c = cn; c < dcn_stddev; c++ )
|
||||
pstddev[c] = 0;
|
||||
IppiSize sz = { cols, rows };
|
||||
int type = src.type();
|
||||
if( !mask.empty() )
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *, Ipp64f *);
|
||||
ippiMaskMeanStdDevFuncC1 ippiMean_StdDev_C1MR =
|
||||
type == CV_8UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_8u_C1MR :
|
||||
type == CV_16UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_16u_C1MR :
|
||||
type == CV_32FC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_32f_C1MR :
|
||||
0;
|
||||
if( ippiMean_StdDev_C1MR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, pmean, pstddev) >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
|
||||
ippiMaskMeanStdDevFuncC3 ippiMean_StdDev_C3CMR =
|
||||
type == CV_8UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CMR :
|
||||
type == CV_16UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CMR :
|
||||
0;
|
||||
if( ippiMean_StdDev_C3CMR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CMR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 3, &pmean[2], &pstddev[2]) >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC1)(const void *, int, IppiSize, Ipp64f *, Ipp64f *);
|
||||
ippiMeanStdDevFuncC1 ippiMean_StdDev_C1R =
|
||||
type == CV_8UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_8u_C1R :
|
||||
type == CV_16UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_16u_C1R :
|
||||
#if (IPP_VERSION_X100 >= 810)
|
||||
type == CV_32FC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_32f_C1R ://Aug 2013: bug in IPP 7.1, 8.0
|
||||
#endif
|
||||
0;
|
||||
if( ippiMean_StdDev_C1R )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C1R, src.ptr(), (int)src.step[0], sz, pmean, pstddev) >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC3)(const void *, int, IppiSize, int, Ipp64f *, Ipp64f *);
|
||||
ippiMeanStdDevFuncC3 ippiMean_StdDev_C3CR =
|
||||
type == CV_8UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CR :
|
||||
type == CV_16UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CR :
|
||||
type == CV_32FC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CR :
|
||||
0;
|
||||
if( ippiMean_StdDev_C3CR )
|
||||
{
|
||||
if( CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src.ptr(), (int)src.step[0], sz, 1, &pmean[0], &pstddev[0]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src.ptr(), (int)src.step[0], sz, 2, &pmean[1], &pstddev[1]) >= 0 &&
|
||||
CV_INSTRUMENT_FUN_IPP(ippiMean_StdDev_C3CR, src.ptr(), (int)src.step[0], sz, 3, &pmean[2], &pstddev[2]) >= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
CV_UNUSED(src); CV_UNUSED(_mean); CV_UNUSED(_sdv); CV_UNUSED(mask);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void meanStdDev(InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray _mask)
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
@ -478,8 +248,6 @@ void meanStdDev(InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray
|
||||
|
||||
CV_Assert(mask.empty() || src.size == mask.size);
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_meanStdDev(src, _mean, _sdv, mask));
|
||||
|
||||
int k, cn = src.channels(), depth = src.depth();
|
||||
Mat mean_mat, stddev_mat;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user