1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Added OpenVX based processing to minMaxLoc

This commit is contained in:
Vitaly Tuzov
2016-11-11 17:04:54 +03:00
parent a53f93ff8d
commit e9cc0f6a4c
2 changed files with 241 additions and 0 deletions
+87
View File
@@ -47,6 +47,12 @@
#include "opencl_kernels_core.hpp"
#ifdef HAVE_OPENVX
#define IVX_HIDE_INFO_WARNINGS
#define IVX_USE_OPENCV
#include "ivx.hpp"
#endif
namespace cv
{
@@ -2226,6 +2232,81 @@ static bool ocl_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int*
#endif
#ifdef HAVE_OPENVX
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 = ivx::Context::create();
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);
}
return true;
}
catch (ivx::RuntimeError & e)
{
CV_Error(CV_StsInternal, e.what());
return false;
}
catch (ivx::WrapperError & e)
{
CV_Error(CV_StsInternal, e.what());
return false;
}
}
#endif
#ifdef HAVE_IPP
static bool ipp_minMaxIdx( Mat &src, double* minVal, double* maxVal, int* minIdx, int* maxIdx, Mat &mask)
{
@@ -2349,6 +2430,12 @@ void cv::minMaxIdx(InputArray _src, double* minVal,
ocl_minMaxIdx(_src, minVal, maxVal, minIdx, maxIdx, _mask))
Mat src = _src.getMat(), mask = _mask.getMat();
#ifdef HAVE_OPENVX
if (openvx_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
return;
#endif
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
MinMaxIdxFunc func = getMinmaxTab(depth);