From 72066a511142f28b119b8fcc039f7608b8061f10 Mon Sep 17 00:00:00 2001 From: Vitaly Tuzov Date: Tue, 27 Sep 2016 14:06:18 +0300 Subject: [PATCH 1/2] Fix for OpenVX-based implementation of HAL multiplication API --- 3rdparty/openvx/include/openvx_hal.hpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/3rdparty/openvx/include/openvx_hal.hpp b/3rdparty/openvx/include/openvx_hal.hpp index 26978e6db2..4e1f6dc2e8 100644 --- a/3rdparty/openvx/include/openvx_hal.hpp +++ b/3rdparty/openvx/include/openvx_hal.hpp @@ -343,11 +343,23 @@ inline int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, { try { + int rounding_policy = VX_ROUND_POLICY_TO_ZERO; + if (scale != 0x0.01010102) + { + int exp = 0; + double significand = frexp(scale, &exp); + if((significand != 0.5) || (exp > 1) || (exp < -14)) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + else + { + rounding_policy = VX_ROUND_POLICY_TO_NEAREST_EVEN;// That's the only rounding that MUST be supported for 1/255 scale + } vxContext * ctx = vxContext::getContext(); vxImage ia(*ctx, a, astep, w, h); vxImage ib(*ctx, b, bstep, w, h); vxImage ic(*ctx, c, cstep, w, h); - vxErr::check(vxuMultiply(ctx->ctx, ia.img, ib.img, (float)scale, VX_CONVERT_POLICY_SATURATE, VX_ROUND_POLICY_TO_ZERO, ic.img)); + vxErr::check(vxuMultiply(ctx->ctx, ia.img, ib.img, (float)scale, VX_CONVERT_POLICY_SATURATE, rounding_policy, ic.img)); } catch (vxErr & e) { From 81938af5d0a8a722c05a37ec230913289b795bbb Mon Sep 17 00:00:00 2001 From: mshabunin Date: Wed, 28 Sep 2016 15:27:11 +0300 Subject: [PATCH 2/2] Added support for OpenVX 1.0, updated cmake part, minor fixes --- 3rdparty/openvx/CMakeLists.txt | 3 +- 3rdparty/openvx/include/openvx_hal.hpp | 56 +++++++++++++++++++------- CMakeLists.txt | 2 +- cmake/FindOpenVX.cmake | 32 ++++++++++----- cmake/templates/cvconfig.h.in | 3 ++ 5 files changed, 69 insertions(+), 27 deletions(-) diff --git a/3rdparty/openvx/CMakeLists.txt b/3rdparty/openvx/CMakeLists.txt index ae9285eaf7..c7b151df68 100644 --- a/3rdparty/openvx/CMakeLists.txt +++ b/3rdparty/openvx/CMakeLists.txt @@ -1,7 +1,8 @@ -add_library(openvx_hal STATIC src/openvx_hal.cpp) +add_library(openvx_hal STATIC include/openvx_hal.hpp src/openvx_hal.cpp) target_include_directories(openvx_hal PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/modules/core/include + ${CMAKE_SOURCE_DIR}/modules/imgproc/include ${OPENVX_INCLUDE_DIR}) target_link_libraries(openvx_hal LINK_PUBLIC ${OPENVX_LIBRARIES}) set_target_properties(openvx_hal PROPERTIES POSITION_INDEPENDENT_CODE TRUE) diff --git a/3rdparty/openvx/include/openvx_hal.hpp b/3rdparty/openvx/include/openvx_hal.hpp index 4e1f6dc2e8..100c14938c 100644 --- a/3rdparty/openvx/include/openvx_hal.hpp +++ b/3rdparty/openvx/include/openvx_hal.hpp @@ -2,6 +2,7 @@ #define OPENCV_OPENVX_HAL_HPP_INCLUDED #include "opencv2/core/hal/interface.h" +#include "opencv2/imgproc/hal/interface.h" #include "VX/vx.h" #include "VX/vxu.h" @@ -10,7 +11,18 @@ #include #include -#include +#include +#include +#include + +#if VX_VERSION == VX_VERSION_1_0 + +#define VX_MEMORY_TYPE_HOST VX_IMPORT_TYPE_HOST +#define VX_INTERPOLATION_BILINEAR VX_INTERPOLATION_TYPE_BILINEAR +#define VX_INTERPOLATION_AREA VX_INTERPOLATION_TYPE_AREA +#define VX_INTERPOLATION_NEAREST_NEIGHBOR VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR + +#endif //================================================================================================== // utility @@ -267,7 +279,9 @@ struct vxImage } ~vxImage() { +#if VX_VERSION > VX_VERSION_1_0 vxErr::check(vxSwapImageHandle(img, NULL, NULL, 1)); +#endif vxReleaseImage(&img); } }; @@ -289,6 +303,8 @@ struct vxMatrix } }; +#if VX_VERSION > VX_VERSION_1_0 + struct vxConvolution { vx_convolution cnv; @@ -305,6 +321,8 @@ struct vxConvolution } }; +#endif + //================================================================================================== // real code starts here // ... @@ -341,25 +359,32 @@ OVX_BINARY_OP(xor, {vxErr::check(vxuXor(ctx->ctx, ia.img, ib.img, ic.img));}) template inline int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h, double scale) { +#ifdef _MSC_VER + const float MAGIC_SCALE = 0x0.01010102; +#else + const float MAGIC_SCALE = 0x1.010102p-8; +#endif try { int rounding_policy = VX_ROUND_POLICY_TO_ZERO; - if (scale != 0x0.01010102) + float fscale = (float)scale; + if (fabs(fscale - MAGIC_SCALE) > FLT_EPSILON) { int exp = 0; - double significand = frexp(scale, &exp); + double significand = frexp(fscale, &exp); if((significand != 0.5) || (exp > 1) || (exp < -14)) return CV_HAL_ERROR_NOT_IMPLEMENTED; } else { + fscale = MAGIC_SCALE; rounding_policy = VX_ROUND_POLICY_TO_NEAREST_EVEN;// That's the only rounding that MUST be supported for 1/255 scale } vxContext * ctx = vxContext::getContext(); vxImage ia(*ctx, a, astep, w, h); vxImage ib(*ctx, b, bstep, w, h); vxImage ic(*ctx, c, cstep, w, h); - vxErr::check(vxuMultiply(ctx->ctx, ia.img, ib.img, (float)scale, VX_CONVERT_POLICY_SATURATE, rounding_policy, ic.img)); + vxErr::check(vxuMultiply(ctx->ctx, ia.img, ib.img, fscale, VX_CONVERT_POLICY_SATURATE, rounding_policy, ic.img)); } catch (vxErr & e) { @@ -409,9 +434,6 @@ inline int ovx_hal_merge8u(const uchar **src_data, uchar *dst_data, int len, int return CV_HAL_ERROR_OK; } - -#if defined OPENCV_IMGPROC_HAL_INTERFACE_H - inline int ovx_hal_resize(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, double inv_scale_x, double inv_scale_y, int interpolation) { try @@ -447,6 +469,8 @@ inline int ovx_hal_resize(int atype, const uchar *a, size_t astep, int aw, int a return CV_HAL_ERROR_OK; } +#if VX_VERSION > VX_VERSION_1_0 + inline int ovx_hal_warpAffine(int atype, const uchar *a, size_t astep, int aw, int ah, uchar *b, size_t bstep, int bw, int bh, const double M[6], int interpolation, int borderType, const double borderValue[4]) { try @@ -568,8 +592,8 @@ struct cvhalFilter2D; struct FilterCtx { vxConvolution cnv; - vx_border_t border; int dst_type; + vx_border_t border; FilterCtx(vxContext &ctx, const short *data, int w, int h, int _dst_type, vx_border_t & _border) : cnv(ctx, data, w, h), dst_type(_dst_type), border(_border) {} }; @@ -770,7 +794,8 @@ inline int ovx_hal_morphInit(cvhalFilter2D **filter_context, int operation, int } else { - border.constant_value.U8 = cv::saturate_cast(borderValue[0]); + int rounded = round(borderValue[0]); + border.constant_value.U8 = (uchar)((unsigned)rounded <= UCHAR_MAX ? rounded : rounded > 0 ? UCHAR_MAX : 0); } break; case CV_HAL_BORDER_REPLICATE: @@ -891,6 +916,8 @@ inline int ovx_hal_morph(cvhalFilter2D *filter_context, uchar *a, size_t astep, return CV_HAL_ERROR_OK; } +#endif // 1.0 guard + inline int ovx_hal_cvtBGRtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int depth, int acn, int bcn, bool swapBlue) { if (depth != CV_8U || swapBlue || acn == bcn || (acn != 3 && acn != 4) || (bcn != 3 && bcn != 4)) @@ -991,8 +1018,6 @@ inline int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, return CV_HAL_ERROR_OK; } -#endif - //================================================================================================== // functions redefinition // ... @@ -1028,10 +1053,11 @@ inline int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, #undef cv_hal_merge8u #define cv_hal_merge8u ovx_hal_merge8u -#if defined OPENCV_IMGPROC_HAL_INTERFACE_H - #undef cv_hal_resize #define cv_hal_resize ovx_hal_resize + +#if VX_VERSION > VX_VERSION_1_0 + #undef cv_hal_warpAffine #define cv_hal_warpAffine ovx_hal_warpAffine #undef cv_hal_warpPerspective @@ -1058,6 +1084,8 @@ inline int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, #undef cv_hal_morphFree #define cv_hal_morphFree ovx_hal_morphFree +#endif // 1.0 guard + #undef cv_hal_cvtBGRtoBGR #define cv_hal_cvtBGRtoBGR ovx_hal_cvtBGRtoBGR #undef cv_hal_cvtTwoPlaneYUVtoBGR @@ -1070,5 +1098,3 @@ inline int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, #define cv_hal_cvtOnePlaneYUVtoBGR ovx_hal_cvtOnePlaneYUVtoBGR #endif - -#endif diff --git a/CMakeLists.txt b/CMakeLists.txt index b85990fdc8..44111ac467 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1235,7 +1235,7 @@ endif(DEFINED WITH_LAPACK) status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO) status(" Use Cuda:" HAVE_CUDA THEN "YES (ver ${CUDA_VERSION_STRING})" ELSE NO) status(" Use OpenCL:" HAVE_OPENCL THEN YES ELSE NO) -status(" Use OpenVX:" HAVE_OPENVX THEN "YES (${OPENVX_LIBS})" ELSE "NO") +status(" Use OpenVX:" HAVE_OPENVX THEN "YES (${OPENVX_LIBRARIES})" ELSE "NO") status(" Use custom HAL:" OpenCV_USED_HAL THEN "YES (${OpenCV_USED_HAL})" ELSE "NO") if(HAVE_CUDA) diff --git a/cmake/FindOpenVX.cmake b/cmake/FindOpenVX.cmake index dc1f7617bd..0a55e951d8 100644 --- a/cmake/FindOpenVX.cmake +++ b/cmake/FindOpenVX.cmake @@ -1,20 +1,32 @@ -ocv_clear_vars(HAVE_OPENVX OPENVX_LIBS) +ocv_clear_vars(HAVE_OPENVX) set(OPENVX_ROOT "" CACHE PATH "OpenVX install directory") +set(OPENVX_LIB_CANDIDATES "openvx;vxu" CACHE STRING "OpenVX library candidates list") + +function(find_openvx_libs _found) + foreach(one ${OPENVX_LIB_CANDIDATES}) + find_library(OPENVX_${one}_LIBRARY ${one} PATHS "${OPENVX_ROOT}/lib" "${OPENVX_ROOT}/bin") + if(OPENVX_${one}_LIBRARY) + list(APPEND _list ${OPENVX_${one}_LIBRARY}) + endif() + endforeach() + set(${_found} ${_list} PARENT_SCOPE) +endfunction() if(OPENVX_ROOT) find_path(OPENVX_INCLUDE_DIR "VX/vx.h" PATHS "${OPENVX_ROOT}/include" DOC "OpenVX include path") - find_library(OPENVX_openvx_LIB "openvx" PATHS "${OPENVX_ROOT}/lib") - find_library(OPENVX_vxu_LIB "vxu" PATHS "${OPENVX_ROOT}/lib") - set(OPENVX_LIBRARIES "${OPENVX_openvx_LIB}" "${OPENVX_vxu_LIB}" CACHE STRING "OpenVX libraries") - if (OPENVX_INCLUDE_DIR AND OPENVX_LIBRARIES) - set(HAVE_OPENVX TRUE) + if(NOT DEFINED OPENVX_LIBRARIES) + find_openvx_libs(found) + if(found) + set(OPENVX_LIBRARIES "${found}" CACHE STRING "OpenVX libraries") + endif() endif() endif() +if(OPENVX_INCLUDE_DIR AND OPENVX_LIBRARIES) + set(HAVE_OPENVX TRUE) +endif() + if(NOT HAVE_OPENVX) - unset(OPENVX_LIBRARIES CACHE) - unset(OPENVX_INCLUDE_DIR CACHE) - unset(HAVE_OPENVX) - message(STATUS "OpenVX: OFF") + ocv_clear_vars(HAVE_OPENVX OPENVX_LIBRARIES OPENVX_INCLUDE_DIR) endif() diff --git a/cmake/templates/cvconfig.h.in b/cmake/templates/cvconfig.h.in index 56d415b400..c4b147f8a4 100644 --- a/cmake/templates/cvconfig.h.in +++ b/cmake/templates/cvconfig.h.in @@ -215,3 +215,6 @@ /* Library was compiled with functions instrumentation */ #cmakedefine ENABLE_INSTRUMENTATION + +/* OpenVX */ +#cmakedefine HAVE_OPENVX