diff --git a/3rdparty/openvx/hal/openvx_hal.cpp b/3rdparty/openvx/hal/openvx_hal.cpp index d03c60954c..8fdc6f3fe2 100644 --- a/3rdparty/openvx/hal/openvx_hal.cpp +++ b/3rdparty/openvx/hal/openvx_hal.cpp @@ -1405,3 +1405,673 @@ int ovx_hal_FAST(const uchar* src_data, size_t src_step, int width, int height, return CV_HAL_ERROR_OK; } + +template <> inline bool skipSmallImages(int w, int h) { return w*h < 1280 * 720; } + +int ovx_hal_medianBlur(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, + int width, int height, int depth, int cn, int ksize) +{ + if (depth != CV_8U || cn != 1 +#ifndef VX_VERSION_1_1 + || ksize != 3 +#endif + ) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + if ( +#ifdef VX_VERSION_1_1 + ksize != 3 ? skipSmallImages(width, height) : +#endif + skipSmallImages(width, height) + ) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + try + { + ivx::Context ctx = getOpenVXHALContext(); +#ifdef VX_VERSION_1_1 + if ((vx_size)ksize > ctx.nonlinearMaxDimension()) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } +#endif + + ivx::Image ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)src_step), + const_cast(src_data)); + + ivx::Image ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)(dst_step)), + dst_data); + + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standard says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(VX_BORDER_REPLICATE); +#ifdef VX_VERSION_1_1 + if (ksize == 3) +#endif + { + ivx::IVX_CHECK_STATUS(vxuMedian3x3(ctx, ia, ib)); + } +#ifdef VX_VERSION_1_1 + else + { + ivx::Matrix mtx; + if(ksize == 5) + mtx = ivx::Matrix::createFromPattern(ctx, VX_PATTERN_BOX, ksize, ksize); + else + { + vx_size supportedSize; + ivx::IVX_CHECK_STATUS(vxQueryContext(ctx, VX_CONTEXT_NONLINEAR_MAX_DIMENSION, &supportedSize, sizeof(supportedSize))); + if ((vx_size)ksize > supportedSize) + { + ctx.setImmediateBorder(prevBorder); + return false; + } + + std::vector mtx_data(ksize*ksize, 255); + mtx = ivx::Matrix::create(ctx, VX_TYPE_UINT8, ksize, ksize); + mtx.copyFrom(&mtx_data[0]); + } + ivx::IVX_CHECK_STATUS(vxuNonLinearFilter(ctx, VX_NONLINEAR_FILTER_MEDIAN, ia, mtx, ib)); + } +#endif + ctx.setImmediateBorder(prevBorder); + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} + +template <> inline bool skipSmallImages(int w, int h) { return w*h < 320 * 240; } + +int ovx_hal_sobel(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int src_depth, int dst_depth, int cn, int margin_left, int margin_top, int margin_right, int margin_bottom, int dx, int dy, int ksize, double scale, double delta, int border_type) +{ + if (cn != 1 || src_depth != CV_8U || dst_depth != CV_16S || + ksize != 3 || scale != 1.0 || delta != 0.0 || + (dx | dy) != 1 || (dx + dy) != 1 || width < ksize || height < ksize) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + // ~BORDER_ISOLATED case not supported for now + if (margin_left != 0 || margin_top != 0 || margin_right != 0 || margin_bottom != 0) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + if (skipSmallImages(width, height)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + vx_enum border; + switch (border_type) + { + case CV_HAL_BORDER_CONSTANT: + border = VX_BORDER_CONSTANT; + break; + case CV_HAL_BORDER_REPLICATE: +// border = VX_BORDER_REPLICATE; +// break; + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + try + { + ivx::Context ctx = getOpenVXHALContext(); + //if ((vx_size)ksize > ctx.convolutionMaxDimension()) + // return false; + + ivx::Image ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)(src_step)), + const_cast(src_data)); + ivx::Image ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_S16, + ivx::Image::createAddressing(width, height, 2, (vx_int32)dst_step), + dst_data); + + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standard says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(border, (vx_uint8)(0)); + if(dx) + ivx::IVX_CHECK_STATUS(vxuSobel3x3(ctx, ia, ib, NULL)); + else + ivx::IVX_CHECK_STATUS(vxuSobel3x3(ctx, ia, NULL, ib)); + ctx.setImmediateBorder(prevBorder); + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} + +template <> inline bool skipSmallImages(int w, int h) { return w*h < 640 * 480; } + +int ovx_hal_canny(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, + int width, int height, int cn, double lowThreshold, double highThreshold, int ksize, bool L2gradient) +{ + if (cn != 1 || width <= ksize || height <= ksize) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + if (skipSmallImages(width, height)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + ivx::Context context = getOpenVXHALContext(); + try + { + ivx::Image _src = ivx::Image::createFromHandle(context, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)src_step), + const_cast(src_data)); + + ivx::Image _dst = ivx::Image::createFromHandle( context, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)dst_step), + dst_data); + + ivx::Threshold threshold = ivx::Threshold::createRange(context, VX_TYPE_UINT8, + (vx_int32)lowThreshold, + (vx_int32)highThreshold); + + #if 0 + // the code below is disabled because vxuCannyEdgeDetector() + // ignores context attribute VX_CONTEXT_IMMEDIATE_BORDER + + // FIXME: may fail in multithread case + border_t prevBorder = context.immediateBorder(); + context.setImmediateBorder(VX_BORDER_REPLICATE); + IVX_CHECK_STATUS( vxuCannyEdgeDetector(context, _src, threshold, ksize, (L2gradient ? VX_NORM_L2 : VX_NORM_L1), _dst) ); + context.setImmediateBorder(prevBorder); + #else + // alternative code without vxuCannyEdgeDetector() + ivx::Graph graph = ivx::Graph::create(context); + ivx::Node node = ivx::Node(vxCannyEdgeDetectorNode(graph, _src, threshold, ksize, + (L2gradient ? VX_NORM_L2 : VX_NORM_L1), _dst) ); + node.setBorder(VX_BORDER_REPLICATE); + graph.verify(); + graph.process(); + #endif + +#ifdef VX_VERSION_1_1 + _src.swapHandle(); + _dst.swapHandle(); +#endif + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} + +// static bool openvx_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType ) +int ovx_hal_pyrdown(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, int depth, int cn, int border_type) +{ + if (depth != CV_8U || border_type != CV_HAL_BORDER_REPLICATE) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + if (skipSmallImages(src_width, src_height)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + // The only border mode which is supported by both cv::pyrDown() and OpenVX + // and produces predictable results + ivx::border_t borderMode; + borderMode.mode = VX_BORDER_REPLICATE; + + try + { + ivx::Context context = getOpenVXHALContext(); + if(context.vendorID() == VX_ID_KHRONOS) + { + // This implementation performs floor-like rounding + // (OpenCV uses floor(x+0.5)-like rounding) + // and ignores border mode (and loses 1px size border) + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + ivx::Image srcImg = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(CV_8UC(cn)), + ivx::Image::createAddressing(src_width, src_height, 1, (vx_int32)src_step), + const_cast(src_data)); + + ivx::Image dstImg = ivx::Image::createFromHandle(context, ivx::Image::matTypeToFormat(CV_8UC(cn)), + ivx::Image::createAddressing(dst_width, dst_height, 1, (vx_int32)dst_step), + dst_data); + + ivx::Scalar kernelSize = ivx::Scalar::create(context, 5); + ivx::Graph graph = ivx::Graph::create(context); + ivx::Node halfNode = ivx::Node::create(graph, VX_KERNEL_HALFSCALE_GAUSSIAN, srcImg, dstImg, kernelSize); + halfNode.setBorder(borderMode); + graph.verify(); + graph.process(); + +#ifdef VX_VERSION_1_1 + //we should take user memory back before release + //(it's not done automatically according to standard) + srcImg.swapHandle(); dstImg.swapHandle(); +#endif + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} + +template <> inline bool skipSmallImages(int w, int h) { return w*h < 640 * 480; } + +int ovx_hal_boxFilter(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, + int width, int height, int src_depth, int dst_depth, int cn, + int margin_left, int margin_top, int margin_right, int margin_bottom, + size_t ksize_width, size_t ksize_height, int anchor_x, int anchor_y, + bool normalize, int border_type) +{ + if (src_depth != CV_8U || cn != 1 || ksize_width != 3 || ksize_height != 3 || dst_depth != CV_8U || + (anchor_x >= 0 && anchor_x != 1) || (anchor_y >= 0 && anchor_y != 1) || !normalize) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + // ~BORDER_ISOLATED case not supported for now + if (margin_left != 0 || margin_top != 0 || margin_right != 0 || margin_bottom != 0) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + if(skipSmallImages(width, height)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + vx_enum border; + switch (border_type) + { + case CV_HAL_BORDER_CONSTANT: + border = VX_BORDER_CONSTANT; + break; + case CV_HAL_BORDER_REPLICATE: + border = VX_BORDER_REPLICATE; + break; + default: + return false; + } + + try + { + ivx::Context ctx = getOpenVXHALContext(); + + ivx::Image ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)src_step), + const_cast(src_data)); + + ivx::Image ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)dst_step), + dst_data); + + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standard says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(border, (vx_uint8)(0)); + ivx::IVX_CHECK_STATUS(vxuBox3x3(ctx, ia, ib)); + ctx.setImmediateBorder(prevBorder); + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} + +int ovx_hal_equalize_hist(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height) +{ + if (skipSmallImages(width, height)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + try + { + ivx::Context context = getOpenVXHALContext(); + + ivx::Image srcImage = ivx::Image::createFromHandle(context, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)src_step), + const_cast(src_data)); + + ivx::Image dstImage = ivx::Image::createFromHandle(context, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)dst_step), + dst_data); + + ivx::IVX_CHECK_STATUS(vxuEqualizeHist(context, srcImage, dstImage)); + +#ifdef VX_VERSION_1_1 + //we should take user memory back before release + //(it's not done automatically according to standard) + srcImage.swapHandle(); dstImage.swapHandle(); +#endif + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} + +int ovx_hal_gaussianBlur(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, + int depth, int cn, size_t margin_left, size_t margin_top, size_t margin_right, size_t margin_bottom, + size_t ksize_width, size_t ksize_height, double sigmaX, double sigmaY, int border_type) +{ + if (sigmaY <= 0) + sigmaY = sigmaX; + // automatic detection of kernel size from sigma + if (ksize_width <= 0 && sigmaX > 0) + ksize_width = (vx_int32)(sigmaX*6 + 1) | 1; + if (ksize_height <= 0 && sigmaY > 0) + ksize_height = (vx_int32)(sigmaY*6 + 1) | 1; + + if (depth != CV_8U || cn != 1 || width < 3 || height < 3 || + ksize_width != 3 || ksize_height != 3) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + sigmaX = std::max(sigmaX, 0.); + sigmaY = std::max(sigmaY, 0.); + + if (!(sigmaX == 0.0 || (sigmaX - 0.8) < DBL_EPSILON) || !(sigmaY == 0.0 || (sigmaY - 0.8) < DBL_EPSILON)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + // ~BORDER_ISOLATED case not supported for now + if (margin_left != 0 || margin_top != 0 || margin_right != 0 || margin_bottom != 0) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + if (skipSmallImages(width, height)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + vx_enum border; + switch (border_type) + { + case CV_HAL_BORDER_CONSTANT: + border = VX_BORDER_CONSTANT; + break; + case CV_HAL_BORDER_REPLICATE: + border = VX_BORDER_REPLICATE; + break; + default: + return false; + } + + try + { + ivx::Context ctx = getOpenVXHALContext(); + + ivx::Image ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)src_step), + const_cast(src_data)); + + ivx::Image ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width, height, 1, (vx_int32)dst_step), + dst_data); + + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standard says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(border, (vx_uint8)(0)); + ivx::IVX_CHECK_STATUS(vxuGaussian3x3(ctx, ia, ib)); + ctx.setImmediateBorder(prevBorder); + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} + +int ovx_hal_remap32f(int src_type, 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, + float* mapx, size_t mapx_step, float* mapy, size_t mapy_step, + int interpolation, int border_type, const double border_value[4]) +{ + + if (src_type != CV_8UC1 || border_type != CV_HAL_BORDER_CONSTANT || (interpolation & CV_HAL_WARP_RELATIVE_MAP)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + if (skipSmallImages(src_width, src_height)) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + vx_interpolation_type_e inter_type; + switch (interpolation) + { + case CV_HAL_INTER_LINEAR: +#if VX_VERSION > VX_VERSION_1_0 + inter_type = VX_INTERPOLATION_BILINEAR; +#else + inter_type = VX_INTERPOLATION_TYPE_BILINEAR; +#endif + break; + case CV_HAL_INTER_NEAREST: +/* NEAREST_NEIGHBOR mode disabled since OpenCV round half to even while OpenVX sample implementation round half up +#if VX_VERSION > VX_VERSION_1_0 + inter_type = VX_INTERPOLATION_NEAREST_NEIGHBOR; +#else + inter_type = VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR; +#endif + if (!map1.empty()) + for (int y = 0; y < map1.rows; ++y) + { + float* line = map1.ptr(y); + for (int x = 0; x < map1.cols; ++x) + line[x] = cvRound(line[x]); + } + if (!map2.empty()) + for (int y = 0; y < map2.rows; ++y) + { + float* line = map2.ptr(y); + for (int x = 0; x < map2.cols; ++x) + line[x] = cvRound(line[x]); + } + break; +*/ + case CV_HAL_INTER_AREA://AREA interpolation mode is unsupported + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + try + { + ivx::Context ctx = getOpenVXHALContext(); + + ivx::Image ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(src_width, src_height, 1, (vx_int32)src_step), + const_cast(src_data)); + ivx::Image ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(dst_width, dst_height, 1, (vx_int32)dst_step), + dst_data); + + //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments + //since OpenVX standard says nothing about thread-safety for now + ivx::border_t prevBorder = ctx.immediateBorder(); + ctx.setImmediateBorder(VX_BORDER_CONSTANT, (vx_uint8)(border_value[0])); + + ivx::Remap map = ivx::Remap::create(ctx, src_width, src_height, dst_width, dst_height); + if (!mapx) map.setMappings(mapy, mapy_step); + else if (!mapy) map.setMappings(mapx, mapx_step); + else map.setMappings(mapx, mapx_step, mapy, mapy_step); + ivx::IVX_CHECK_STATUS(vxuRemap(ctx, ia, map, inter_type, ib)); +#ifdef VX_VERSION_1_1 + ib.swapHandle(); + ia.swapHandle(); +#endif + ctx.setImmediateBorder(prevBorder); + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} + +#define IMPL_OPENVX_TOZERO 1 +int ovx_hal_threshold(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, + int width, int height, int depth, int cn, double thresh, double maxValue, int thresholdType) +{ + if(depth != CV_8U) + { + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + int trueVal, falseVal; + switch (thresholdType) + { + case CV_HAL_THRESH_BINARY: +#ifndef VX_VERSION_1_1 + if (maxValue != 255) + return CV_HAL_ERROR_NOT_IMPLEMENTED; +#endif + trueVal = maxValue; + falseVal = 0; + break; + case CV_HAL_THRESH_TOZERO: +#if IMPL_OPENVX_TOZERO + trueVal = 255; + falseVal = 0; + break; +#endif + case CV_HAL_THRESH_BINARY_INV: +#ifdef VX_VERSION_1_1 + trueVal = 0; + falseVal = maxValue; + break; +#endif + case CV_HAL_THRESH_TOZERO_INV: +#ifdef VX_VERSION_1_1 +#if IMPL_OPENVX_TOZERO + trueVal = 0; + falseVal = 255; + break; +#endif +#endif + case CV_HAL_THRESH_TRUNC: + default: + return CV_HAL_ERROR_NOT_IMPLEMENTED; + } + + try + { + ivx::Context ctx = getOpenVXHALContext(); + + ivx::Threshold thh = ivx::Threshold::createBinary(ctx, VX_TYPE_UINT8, thresh); + thh.setValueTrue(trueVal); + thh.setValueFalse(falseVal); + + ivx::Image ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width*cn, height, 1, (vx_int32)src_step), + const_cast(src_data)); + ivx::Image ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width*cn, height, 1, (vx_int32)dst_step), + dst_data); + + ivx::IVX_CHECK_STATUS(vxuThreshold(ctx, ia, thh, ib)); +#if IMPL_OPENVX_TOZERO + if (thresholdType == CV_HAL_THRESH_TOZERO || thresholdType == CV_HAL_THRESH_TOZERO_INV) + { + ivx::Image ic = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, + ivx::Image::createAddressing(width*cn, height, 1, (vx_int32)dst_step), dst_data); + ivx::IVX_CHECK_STATUS(vxuAnd(ctx, ib, ia, ic)); + } +#endif + } + catch (const ivx::RuntimeError & e) + { + PRINT_HALERR_MSG(runtime); + return CV_HAL_ERROR_UNKNOWN; + } + catch (const ivx::WrapperError & e) + { + PRINT_HALERR_MSG(wrapper); + return CV_HAL_ERROR_UNKNOWN; + } + + return CV_HAL_ERROR_OK; +} diff --git a/3rdparty/openvx/hal/openvx_hal.hpp b/3rdparty/openvx/hal/openvx_hal.hpp index 539144f855..f9a2931eb5 100644 --- a/3rdparty/openvx/hal/openvx_hal.hpp +++ b/3rdparty/openvx/hal/openvx_hal.hpp @@ -59,8 +59,29 @@ int ovx_hal_meanStdDev(const uchar* src_data, size_t src_step, int width, int he int ovx_hal_lut(const uchar *src_data, size_t src_step, size_t src_type, const uchar* lut_data, size_t lut_channel_size, size_t lut_channels, uchar *dst_data, size_t dst_step, int width, int height); int ovx_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width, int height, int depth, double* minVal, double* maxVal, int* minIdx, int* maxIdx, uchar* mask, size_t mask_step); +int ovx_hal_medianBlur(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int cn, int ksize); +int ovx_hal_sobel(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int src_depth, int dst_depth, int cn, int margin_left, int margin_top, int margin_right, int margin_bottom, int dx, int dy, int ksize, double scale, double delta, int border_type); +int ovx_hal_canny(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, + int width, int height, int cn, double lowThreshold, double highThreshold, int ksize, bool L2gradient); +int ovx_hal_pyrdown(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, int depth, int cn, int border_type); +int ovx_hal_boxFilter(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, + int width, int height, int src_depth, int dst_depth, int cn, + int margin_left, int margin_top, int margin_right, int margin_bottom, + size_t ksize_width, size_t ksize_height, int anchor_x, int anchor_y, bool normalize, int border_type); +int ovx_hal_equalize_hist(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height); +int ovx_hal_gaussianBlur(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, + int depth, int cn, size_t margin_left, size_t margin_top, size_t margin_right, size_t margin_bottom, + size_t ksize_width, size_t ksize_height, double sigmaX, double sigmaY, int border_type); +int ovx_hal_remap32f(int src_type, 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, + float* mapx, size_t mapx_step, float* mapy, size_t mapy_step, + int interpolation, int border_type, const double border_value[4]); +int ovx_hal_threshold(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, + int width, int height, int depth, int cn, double thresh, double maxValue, int thresholdType); int ovx_hal_FAST(const uchar* src_data, size_t src_step, int width, int height, uchar* keypoints_data, size_t* keypoints_count, int threshold, bool nonmax_suppression, int /*cv::FastFeatureDetector::DetectorType*/ dtype); + //================================================================================================== // functions redefinition // ... @@ -153,6 +174,5 @@ int ovx_hal_FAST(const uchar* src_data, size_t src_step, int width, int height, #define cv_hal_lut ovx_hal_lut #undef cv_hal_minMaxIdxMaskStep #define cv_hal_minMaxIdxMaskStep ovx_hal_minMaxIdxMaskStep -#define cv_hal_FAST ovx_hal_FAST #endif diff --git a/3rdparty/openvx/include/ivx.hpp b/3rdparty/openvx/include/ivx.hpp index 281e4b0024..5e63d1bb24 100644 --- a/3rdparty/openvx/include/ivx.hpp +++ b/3rdparty/openvx/include/ivx.hpp @@ -1717,6 +1717,22 @@ static const vx_enum #endif } + /// Convert cv::Mat type to standard image format (fourcc), throws WrapperError if not possible + static vx_df_image matTypeToFormat(int matType) + { + switch (matType) + { + case CV_8UC4: return VX_DF_IMAGE_RGBX; + case CV_8UC3: return VX_DF_IMAGE_RGB; + case CV_8UC1: return VX_DF_IMAGE_U8; + case CV_16UC1: return VX_DF_IMAGE_U16; + case CV_16SC1: return VX_DF_IMAGE_S16; + case CV_32SC1: return VX_DF_IMAGE_S32; + case CV_32FC1: return VX_DF_IMAGE('F', '0', '3', '2'); + default: throw WrapperError(std::string(__func__)+"(): unsupported cv::Mat type"); + } + } + #ifdef IVX_USE_OPENCV /// Convert image format (fourcc) to cv::Mat type, throws WrapperError if not possible static int formatToMatType(vx_df_image format, vx_uint32 planeIdx = 0) @@ -1742,22 +1758,6 @@ static const vx_enum } } - /// Convert cv::Mat type to standard image format (fourcc), throws WrapperError if not possible - static vx_df_image matTypeToFormat(int matType) - { - switch (matType) - { - case CV_8UC4: return VX_DF_IMAGE_RGBX; - case CV_8UC3: return VX_DF_IMAGE_RGB; - case CV_8UC1: return VX_DF_IMAGE_U8; - case CV_16UC1: return VX_DF_IMAGE_U16; - case CV_16SC1: return VX_DF_IMAGE_S16; - case CV_32SC1: return VX_DF_IMAGE_S32; - case CV_32FC1: return VX_DF_IMAGE('F', '0', '3', '2'); - default: throw WrapperError(std::string(__func__)+"(): unsupported cv::Mat type"); - } - } - /// Initialize cv::Mat shape to fit the specified image plane data void createMatForPlane(cv::Mat& m, vx_uint32 planeIdx) { @@ -3177,6 +3177,27 @@ public: void getMapping(vx_uint32 dst_x, vx_uint32 dst_y, vx_float32 &src_x, vx_float32 &src_y) const { IVX_CHECK_STATUS(vxGetRemapPoint(ref, dst_x, dst_y, &src_x, &src_y)); } + void setMappings(vx_float32* map_x, size_t map_x_stride, vx_float32* map_y, size_t map_y_stride) + { + for (vx_uint32 y = 0; y < dstHeight(); y++) + { + const vx_float32* map_x_line = (vx_float32*)((char*)map_x + y*map_x_stride); + const vx_float32* map_y_line = (vx_float32*)((char*)map_y + y*map_y_stride); + for (vx_uint32 x = 0; x < dstWidth(); x++) + setMapping(x, y, map_x_line[x], map_y_line[x]); + } + } + + void setMappings(vx_float32* map, size_t map_stride) + { + for (vx_uint32 y = 0; y < dstHeight(); y++) + { + const vx_float32* map_line = (vx_float32*)((char*)map + y*map_stride); + for (vx_uint32 x = 0; x < 2*dstWidth(); x+=2) + setMapping(x, y, map_line[x], map_line[x+1]); + } + } + #ifdef IVX_USE_OPENCV void setMappings(const cv::Mat& map_x, const cv::Mat& map_y) { diff --git a/modules/imgproc/src/box_filter.dispatch.cpp b/modules/imgproc/src/box_filter.dispatch.cpp index 6baefdff1a..ba90adee1d 100644 --- a/modules/imgproc/src/box_filter.dispatch.cpp +++ b/modules/imgproc/src/box_filter.dispatch.cpp @@ -48,8 +48,6 @@ #include "opencv2/core/hal/intrin.hpp" #include "opencl_kernels_imgproc.hpp" -#include "opencv2/core/openvx/ovx_defs.hpp" - #include "box_filter.simd.hpp" #include "box_filter.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content @@ -315,80 +313,6 @@ Ptr createBoxFilter(int srcType, int dstType, Size ksize, CV_CPU_DISPATCH_MODES_ALL); } -#ifdef HAVE_OPENVX - namespace ovx { - template <> inline bool skipSmallImages(int w, int h) { return w*h < 640 * 480; } - } - static bool openvx_boxfilter(InputArray _src, OutputArray _dst, int ddepth, - Size ksize, Point anchor, - bool normalize, int borderType) - { - if (ddepth < 0) - ddepth = CV_8UC1; - if (_src.type() != CV_8UC1 || ddepth != CV_8U || !normalize || - _src.cols() < 3 || _src.rows() < 3 || - ksize.width != 3 || ksize.height != 3 || - (anchor.x >= 0 && anchor.x != 1) || - (anchor.y >= 0 && anchor.y != 1) || - ovx::skipSmallImages(_src.cols(), _src.rows())) - return false; - - Mat src = _src.getMat(); - - if ((borderType & BORDER_ISOLATED) == 0 && src.isSubmatrix()) - return false; //Process isolated borders only - vx_enum border; - switch (borderType & ~BORDER_ISOLATED) - { - case BORDER_CONSTANT: - border = VX_BORDER_CONSTANT; - break; - case BORDER_REPLICATE: - border = VX_BORDER_REPLICATE; - break; - default: - return false; - } - - _dst.create(src.size(), CV_8UC1); - Mat dst = _dst.getMat(); - - try - { - ivx::Context ctx = ovx::getOpenVXContext(); - - Mat a; - if (dst.data != src.data) - a = src; - else - src.copyTo(a); - - ivx::Image - ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(a.cols, a.rows, 1, (vx_int32)(a.step)), a.data), - ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(dst.cols, dst.rows, 1, (vx_int32)(dst.step)), dst.data); - - //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments - //since OpenVX standard says nothing about thread-safety for now - ivx::border_t prevBorder = ctx.immediateBorder(); - ctx.setImmediateBorder(border, (vx_uint8)(0)); - ivx::IVX_CHECK_STATUS(vxuBox3x3(ctx, ia, ib)); - ctx.setImmediateBorder(prevBorder); - } - catch (const ivx::RuntimeError & e) - { - VX_DbgThrow(e.what()); - } - catch (const ivx::WrapperError & e) - { - VX_DbgThrow(e.what()); - } - - return true; - } -#endif - #if 0 //defined(HAVE_IPP) static bool ipp_boxfilter(Mat &src, Mat &dst, Size ksize, Point anchor, bool normalize, int borderType) { @@ -475,9 +399,6 @@ void boxFilter(InputArray _src, OutputArray _dst, int ddepth, ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, ksize.width, ksize.height, anchor.x, anchor.y, normalize, borderType&~BORDER_ISOLATED); - CV_OVX_RUN(true, - openvx_boxfilter(src, dst, ddepth, ksize, anchor, normalize, borderType)) - //CV_IPP_RUN_FAST(ipp_boxfilter(src, dst, ksize, anchor, normalize, borderType)); borderType = (borderType&~BORDER_ISOLATED); diff --git a/modules/imgproc/src/canny.cpp b/modules/imgproc/src/canny.cpp index c322959441..29696139a1 100644 --- a/modules/imgproc/src/canny.cpp +++ b/modules/imgproc/src/canny.cpp @@ -45,8 +45,6 @@ #include "opencv2/core/hal/intrin.hpp" #include -#include "opencv2/core/openvx/ovx_defs.hpp" - namespace cv { @@ -761,65 +759,6 @@ private: finalPass& operator=(const finalPass&); // = delete }; -#ifdef HAVE_OPENVX -namespace ovx { - template <> inline bool skipSmallImages(int w, int h) { return w*h < 640 * 480; } -} -static bool openvx_canny(const Mat& src, Mat& dst, int loVal, int hiVal, int kSize, bool useL2) -{ - using namespace ivx; - - Context context = ovx::getOpenVXContext(); - try - { - Image _src = Image::createFromHandle( - context, - Image::matTypeToFormat(src.type()), - Image::createAddressing(src), - src.data ); - Image _dst = Image::createFromHandle( - context, - Image::matTypeToFormat(dst.type()), - Image::createAddressing(dst), - dst.data ); - Threshold threshold = Threshold::createRange(context, VX_TYPE_UINT8, saturate_cast(loVal), saturate_cast(hiVal)); - -#if 0 - // the code below is disabled because vxuCannyEdgeDetector() - // ignores context attribute VX_CONTEXT_IMMEDIATE_BORDER - - // FIXME: may fail in multithread case - border_t prevBorder = context.immediateBorder(); - context.setImmediateBorder(VX_BORDER_REPLICATE); - IVX_CHECK_STATUS( vxuCannyEdgeDetector(context, _src, threshold, kSize, (useL2 ? VX_NORM_L2 : VX_NORM_L1), _dst) ); - context.setImmediateBorder(prevBorder); -#else - // alternative code without vxuCannyEdgeDetector() - Graph graph = Graph::create(context); - ivx::Node node = ivx::Node(vxCannyEdgeDetectorNode(graph, _src, threshold, kSize, (useL2 ? VX_NORM_L2 : VX_NORM_L1), _dst) ); - node.setBorder(VX_BORDER_REPLICATE); - graph.verify(); - graph.process(); -#endif - -#ifdef VX_VERSION_1_1 - _src.swapHandle(); - _dst.swapHandle(); -#endif - } - catch(const WrapperError& e) - { - VX_DbgThrow(e.what()); - } - catch(const RuntimeError& e) - { - VX_DbgThrow(e.what()); - } - - return true; -} -#endif // HAVE_OPENVX - void Canny( InputArray _src, OutputArray _dst, double low_thresh, double high_thresh, int aperture_size, bool L2gradient ) @@ -864,21 +803,6 @@ void Canny( InputArray _src, OutputArray _dst, CALL_HAL(canny, cv_hal_canny, src.data, src.step, dst.data, dst.step, src.cols, src.rows, src.channels(), low_thresh, high_thresh, aperture_size, L2gradient); - CV_OVX_RUN( - false && /* disabling due to accuracy issues */ - src.type() == CV_8UC1 && - !src.isSubmatrix() && - src.cols >= aperture_size && - src.rows >= aperture_size && - !ovx::skipSmallImages(src.cols, src.rows), - openvx_canny( - src, - dst, - cvFloor(low_thresh), - cvFloor(high_thresh), - aperture_size, - L2gradient ) ) - CV_IPP_RUN_FAST(ipp_Canny(src, Mat(), Mat(), dst, (float)low_thresh, (float)high_thresh, L2gradient, aperture_size)) if (L2gradient) diff --git a/modules/imgproc/src/deriv.cpp b/modules/imgproc/src/deriv.cpp index cc9db282fd..4e5c0f986b 100644 --- a/modules/imgproc/src/deriv.cpp +++ b/modules/imgproc/src/deriv.cpp @@ -43,7 +43,6 @@ #include "precomp.hpp" #include "opencl_kernels_imgproc.hpp" -#include "opencv2/core/openvx/ovx_defs.hpp" #include "filter.hpp" /****************************************************************************************\ @@ -182,83 +181,6 @@ cv::Ptr cv::createDerivFilter(int srcType, int dstType, kx, ky, Point(-1,-1), 0, borderType ); } -#ifdef HAVE_OPENVX -namespace cv -{ - namespace ovx { - template <> inline bool skipSmallImages(int w, int h) { return w*h < 320 * 240; } - } - static bool openvx_sobel(InputArray _src, OutputArray _dst, - int dx, int dy, int ksize, - double scale, double delta, int borderType) - { - if (_src.type() != CV_8UC1 || _dst.type() != CV_16SC1 || - ksize != 3 || scale != 1.0 || delta != 0.0 || - (dx | dy) != 1 || (dx + dy) != 1 || - _src.cols() < ksize || _src.rows() < ksize || - ovx::skipSmallImages(_src.cols(), _src.rows()) - ) - return false; - - Mat src = _src.getMat(); - Mat dst = _dst.getMat(); - - if ((borderType & BORDER_ISOLATED) == 0 && src.isSubmatrix()) - return false; //Process isolated borders only - vx_enum border; - switch (borderType & ~BORDER_ISOLATED) - { - case BORDER_CONSTANT: - border = VX_BORDER_CONSTANT; - break; - case BORDER_REPLICATE: -// border = VX_BORDER_REPLICATE; -// break; - default: - return false; - } - - try - { - ivx::Context ctx = ovx::getOpenVXContext(); - //if ((vx_size)ksize > ctx.convolutionMaxDimension()) - // return false; - - Mat a; - if (dst.data != src.data) - a = src; - else - src.copyTo(a); - - ivx::Image - ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(a.cols, a.rows, 1, (vx_int32)(a.step)), a.data), - ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_S16, - ivx::Image::createAddressing(dst.cols, dst.rows, 2, (vx_int32)(dst.step)), dst.data); - - //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments - //since OpenVX standard says nothing about thread-safety for now - ivx::border_t prevBorder = ctx.immediateBorder(); - ctx.setImmediateBorder(border, (vx_uint8)(0)); - if(dx) - ivx::IVX_CHECK_STATUS(vxuSobel3x3(ctx, ia, ib, NULL)); - else - ivx::IVX_CHECK_STATUS(vxuSobel3x3(ctx, ia, NULL, ib)); - ctx.setImmediateBorder(prevBorder); - } - catch (const ivx::RuntimeError & e) - { - VX_DbgThrow(e.what()); - } - catch (const ivx::WrapperError & e) - { - VX_DbgThrow(e.what()); - } - - return true; - } -} -#endif #if 0 //defined HAVE_IPP namespace cv @@ -456,9 +378,6 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, CALL_HAL(sobel, cv_hal_sobel, src.ptr(), src.step, dst.ptr(), dst.step, src.cols, src.rows, sdepth, ddepth, cn, ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, dx, dy, ksize, scale, delta, borderType&~BORDER_ISOLATED); - CV_OVX_RUN(true, - openvx_sobel(src, dst, dx, dy, ksize, scale, delta, borderType)) - //CV_IPP_RUN_FAST(ipp_Deriv(src, dst, dx, dy, ksize, scale, delta, borderType)); sepFilter2D(src, dst, ddepth, kx, ky, Point(-1, -1), delta, borderType ); diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index 48c1223059..c90039a0f3 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -3396,43 +3396,6 @@ static bool ocl_equalizeHist(InputArray _src, OutputArray _dst) #endif -#ifdef HAVE_OPENVX -namespace cv -{ -static bool openvx_equalize_hist(Mat srcMat, Mat dstMat) -{ - using namespace ivx; - - try - { - Context context = ovx::getOpenVXContext(); - Image srcImage = Image::createFromHandle(context, Image::matTypeToFormat(srcMat.type()), - Image::createAddressing(srcMat), srcMat.data); - Image dstImage = Image::createFromHandle(context, Image::matTypeToFormat(dstMat.type()), - Image::createAddressing(dstMat), dstMat.data); - - IVX_CHECK_STATUS(vxuEqualizeHist(context, srcImage, dstImage)); - -#ifdef VX_VERSION_1_1 - //we should take user memory back before release - //(it's not done automatically according to standard) - srcImage.swapHandle(); dstImage.swapHandle(); -#endif - } - catch (const RuntimeError & e) - { - VX_DbgThrow(e.what()); - } - catch (const WrapperError & e) - { - VX_DbgThrow(e.what()); - } - - return true; -} -} -#endif - void cv::equalizeHist( InputArray _src, OutputArray _dst ) { CV_INSTRUMENT_REGION(); @@ -3449,9 +3412,6 @@ void cv::equalizeHist( InputArray _src, OutputArray _dst ) _dst.create( src.size(), src.type() ); Mat dst = _dst.getMat(); - CV_OVX_RUN(!ovx::skipSmallImages(src.cols, src.rows), - openvx_equalize_hist(src, dst)) - CALL_HAL(equalizeHist, cv_hal_equalize_hist, src.data, src.step, dst.data, dst.step, src.cols, src.rows); Mutex histogramLockInstance; diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index c8371daf2d..609b3f4557 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -52,7 +52,6 @@ #include "hal_replacement.hpp" #include #include "opencv2/core/hal/intrin.hpp" -#include "opencv2/core/openvx/ovx_defs.hpp" #include "opencv2/core/softfloat.hpp" #include "imgwarp.hpp" @@ -1573,94 +1572,6 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst, #endif -#ifdef HAVE_OPENVX -static bool openvx_remap(Mat src, Mat dst, Mat map1, Mat map2, int interpolation, const Scalar& borderValue) -{ - vx_interpolation_type_e inter_type; - switch (interpolation) - { - case INTER_LINEAR: -#if VX_VERSION > VX_VERSION_1_0 - inter_type = VX_INTERPOLATION_BILINEAR; -#else - inter_type = VX_INTERPOLATION_TYPE_BILINEAR; -#endif - break; - case INTER_NEAREST: -/* NEAREST_NEIGHBOR mode disabled since OpenCV round half to even while OpenVX sample implementation round half up -#if VX_VERSION > VX_VERSION_1_0 - inter_type = VX_INTERPOLATION_NEAREST_NEIGHBOR; -#else - inter_type = VX_INTERPOLATION_TYPE_NEAREST_NEIGHBOR; -#endif - if (!map1.empty()) - for (int y = 0; y < map1.rows; ++y) - { - float* line = map1.ptr(y); - for (int x = 0; x < map1.cols; ++x) - line[x] = cvRound(line[x]); - } - if (!map2.empty()) - for (int y = 0; y < map2.rows; ++y) - { - float* line = map2.ptr(y); - for (int x = 0; x < map2.cols; ++x) - line[x] = cvRound(line[x]); - } - break; -*/ - case INTER_AREA://AREA interpolation mode is unsupported - default: - return false; - } - - try - { - ivx::Context ctx = ovx::getOpenVXContext(); - - Mat a; - if (dst.data != src.data) - a = src; - else - src.copyTo(a); - - ivx::Image - ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(a.cols, a.rows, 1, (vx_int32)(a.step)), a.data), - ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(dst.cols, dst.rows, 1, (vx_int32)(dst.step)), dst.data); - - //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments - //since OpenVX standard says nothing about thread-safety for now - ivx::border_t prevBorder = ctx.immediateBorder(); - ctx.setImmediateBorder(VX_BORDER_CONSTANT, (vx_uint8)(borderValue[0])); - - ivx::Remap map = ivx::Remap::create(ctx, src.cols, src.rows, dst.cols, dst.rows); - if (map1.empty()) map.setMappings(map2); - else if (map2.empty()) map.setMappings(map1); - else map.setMappings(map1, map2); - ivx::IVX_CHECK_STATUS(vxuRemap(ctx, ia, map, inter_type, ib)); -#ifdef VX_VERSION_1_1 - ib.swapHandle(); - ia.swapHandle(); -#endif - - ctx.setImmediateBorder(prevBorder); - } - catch (const ivx::RuntimeError & e) - { - CV_Error(cv::Error::StsInternal, e.what()); - return false; - } - catch (const ivx::WrapperError & e) - { - CV_Error(cv::Error::StsInternal, e.what()); - return false; - } - return true; -} -#endif - #if defined HAVE_IPP && !IPP_DISABLE_REMAP typedef IppStatus (CV_STDCALL * ippiRemap)(const void * pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi, @@ -1799,17 +1710,6 @@ void cv::remap( InputArray _src, OutputArray _dst, _dst.create( map1.size(), src.type() ); Mat dst = _dst.getMat(); - CV_OVX_RUN( - src.type() == CV_8UC1 && dst.type() == CV_8UC1 && - !ovx::skipSmallImages(src.cols, src.rows) && - (borderType& ~BORDER_ISOLATED) == BORDER_CONSTANT && - ((map1.type() == CV_32FC2 && map2.empty() && map1.size == dst.size) || - (map1.type() == CV_32FC1 && map2.type() == CV_32FC1 && map1.size == dst.size && map2.size == dst.size) || - (map1.empty() && map2.type() == CV_32FC2 && map2.size == dst.size)) && - ((borderType & BORDER_ISOLATED) != 0 || !src.isSubmatrix()) && - !hasRelativeFlag, - openvx_remap(src, dst, map1, map2, interpolation, borderValue)); - CV_Assert( dst.cols < SHRT_MAX && dst.rows < SHRT_MAX && src.cols < SHRT_MAX && src.rows < SHRT_MAX ); if( dst.data == src.data ) diff --git a/modules/imgproc/src/median_blur.dispatch.cpp b/modules/imgproc/src/median_blur.dispatch.cpp index 949a0a9ece..6e1b9c917d 100644 --- a/modules/imgproc/src/median_blur.dispatch.cpp +++ b/modules/imgproc/src/median_blur.dispatch.cpp @@ -48,8 +48,6 @@ #include "opencv2/core/hal/intrin.hpp" #include "opencl_kernels_imgproc.hpp" -#include "opencv2/core/openvx/ovx_defs.hpp" - #include "median_blur.simd.hpp" #include "median_blur.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content @@ -112,97 +110,6 @@ static bool ocl_medianFilter(InputArray _src, OutputArray _dst, int m) #endif -#ifdef HAVE_OPENVX -namespace ovx { - template <> inline bool skipSmallImages(int w, int h) { return w*h < 1280 * 720; } -} -static bool openvx_medianFilter(InputArray _src, OutputArray _dst, int ksize) -{ - if (_src.type() != CV_8UC1 || _dst.type() != CV_8U -#ifndef VX_VERSION_1_1 - || ksize != 3 -#endif - ) - return false; - - Mat src = _src.getMat(); - Mat dst = _dst.getMat(); - - if ( -#ifdef VX_VERSION_1_1 - ksize != 3 ? ovx::skipSmallImages(src.cols, src.rows) : -#endif - ovx::skipSmallImages(src.cols, src.rows) - ) - return false; - - try - { - ivx::Context ctx = ovx::getOpenVXContext(); -#ifdef VX_VERSION_1_1 - if ((vx_size)ksize > ctx.nonlinearMaxDimension()) - return false; -#endif - - Mat a; - if (dst.data != src.data) - a = src; - else - src.copyTo(a); - - ivx::Image - ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(a.cols, a.rows, 1, (vx_int32)(a.step)), a.data), - ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(dst.cols, dst.rows, 1, (vx_int32)(dst.step)), dst.data); - - //ATTENTION: VX_CONTEXT_IMMEDIATE_BORDER attribute change could lead to strange issues in multi-threaded environments - //since OpenVX standard says nothing about thread-safety for now - ivx::border_t prevBorder = ctx.immediateBorder(); - ctx.setImmediateBorder(VX_BORDER_REPLICATE); -#ifdef VX_VERSION_1_1 - if (ksize == 3) -#endif - { - ivx::IVX_CHECK_STATUS(vxuMedian3x3(ctx, ia, ib)); - } -#ifdef VX_VERSION_1_1 - else - { - ivx::Matrix mtx; - if(ksize == 5) - mtx = ivx::Matrix::createFromPattern(ctx, VX_PATTERN_BOX, ksize, ksize); - else - { - vx_size supportedSize; - ivx::IVX_CHECK_STATUS(vxQueryContext(ctx, VX_CONTEXT_NONLINEAR_MAX_DIMENSION, &supportedSize, sizeof(supportedSize))); - if ((vx_size)ksize > supportedSize) - { - ctx.setImmediateBorder(prevBorder); - return false; - } - Mat mask(ksize, ksize, CV_8UC1, Scalar(255)); - mtx = ivx::Matrix::create(ctx, VX_TYPE_UINT8, ksize, ksize); - mtx.copyFrom(mask); - } - ivx::IVX_CHECK_STATUS(vxuNonLinearFilter(ctx, VX_NONLINEAR_FILTER_MEDIAN, ia, mtx, ib)); - } -#endif - ctx.setImmediateBorder(prevBorder); - } - catch (const ivx::RuntimeError & e) - { - VX_DbgThrow(e.what()); - } - catch (const ivx::WrapperError & e) - { - VX_DbgThrow(e.what()); - } - - return true; -} -#endif - #if 0 //defined HAVE_IPP static bool ipp_medianFilter(Mat &src0, Mat &dst, int ksize) { @@ -300,9 +207,6 @@ void medianBlur( InputArray _src0, OutputArray _dst, int ksize ) CALL_HAL(medianBlur, cv_hal_medianBlur, src0.data, src0.step, dst.data, dst.step, src0.cols, src0.rows, src0.depth(), src0.channels(), ksize); - CV_OVX_RUN(true, - openvx_medianFilter(_src0, _dst, ksize)) - //CV_IPP_RUN_FAST(ipp_medianFilter(src0, dst, ksize)); CV_CPU_DISPATCH(medianBlur, (src0, dst, ksize), diff --git a/modules/imgproc/src/pyramids.cpp b/modules/imgproc/src/pyramids.cpp index d8993b5cc3..f8a412863d 100644 --- a/modules/imgproc/src/pyramids.cpp +++ b/modules/imgproc/src/pyramids.cpp @@ -45,8 +45,6 @@ #include "opencl_kernels_imgproc.hpp" #include "opencv2/core/hal/intrin.hpp" -#include "opencv2/core/openvx/ovx_defs.hpp" - namespace cv { @@ -1266,85 +1264,6 @@ static bool ocl_pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int } -#ifdef HAVE_OPENVX -namespace cv -{ -static bool openvx_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType ) -{ - using namespace ivx; - - Mat srcMat = _src.getMat(); - - if (ovx::skipSmallImages(srcMat.cols, srcMat.rows)) - return false; - - CV_Assert(!srcMat.empty()); - - Size ssize = _src.size(); - Size acceptableSize = Size((ssize.width + 1) / 2, (ssize.height + 1) / 2); - - // OpenVX limitations - if((srcMat.type() != CV_8U) || - (borderType != BORDER_REPLICATE) || - (_dsz != acceptableSize && !_dsz.empty())) - return false; - - // The only border mode which is supported by both cv::pyrDown() and OpenVX - // and produces predictable results - ivx::border_t borderMode; - borderMode.mode = VX_BORDER_REPLICATE; - - _dst.create( acceptableSize, srcMat.type() ); - Mat dstMat = _dst.getMat(); - - CV_Assert( ssize.width > 0 && ssize.height > 0 && - std::abs(acceptableSize.width*2 - ssize.width) <= 2 && - std::abs(acceptableSize.height*2 - ssize.height) <= 2 ); - - try - { - Context context = ovx::getOpenVXContext(); - if(context.vendorID() == VX_ID_KHRONOS) - { - // This implementation performs floor-like rounding - // (OpenCV uses floor(x+0.5)-like rounding) - // and ignores border mode (and loses 1px size border) - return false; - } - - Image srcImg = Image::createFromHandle(context, Image::matTypeToFormat(srcMat.type()), - Image::createAddressing(srcMat), (void*)srcMat.data); - Image dstImg = Image::createFromHandle(context, Image::matTypeToFormat(dstMat.type()), - Image::createAddressing(dstMat), (void*)dstMat.data); - - ivx::Scalar kernelSize = ivx::Scalar::create(context, 5); - Graph graph = Graph::create(context); - ivx::Node halfNode = ivx::Node::create(graph, VX_KERNEL_HALFSCALE_GAUSSIAN, srcImg, dstImg, kernelSize); - halfNode.setBorder(borderMode); - graph.verify(); - graph.process(); - -#ifdef VX_VERSION_1_1 - //we should take user memory back before release - //(it's not done automatically according to standard) - srcImg.swapHandle(); dstImg.swapHandle(); -#endif - } - catch (const RuntimeError & e) - { - VX_DbgThrow(e.what()); - } - catch (const WrapperError & e) - { - VX_DbgThrow(e.what()); - } - - return true; -} - -} -#endif - void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType ) { CV_INSTRUMENT_REGION(); @@ -1354,9 +1273,6 @@ void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borde CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(), ocl_pyrDown(_src, _dst, _dsz, borderType)) - CV_OVX_RUN(_src.dims() <= 2, - openvx_pyrDown(_src, _dst, _dsz, borderType)) - Mat src = _src.getMat(); Size dsz = _dsz.empty() ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz; _dst.create( dsz, src.type() ); diff --git a/modules/imgproc/src/smooth.dispatch.cpp b/modules/imgproc/src/smooth.dispatch.cpp index f7dafbd956..f7373f362d 100644 --- a/modules/imgproc/src/smooth.dispatch.cpp +++ b/modules/imgproc/src/smooth.dispatch.cpp @@ -713,8 +713,6 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize, // IPP is not bit-exact to OpenCV implementation CV_IPP_RUN_FAST(ipp_GaussianBlur(src, dst, ksize, sigma1, sigma2, borderType)); #endif - CV_OVX_RUN(true, - openvx_gaussianBlur(src, dst, ksize, sigma1, sigma2, borderType)) } CV_CPU_DISPATCH(GaussianBlurFixedPoint, (src, dst, (const uint16_t*)&fkx[0], (int)fkx.size(), (const uint16_t*)&fky[0], (int)fky.size(), borderType), @@ -783,8 +781,6 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize, // IPP is not bit-exact to OpenCV implementation CV_IPP_RUN_FAST(ipp_GaussianBlur(src, dst, ksize, sigma1, sigma2, borderType)); #endif - CV_OVX_RUN(true, - openvx_gaussianBlur(src, dst, ksize, sigma1, sigma2, borderType)) } CV_CPU_DISPATCH(GaussianBlurFixedPoint, (src, dst, (const uint32_t*)&fkx[0], (int)fkx.size(), (const uint32_t*)&fky[0], (int)fky.size(), borderType), @@ -814,9 +810,6 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize, ofs.x, ofs.y, wsz.width - src.cols - ofs.x, wsz.height - src.rows - ofs.y, ksize.width, ksize.height, sigma1, sigma2, borderType & ~BORDER_ISOLATED); - CV_OVX_RUN(true, - openvx_gaussianBlur(src, dst, ksize, sigma1, sigma2, borderType)) - #if defined ENABLE_IPP_GAUSSIAN_BLUR // IPP is not bit-exact to OpenCV implementation CV_IPP_RUN_FAST(ipp_GaussianBlur(src, dst, ksize, sigma1, sigma2, borderType)); diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index b45a54d0cf..c92912d8dc 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -44,8 +44,6 @@ #include "opencl_kernels_imgproc.hpp" #include "opencv2/core/hal/intrin.hpp" -#include "opencv2/core/openvx/ovx_defs.hpp" - namespace cv { @@ -1447,97 +1445,6 @@ static bool ocl_threshold( InputArray _src, OutputArray _dst, double & thresh, d #endif - -#ifdef HAVE_OPENVX -#define IMPL_OPENVX_TOZERO 1 -static bool openvx_threshold(Mat src, Mat dst, int thresh, int maxval, int type) -{ - Mat a = src; - - int trueVal, falseVal; - switch (type) - { - case THRESH_BINARY: -#ifndef VX_VERSION_1_1 - if (maxval != 255) - return false; -#endif - trueVal = maxval; - falseVal = 0; - break; - case THRESH_TOZERO: -#if IMPL_OPENVX_TOZERO - trueVal = 255; - falseVal = 0; - if (dst.data == src.data) - { - a = Mat(src.size(), src.type()); - src.copyTo(a); - } - break; -#endif - case THRESH_BINARY_INV: -#ifdef VX_VERSION_1_1 - trueVal = 0; - falseVal = maxval; - break; -#endif - case THRESH_TOZERO_INV: -#ifdef VX_VERSION_1_1 -#if IMPL_OPENVX_TOZERO - trueVal = 0; - falseVal = 255; - if (dst.data == src.data) - { - a = Mat(src.size(), src.type()); - src.copyTo(a); - } - break; -#endif -#endif - case THRESH_TRUNC: - default: - return false; - } - - try - { - ivx::Context ctx = ovx::getOpenVXContext(); - - ivx::Threshold thh = ivx::Threshold::createBinary(ctx, VX_TYPE_UINT8, thresh); - thh.setValueTrue(trueVal); - thh.setValueFalse(falseVal); - - ivx::Image - ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(a.cols*a.channels(), a.rows, 1, (vx_int32)(a.step)), src.data), - ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(dst.cols*dst.channels(), dst.rows, 1, (vx_int32)(dst.step)), dst.data); - - ivx::IVX_CHECK_STATUS(vxuThreshold(ctx, ia, thh, ib)); -#if IMPL_OPENVX_TOZERO - if (type == THRESH_TOZERO || type == THRESH_TOZERO_INV) - { - ivx::Image - ic = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8, - ivx::Image::createAddressing(dst.cols*dst.channels(), dst.rows, 1, (vx_int32)(dst.step)), dst.data); - ivx::IVX_CHECK_STATUS(vxuAnd(ctx, ib, ia, ic)); - } -#endif - } - catch (const ivx::RuntimeError & e) - { - VX_DbgThrow(e.what()); - } - catch (const ivx::WrapperError & e) - { - VX_DbgThrow(e.what()); - } - - return true; -} -#endif - } double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double maxval, int type ) @@ -1605,9 +1512,6 @@ double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double m return thresh; } - CV_OVX_RUN(!ovx::skipSmallImages(src.cols, src.rows), - openvx_threshold(src, dst, ithresh, imaxval, type), (double)ithresh) - thresh = ithresh; maxval = imaxval; }