mirror of
https://github.com/opencv/opencv.git
synced 2025-07-20 19:17:36 +08:00
Merge pull request #26903 from asmorkalov:as/openvx_hal
Migrate remaning OpenVX integrations to OpenVX HAL (core) #26903 Tested with OpenVX 1.2 & 1.3 sample implementation. Steps to build and test: ``` git clone git@github.com:KhronosGroup/OpenVX-sample-impl.git cd OpenVX-sample-impl python3 Build.py --os=Linux --conf=Release cd .. mkdir build cmake -DWITH_OPENVX=ON -DOPENVX_ROOT=/mnt/Projects/Projects/OpenVX-sample-impl/install/Linux/x64/Release/ ../opencv make -j8 ``` ### 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
e4b23cf96a
commit
58e557d059
191
3rdparty/openvx/hal/openvx_hal.cpp
vendored
191
3rdparty/openvx/hal/openvx_hal.cpp
vendored
@ -191,7 +191,7 @@ int ovx_hal_mul(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t
|
||||
#ifdef _WIN32
|
||||
const float MAGIC_SCALE = 0x0.01010102p0;
|
||||
#else
|
||||
const float MAGIC_SCALE = 0x1.010102p-8;
|
||||
const float MAGIC_SCALE = 0.003922; // 0x1.010102p-8;
|
||||
#endif
|
||||
try
|
||||
{
|
||||
@ -1145,3 +1145,192 @@ int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep,
|
||||
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
int ovx_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)
|
||||
{
|
||||
(void)mask_step;
|
||||
|
||||
if (src_type != CV_8UC1 || mask)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (skipSmallImages<VX_KERNEL_MEAN_STDDEV>(width, height))
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (src_step == 0)
|
||||
{
|
||||
src_step = (int)width;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
#ifndef VX_VERSION_1_1
|
||||
if (ctx.vendorID() == VX_ID_KHRONOS)
|
||||
return false; // Do not use OpenVX meanStdDev estimation for sample 1.0.1 implementation due to lack of accuracy
|
||||
#endif
|
||||
|
||||
ivx::Image ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(width, height, 1, (vx_int32)src_step), const_cast<uchar*>(src_data));
|
||||
|
||||
vx_float32 mean_temp, stddev_temp;
|
||||
ivx::IVX_CHECK_STATUS(vxuMeanStdDev(ctx, ia, &mean_temp, &stddev_temp));
|
||||
|
||||
if (mean_val)
|
||||
{
|
||||
mean_val[0] = mean_temp;
|
||||
}
|
||||
|
||||
if (stddev_val)
|
||||
{
|
||||
stddev_val[0] = stddev_temp;
|
||||
}
|
||||
}
|
||||
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_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)
|
||||
{
|
||||
if (src_type != CV_8UC1 || lut_channels != 1 || lut_channel_size != 1)
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (skipSmallImages<VX_KERNEL_TABLE_LOOKUP>(width, height))
|
||||
{
|
||||
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(width, height, 1, (vx_int32)src_step),
|
||||
const_cast<uchar*>(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);
|
||||
|
||||
ivx::LUT lut = ivx::LUT::create(ctx);
|
||||
lut.copyFrom(lut_data);
|
||||
ivx::IVX_CHECK_STATUS(vxuTableLookup(ctx, ia, lut, ib));
|
||||
}
|
||||
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<VX_KERNEL_MINMAXLOC>(int w, int h) { return w*h < 3840 * 2160; }
|
||||
|
||||
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)
|
||||
{
|
||||
(void)mask_step;
|
||||
|
||||
if ((depth != CV_8U && depth != CV_16S) || mask )
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (skipSmallImages<VX_KERNEL_MINMAXLOC>(width, height))
|
||||
{
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (src_step == 0)
|
||||
{
|
||||
src_step = (int)width;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = getOpenVXHALContext();
|
||||
ivx::Image ia = ivx::Image::createFromHandle(ctx, depth == CV_8U ? VX_DF_IMAGE_U8 : VX_DF_IMAGE_S16,
|
||||
ivx::Image::createAddressing(width, height, depth == CV_8U ? 1 : 2, (vx_int32)src_step),
|
||||
const_cast<uchar*>(src_data));
|
||||
|
||||
ivx::Scalar vxMinVal = ivx::Scalar::create(ctx, depth == CV_8U ? VX_TYPE_UINT8 : VX_TYPE_INT16, 0);
|
||||
ivx::Scalar vxMaxVal = ivx::Scalar::create(ctx, depth == CV_8U ? VX_TYPE_UINT8 : VX_TYPE_INT16, 0);
|
||||
ivx::Array vxMinInd, vxMaxInd;
|
||||
ivx::Scalar vxMinCount, vxMaxCount;
|
||||
if (minIdx)
|
||||
{
|
||||
vxMinInd = ivx::Array::create(ctx, VX_TYPE_COORDINATES2D, 1);
|
||||
vxMinCount = ivx::Scalar::create(ctx, VX_TYPE_UINT32, 0);
|
||||
}
|
||||
if (maxIdx)
|
||||
{
|
||||
vxMaxInd = ivx::Array::create(ctx, VX_TYPE_COORDINATES2D, 1);
|
||||
vxMaxCount = ivx::Scalar::create(ctx, VX_TYPE_UINT32, 0);
|
||||
}
|
||||
|
||||
ivx::IVX_CHECK_STATUS(vxuMinMaxLoc(ctx, ia, vxMinVal, vxMaxVal, vxMinInd, vxMaxInd, vxMinCount, vxMaxCount));
|
||||
|
||||
if (minVal)
|
||||
{
|
||||
*minVal = depth == CV_8U ? vxMinVal.getValue<vx_uint8>() : vxMinVal.getValue<vx_int16>();
|
||||
}
|
||||
if (maxVal)
|
||||
{
|
||||
*maxVal = depth == CV_8U ? vxMaxVal.getValue<vx_uint8>() : vxMaxVal.getValue<vx_int16>();
|
||||
}
|
||||
if (minIdx)
|
||||
{
|
||||
if(vxMinCount.getValue<vx_uint32>()<1) throw ivx::RuntimeError(VX_ERROR_INVALID_VALUE, std::string(__func__) + "(): minimum value location not found");
|
||||
vx_coordinates2d_t loc;
|
||||
vxMinInd.copyRangeTo(0, 1, &loc);
|
||||
minIdx[0] = loc.y;
|
||||
minIdx[1] = loc.x;
|
||||
}
|
||||
if (maxIdx)
|
||||
{
|
||||
if (vxMaxCount.getValue<vx_uint32>()<1) throw ivx::RuntimeError(VX_ERROR_INVALID_VALUE, std::string(__func__) + "(): maximum value location not found");
|
||||
vx_coordinates2d_t loc;
|
||||
vxMaxInd.copyRangeTo(0, 1, &loc);
|
||||
maxIdx[0] = loc.y;
|
||||
maxIdx[1] = loc.x;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
11
3rdparty/openvx/hal/openvx_hal.hpp
vendored
11
3rdparty/openvx/hal/openvx_hal.hpp
vendored
@ -54,6 +54,11 @@ int ovx_hal_cvtThreePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size
|
||||
int ovx_hal_cvtBGRtoThreePlaneYUV(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int acn, bool swapBlue, int uIdx);
|
||||
int ovx_hal_cvtOnePlaneYUVtoBGR(const uchar * a, size_t astep, uchar * b, size_t bstep, int w, int h, int bcn, bool swapBlue, int uIdx, int ycn);
|
||||
int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep, uchar * b, size_t bstep, uchar * c, size_t, uchar * d, size_t, int w, int h, int cn);
|
||||
int ovx_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);
|
||||
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);
|
||||
|
||||
//==================================================================================================
|
||||
// functions redefinition
|
||||
@ -141,5 +146,11 @@ int ovx_hal_integral(int depth, int sdepth, int, const uchar * a, size_t astep,
|
||||
#define cv_hal_cvtOnePlaneYUVtoBGR ovx_hal_cvtOnePlaneYUVtoBGR
|
||||
#undef cv_hal_integral
|
||||
#define cv_hal_integral ovx_hal_integral
|
||||
#undef cv_hal_meanStdDev
|
||||
#define cv_hal_meanStdDev ovx_hal_meanStdDev
|
||||
#undef cv_hal_lut
|
||||
#define cv_hal_lut ovx_hal_lut
|
||||
#undef cv_hal_minMaxIdxMaskStep
|
||||
#define cv_hal_minMaxIdxMaskStep ovx_hal_minMaxIdxMaskStep
|
||||
|
||||
#endif
|
||||
|
16
3rdparty/openvx/include/ivx.hpp
vendored
16
3rdparty/openvx/include/ivx.hpp
vendored
@ -22,7 +22,13 @@ Details: TBD
|
||||
#include <VX/vx.h>
|
||||
#include <VX/vxu.h>
|
||||
|
||||
#ifndef VX_VERSION_1_1
|
||||
// For OpenVX 1.2 & 1.3
|
||||
#if (VX_VERSION > VX_VERSION_1_1)
|
||||
# include <VX/vx_compatibility.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if (VX_VERSION == VX_VERSION_1_0)
|
||||
// 1.1 to 1.0 backward compatibility defines
|
||||
|
||||
static const vx_enum VX_INTERPOLATION_BILINEAR = VX_INTERPOLATION_TYPE_BILINEAR;
|
||||
@ -32,12 +38,6 @@ static const vx_enum VX_INTERPOLATION_NEAREST_NEIGHBOR = VX_INTERPOLATION_TYPE_N
|
||||
static const vx_enum VX_BORDER_CONSTANT = VX_BORDER_MODE_CONSTANT;
|
||||
static const vx_enum VX_BORDER_REPLICATE = VX_BORDER_MODE_REPLICATE;
|
||||
|
||||
#else
|
||||
|
||||
#ifdef IVX_RENAMED_REFS
|
||||
static const vx_enum VX_REF_ATTRIBUTE_TYPE = VX_REFERENCE_TYPE;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef IVX_USE_CXX98
|
||||
@ -218,7 +218,7 @@ template<> struct TypeToEnum<vx_int64> { static const vx_enum value = VX_TYPE
|
||||
template<> struct TypeToEnum<vx_uint64> { static const vx_enum value = VX_TYPE_UINT64; };
|
||||
template<> struct TypeToEnum<vx_float32> { static const vx_enum value = VX_TYPE_FLOAT32, imgType = VX_DF_IMAGE('F', '0', '3', '2'); };
|
||||
template<> struct TypeToEnum<vx_float64> { static const vx_enum value = VX_TYPE_FLOAT64; };
|
||||
template<> struct TypeToEnum<vx_bool> { static const vx_enum value = VX_TYPE_BOOL; };
|
||||
//template<> struct TypeToEnum<vx_bool> { static const vx_enum value = VX_TYPE_BOOL; };
|
||||
template<> struct TypeToEnum<vx_keypoint_t> {static const vx_enum value = VX_TYPE_KEYPOINT; };
|
||||
// the commented types are aliases (of integral tyes) and have conflicts with the types above
|
||||
//template<> struct TypeToEnum<vx_enum> { static const vx_enum val = VX_TYPE_ENUM; };
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "convert.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
|
||||
/****************************************************************************************\
|
||||
* LUT Transform *
|
||||
@ -105,39 +104,6 @@ static bool ocl_LUT(InputArray _src, InputArray _lut, OutputArray _dst)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
static bool openvx_LUT(Mat src, Mat dst, Mat _lut)
|
||||
{
|
||||
if (src.type() != CV_8UC1 || dst.type() != src.type() || _lut.type() != src.type() || !_lut.isContinuous())
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
|
||||
ivx::Image
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(src.cols, src.rows, 1, (vx_int32)(src.step)), src.data),
|
||||
ib = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(dst.cols, dst.rows, 1, (vx_int32)(dst.step)), dst.data);
|
||||
|
||||
ivx::LUT lut = ivx::LUT::create(ctx);
|
||||
lut.copyFrom(_lut);
|
||||
ivx::IVX_CHECK_STATUS(vxuTableLookup(ctx, ia, lut, ib));
|
||||
}
|
||||
catch (const ivx::RuntimeError& e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError& e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_IPP)
|
||||
#if !IPP_DISABLE_PERF_LUT // there are no performance benefits (PR #2653)
|
||||
namespace ipp {
|
||||
@ -379,9 +345,6 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst )
|
||||
_dst.create(src.dims, src.size, CV_MAKETYPE(_lut.depth(), cn));
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_TABLE_LOOKUP>(src.cols, src.rows),
|
||||
openvx_LUT(src, dst, lut))
|
||||
|
||||
CALL_HAL(LUT, cv_hal_lut, src.data, src.step, src.type(), lut.data,
|
||||
lut.elemSize1(), lutcn, dst.data, dst.step, src.cols, src.rows);
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
#include "stat.hpp"
|
||||
|
||||
#ifndef OPENCV_IPP_MEAN
|
||||
@ -328,70 +327,6 @@ static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
static bool openvx_meanStdDev(Mat& src, OutputArray _mean, OutputArray _sdv, Mat& mask)
|
||||
{
|
||||
size_t total_size = src.total();
|
||||
int rows = src.size[0], cols = rows ? (int)(total_size / rows) : 0;
|
||||
if (src.type() != CV_8UC1|| !mask.empty() ||
|
||||
(src.dims != 2 && !(src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size))
|
||||
)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
#ifndef VX_VERSION_1_1
|
||||
if (ctx.vendorID() == VX_ID_KHRONOS)
|
||||
return false; // Do not use OpenVX meanStdDev estimation for sample 1.0.1 implementation due to lack of accuracy
|
||||
#endif
|
||||
|
||||
ivx::Image
|
||||
ia = ivx::Image::createFromHandle(ctx, VX_DF_IMAGE_U8,
|
||||
ivx::Image::createAddressing(cols, rows, 1, (vx_int32)(src.step[0])), src.ptr());
|
||||
|
||||
vx_float32 mean_temp, stddev_temp;
|
||||
ivx::IVX_CHECK_STATUS(vxuMeanStdDev(ctx, ia, &mean_temp, &stddev_temp));
|
||||
|
||||
if (_mean.needed())
|
||||
{
|
||||
if (!_mean.fixedSize())
|
||||
_mean.create(1, 1, CV_64F, -1, true);
|
||||
Mat mean = _mean.getMat();
|
||||
CV_Assert(mean.type() == CV_64F && mean.isContinuous() &&
|
||||
(mean.cols == 1 || mean.rows == 1) && mean.total() >= 1);
|
||||
double *pmean = mean.ptr<double>();
|
||||
pmean[0] = mean_temp;
|
||||
for (int c = 1; c < (int)mean.total(); c++)
|
||||
pmean[c] = 0;
|
||||
}
|
||||
|
||||
if (_sdv.needed())
|
||||
{
|
||||
if (!_sdv.fixedSize())
|
||||
_sdv.create(1, 1, CV_64F, -1, true);
|
||||
Mat stddev = _sdv.getMat();
|
||||
CV_Assert(stddev.type() == CV_64F && stddev.isContinuous() &&
|
||||
(stddev.cols == 1 || stddev.rows == 1) && stddev.total() >= 1);
|
||||
double *pstddev = stddev.ptr<double>();
|
||||
pstddev[0] = stddev_temp;
|
||||
for (int c = 1; c < (int)stddev.total(); c++)
|
||||
pstddev[c] = 0;
|
||||
}
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_meanStdDev(Mat& src, OutputArray _mean, OutputArray _sdv, Mat& mask)
|
||||
{
|
||||
@ -543,9 +478,6 @@ void meanStdDev(InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray
|
||||
|
||||
CV_Assert(mask.empty() || src.size == mask.size);
|
||||
|
||||
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_MEAN_STDDEV>(src.cols, src.rows),
|
||||
openvx_meanStdDev(src, _mean, _sdv, mask))
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_meanStdDev(src, _mean, _sdv, mask));
|
||||
|
||||
int k, cn = src.channels(), depth = src.depth();
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_core.hpp"
|
||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||
#include "stat.hpp"
|
||||
#include "opencv2/core/detail/dispatch_helper.impl.hpp"
|
||||
|
||||
@ -1119,82 +1118,6 @@ bool ocl_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int* minLoc
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENVX
|
||||
namespace ovx {
|
||||
template <> inline bool skipSmallImages<VX_KERNEL_MINMAXLOC>(int w, int h) { return w*h < 3840 * 2160; }
|
||||
}
|
||||
static bool openvx_minMaxIdx(Mat &src, double* minVal, double* maxVal, int* minIdx, int* maxIdx, Mat &mask)
|
||||
{
|
||||
int stype = src.type();
|
||||
size_t total_size = src.total();
|
||||
int rows = src.size[0], cols = rows ? (int)(total_size / rows) : 0;
|
||||
if ((stype != CV_8UC1 && stype != CV_16SC1) || !mask.empty() ||
|
||||
(src.dims != 2 && !(src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size))
|
||||
)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
ivx::Context ctx = ovx::getOpenVXContext();
|
||||
ivx::Image
|
||||
ia = ivx::Image::createFromHandle(ctx, stype == CV_8UC1 ? VX_DF_IMAGE_U8 : VX_DF_IMAGE_S16,
|
||||
ivx::Image::createAddressing(cols, rows, stype == CV_8UC1 ? 1 : 2, (vx_int32)(src.step[0])), src.ptr());
|
||||
|
||||
ivx::Scalar vxMinVal = ivx::Scalar::create(ctx, stype == CV_8UC1 ? VX_TYPE_UINT8 : VX_TYPE_INT16, 0);
|
||||
ivx::Scalar vxMaxVal = ivx::Scalar::create(ctx, stype == CV_8UC1 ? VX_TYPE_UINT8 : VX_TYPE_INT16, 0);
|
||||
ivx::Array vxMinInd, vxMaxInd;
|
||||
ivx::Scalar vxMinCount, vxMaxCount;
|
||||
if (minIdx)
|
||||
{
|
||||
vxMinInd = ivx::Array::create(ctx, VX_TYPE_COORDINATES2D, 1);
|
||||
vxMinCount = ivx::Scalar::create(ctx, VX_TYPE_UINT32, 0);
|
||||
}
|
||||
if (maxIdx)
|
||||
{
|
||||
vxMaxInd = ivx::Array::create(ctx, VX_TYPE_COORDINATES2D, 1);
|
||||
vxMaxCount = ivx::Scalar::create(ctx, VX_TYPE_UINT32, 0);
|
||||
}
|
||||
|
||||
ivx::IVX_CHECK_STATUS(vxuMinMaxLoc(ctx, ia, vxMinVal, vxMaxVal, vxMinInd, vxMaxInd, vxMinCount, vxMaxCount));
|
||||
|
||||
if (minVal)
|
||||
{
|
||||
*minVal = stype == CV_8UC1 ? vxMinVal.getValue<vx_uint8>() : vxMinVal.getValue<vx_int16>();
|
||||
}
|
||||
if (maxVal)
|
||||
{
|
||||
*maxVal = stype == CV_8UC1 ? vxMaxVal.getValue<vx_uint8>() : vxMaxVal.getValue<vx_int16>();
|
||||
}
|
||||
if (minIdx)
|
||||
{
|
||||
if(vxMinCount.getValue<vx_uint32>()<1) throw ivx::RuntimeError(VX_ERROR_INVALID_VALUE, std::string(__func__) + "(): minimum value location not found");
|
||||
vx_coordinates2d_t loc;
|
||||
vxMinInd.copyRangeTo(0, 1, &loc);
|
||||
size_t minidx = loc.y * cols + loc.x + 1;
|
||||
ofs2idx(src, minidx, minIdx);
|
||||
}
|
||||
if (maxIdx)
|
||||
{
|
||||
if (vxMaxCount.getValue<vx_uint32>()<1) throw ivx::RuntimeError(VX_ERROR_INVALID_VALUE, std::string(__func__) + "(): maximum value location not found");
|
||||
vx_coordinates2d_t loc;
|
||||
vxMaxInd.copyRangeTo(0, 1, &loc);
|
||||
size_t maxidx = loc.y * cols + loc.x + 1;
|
||||
ofs2idx(src, maxidx, maxIdx);
|
||||
}
|
||||
}
|
||||
catch (const ivx::RuntimeError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
catch (const ivx::WrapperError & e)
|
||||
{
|
||||
VX_DbgThrow(e.what());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static IppStatus ipp_minMaxIndex_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
|
||||
float* pMinVal, float* pMaxVal, IppiPoint* pMinIndex, IppiPoint* pMaxIndex, const Ipp8u*, int)
|
||||
@ -1519,13 +1442,10 @@ void cv::minMaxIdx(InputArray _src, double* minVal,
|
||||
CALL_HAL(minMaxIdx, cv_hal_minMaxIdx, src.data, src.step, src.cols*cn, src.rows,
|
||||
src.depth(), minVal, maxVal, minIdx, maxIdx, mask.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
CALL_HAL(minMaxIdxMaskStep, cv_hal_minMaxIdxMaskStep, src.data, src.step, src.cols*cn, src.rows,
|
||||
src.depth(), minVal, maxVal, minIdx, maxIdx, mask.data, mask.step);
|
||||
}
|
||||
|
||||
}
|
||||
else if (src.isContinuous() && mask.isContinuous())
|
||||
{
|
||||
int res = cv_hal_minMaxIdx(src.data, 0, (int)src.total()*cn, 1, src.depth(),
|
||||
@ -1547,9 +1467,6 @@ void cv::minMaxIdx(InputArray _src, double* minVal,
|
||||
}
|
||||
}
|
||||
|
||||
CV_OVX_RUN(!ovx::skipSmallImages<VX_KERNEL_MINMAXLOC>(src.cols, src.rows),
|
||||
openvx_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
|
||||
|
||||
MinMaxIdxFunc func = getMinmaxTab(depth);
|
||||
|
Loading…
Reference in New Issue
Block a user